Migrate websocketmanager and netconfnode-state-service
[ccsdk/features.git] / sdnr / wt / netconfnode-state-service / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / netconfnodestateservice / impl / access / binding / GenericTransactionUtils.java
1 /*
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  */
18 package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.access.binding;
19
20 import com.google.common.base.Preconditions;
21 import com.google.common.util.concurrent.FluentFuture;
22 import java.util.NoSuchElementException;
23 import java.util.Optional;
24 import java.util.concurrent.CancellationException;
25 import java.util.concurrent.ExecutionException;
26 import java.util.concurrent.atomic.AtomicBoolean;
27 import java.util.concurrent.atomic.AtomicReference;
28 import org.eclipse.jdt.annotation.NonNull;
29 import org.eclipse.jdt.annotation.Nullable;
30 import org.onap.ccsdk.features.sdnr.wt.common.util.StackTrace;
31 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils;
32 import org.opendaylight.mdsal.binding.api.DataBroker;
33 import org.opendaylight.mdsal.binding.api.ReadTransaction;
34 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
35 import org.opendaylight.yangtools.yang.binding.DataObject;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 public final class GenericTransactionUtils implements TransactionUtils {
41     static final Logger LOG = LoggerFactory.getLogger(GenericTransactionUtils.class);
42
43     /**
44      * Deliver the data back or null. Warning
45      *
46      * @param <T> SubType of the DataObject to be handled
47      * @param dataBroker for accessing data
48      * @param dataStoreType to address datastore
49      * @param iid id to access data
50      * @return null or object
51      */
52     @Override
53     @Nullable
54     public <T extends DataObject> T readData(DataBroker dataBroker, LogicalDatastoreType dataStoreType,
55             InstanceIdentifier<T> iid) {
56
57         AtomicBoolean noErrorIndication = new AtomicBoolean();
58         AtomicReference<String> statusText = new AtomicReference<>();
59
60         @Nullable
61         T obj = readDataOptionalWithStatus(dataBroker, dataStoreType, iid, noErrorIndication, statusText);
62
63         if (!noErrorIndication.get()) {
64             LOG.warn("Read transaction for identifier " + iid + " failed with status " + statusText.get());
65         }
66
67         return obj;
68     }
69
70     /**
71      * Deliver the data back or null
72      *
73      * @param <T> SubType of the DataObject to be handled
74      * @param dataBroker for accessing data
75      * @param dataStoreType to address datastore
76      * @param iid id to access data
77      * @param noErrorIndication (Output) true if data could be read and are available and is not null
78      * @param statusIndicator (Output) String with status indications during the read.
79      * @return null or object
80      */
81     @Override
82     public @Nullable <T extends DataObject> T readDataOptionalWithStatus(DataBroker dataBroker,
83             LogicalDatastoreType dataStoreType, InstanceIdentifier<T> iid, AtomicBoolean noErrorIndication,
84             AtomicReference<String> statusIndicator) {
85
86         @Nullable
87         T data = null;
88         noErrorIndication.set(false);
89
90         statusIndicator.set("Preconditions");
91         Preconditions.checkNotNull(dataBroker);
92
93         int retry = 0;
94         int retryDelayMilliseconds = 2000;
95         int maxRetries = 0; // 0 no Retry
96
97         do {
98             if (retry > 0) {
99                 try {
100                     LOG.debug("Sleep {}ms", retryDelayMilliseconds);
101                     Thread.sleep(retryDelayMilliseconds);
102                 } catch (InterruptedException e) {
103                     LOG.debug("Sleep interrupted", e);
104                     Thread.currentThread().interrupt();
105                 }
106             }
107
108             LOG.debug("Sending message with retry {} ", retry);
109             statusIndicator.set("Create Read Transaction");
110             ReadTransaction readTransaction = dataBroker.newReadOnlyTransaction();
111             try {
112                 @NonNull
113                 FluentFuture<Optional<T>> od = readTransaction.read(dataStoreType, iid);
114                 statusIndicator.set("Read done");
115                 if (od != null) {
116                     statusIndicator.set("Unwrap checkFuture done");
117                     Optional<T> optionalData = od.get();
118                     if (optionalData != null) {
119                         statusIndicator.set("Unwrap optional done");
120                         data = optionalData.orElse(null);
121                         statusIndicator.set("Read transaction done");
122                         noErrorIndication.set(true);
123                     } else {
124                         statusIndicator.set("optional Data is null");
125                     }
126                 } else {
127                     statusIndicator.set("od feature is null");
128                 }
129             } catch (CancellationException | ExecutionException | InterruptedException | NoSuchElementException e) {
130                 statusIndicator.set(StackTrace.toString(e));
131                 if (e instanceof InterruptedException) {
132                     Thread.currentThread().interrupt();
133                 }
134                 LOG.debug("Exception during read", e);
135             }
136
137         } while (noErrorIndication.get() == false && retry++ < maxRetries);
138
139         LOG.debug("stage 2 noErrorIndication {} status text {}", noErrorIndication.get(), statusIndicator.get());
140
141         return data;
142     }
143
144
145 }