30483377f71fada7050421fc19f912110fe102e2
[netconf.git] / netconf / netconf-topology-singleton / src / main / java / org / opendaylight / netconf / topology / singleton / impl / tx / NetconfReadOnlyTransaction.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. 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
9 package org.opendaylight.netconf.topology.singleton.impl.tx;
10
11 import akka.actor.ActorSystem;
12 import akka.dispatch.OnComplete;
13 import com.google.common.base.Function;
14 import com.google.common.base.Optional;
15 import com.google.common.util.concurrent.CheckedFuture;
16 import com.google.common.util.concurrent.Futures;
17 import com.google.common.util.concurrent.SettableFuture;
18 import javax.annotation.Nullable;
19 import org.opendaylight.controller.config.util.xml.DocumentedException;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
22 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
23 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
24 import org.opendaylight.netconf.topology.singleton.api.NetconfDOMTransaction;
25 import org.opendaylight.netconf.topology.singleton.messages.NormalizedNodeMessage;
26 import org.opendaylight.yangtools.yang.common.RpcError;
27 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import scala.concurrent.Future;
33
34 public class NetconfReadOnlyTransaction implements DOMDataReadOnlyTransaction {
35
36     private static final Logger LOG = LoggerFactory.getLogger(NetconfReadOnlyTransaction.class);
37
38     private final RemoteDeviceId id;
39     private final NetconfDOMTransaction delegate;
40     private final ActorSystem actorSystem;
41
42     public NetconfReadOnlyTransaction(final RemoteDeviceId id,
43                                       final ActorSystem actorSystem,
44                                       final NetconfDOMTransaction delegate) {
45         this.id = id;
46         this.delegate = delegate;
47         this.actorSystem = actorSystem;
48     }
49
50     @Override
51     public void close() {
52         //NOOP
53     }
54
55     @Override
56     public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(final LogicalDatastoreType store,
57                                                                                    final YangInstanceIdentifier path) {
58
59         LOG.trace("{}: Read {} via NETCONF: {}", id, store, path);
60
61         final Future<Optional<NormalizedNodeMessage>> future = delegate.read(store, path);
62         final SettableFuture<Optional<NormalizedNode<?, ?>>> settableFuture = SettableFuture.create();
63         final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> checkedFuture;
64         checkedFuture = Futures.makeChecked(settableFuture, new Function<Exception, ReadFailedException>() {
65             @Nullable
66             @Override
67             public ReadFailedException apply(Exception cause) {
68                 if (cause.getCause() instanceof DocumentedException) {
69                     final DocumentedException exception = (DocumentedException) cause.getCause();
70                     if (exception.getErrorSeverity() == DocumentedException.ErrorSeverity.ERROR &&
71                             exception.getErrorType() == DocumentedException.ErrorType.TRANSPORT &&
72                             exception.getErrorTag() == DocumentedException.ErrorTag.RESOURCE_DENIED) {
73                         final RpcError error = RpcResultBuilder.newError(
74                                 RpcError.ErrorType.TRANSPORT,
75                                 exception.getErrorTag().getTagValue(),
76                                 exception.getMessage());
77                         return new ReadFailedException("Read from transaction failed", error);
78                     }
79                 }
80                 return new ReadFailedException("Read from transaction failed", cause);
81             }
82         });
83         future.onComplete(new OnComplete<Optional<NormalizedNodeMessage>>() {
84             @Override
85             public void onComplete(final Throwable throwable,
86                                    final Optional<NormalizedNodeMessage> normalizedNodeMessage) throws Throwable {
87                 if (throwable == null) {
88                     if (normalizedNodeMessage.isPresent()) {
89                         settableFuture.set(normalizedNodeMessage.transform(new Function<NormalizedNodeMessage,
90                                 NormalizedNode<?, ?>>() {
91
92                             @Nullable
93                             @Override
94                             public NormalizedNode<?, ?> apply(final NormalizedNodeMessage input) {
95                                 return input.getNode();
96                             }
97                         }));
98                     } else {
99                         settableFuture.set(Optional.absent());
100                     }
101                 } else {
102                     settableFuture.setException(throwable);
103                 }
104             }
105         }, actorSystem.dispatcher());
106         return checkedFuture;
107     }
108
109     @Override
110     public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store,
111                                                               final YangInstanceIdentifier path) {
112
113         LOG.trace("{}: Exists {} via NETCONF: {}", id, store, path);
114
115         final Future<Boolean> existsFuture = delegate.exists(store, path);
116         final SettableFuture<Boolean> settableFuture = SettableFuture.create();
117         final CheckedFuture<Boolean, ReadFailedException> checkedFuture;
118         checkedFuture = Futures.makeChecked(settableFuture, new Function<Exception, ReadFailedException>() {
119             @Nullable
120             @Override
121             public ReadFailedException apply(Exception cause) {
122                 return new ReadFailedException("Read from transaction failed", cause);
123             }
124         });
125         existsFuture.onComplete(new OnComplete<Boolean>() {
126             @Override
127             public void onComplete(final Throwable throwable, final Boolean result) throws Throwable {
128                 if (throwable == null) {
129                     settableFuture.set(result);
130                 } else {
131                     settableFuture.setException(throwable);
132                 }
133             }
134         }, actorSystem.dispatcher());
135         return checkedFuture;
136     }
137
138     @Override
139     public Object getIdentifier() {
140         return this;
141     }
142 }