755224027d725180820a4985f9aab19431979de1
[ccsdk/features.git] /
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;
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
29 import org.eclipse.jdt.annotation.NonNull;
30 import org.eclipse.jdt.annotation.Nullable;
31 import org.onap.ccsdk.features.sdnr.wt.common.util.StackTrace;
32 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.TransactionUtils;
33 import org.opendaylight.mdsal.binding.api.DataBroker;
34 import org.opendaylight.mdsal.binding.api.ReadTransaction;
35 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
36 import org.opendaylight.yangtools.yang.binding.DataObject;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 public final class GenericTransactionUtils implements TransactionUtils {
42     static final Logger LOG = LoggerFactory.getLogger(GenericTransactionUtils.class);
43
44     /**
45      * Deliver the data back or null. Warning
46      *
47      * @param <T> SubType of the DataObject to be handled
48      * @param dataBroker for accessing data
49      * @param dataStoreType to address datastore
50      * @param iid id to access data
51      * @return null or object
52      */
53     @Override
54     @Nullable
55     public <T extends DataObject> T readData(DataBroker dataBroker, LogicalDatastoreType dataStoreType,
56             InstanceIdentifier<T> iid) {
57
58         AtomicBoolean noErrorIndication = new AtomicBoolean();
59         AtomicReference<String> statusText = new AtomicReference<>();
60
61         @Nullable
62         T obj = readDataOptionalWithStatus(dataBroker, dataStoreType, iid, noErrorIndication, statusText);
63
64         if (!noErrorIndication.get()) {
65             LOG.warn("Read transaction for identifier " + iid + " failed with status " + statusText.get());
66         }
67
68         return obj;
69     }
70
71     /**
72      * Deliver the data back or null
73      *
74      * @param <T> SubType of the DataObject to be handled
75      * @param dataBroker for accessing data
76      * @param dataStoreType to address datastore
77      * @param iid id to access data
78      * @param noErrorIndication (Output) true if data could be read and are available and is not null
79      * @param statusIndicator (Output) String with status indications during the read.
80      * @return null or object
81      */
82     @Override
83     @SuppressWarnings("null")
84     public @Nullable <T extends DataObject> T readDataOptionalWithStatus(DataBroker dataBroker,
85             LogicalDatastoreType dataStoreType, InstanceIdentifier<T> iid, AtomicBoolean noErrorIndication,
86             AtomicReference<String> statusIndicator) {
87
88         @Nullable
89         T data = null;
90         noErrorIndication.set(false);
91
92         statusIndicator.set("Preconditions");
93         Preconditions.checkNotNull(dataBroker);
94
95         int retry = 0;
96         int retryDelayMilliseconds = 2000;
97         int maxRetries = 0; // 0 no Retry
98
99         do {
100             if (retry > 0) {
101                 try {
102                     LOG.debug("Sleep {}ms", retryDelayMilliseconds);
103                     Thread.sleep(retryDelayMilliseconds);
104                 } catch (InterruptedException e) {
105                     LOG.debug("Sleep interrupted", e);
106                     Thread.currentThread().interrupt();
107                 }
108             }
109
110             LOG.debug("Sending message with retry {} ", retry);
111             statusIndicator.set("Create Read Transaction");
112             ReadTransaction readTransaction = dataBroker.newReadOnlyTransaction();
113             try {
114                 @NonNull
115                 FluentFuture<Optional<T>> od = readTransaction.read(dataStoreType, iid);
116                 statusIndicator.set("Read done");
117                 if (od != null) {
118                     statusIndicator.set("Unwrap checkFuture done");
119                     Optional<T> optionalData = od.get();
120                     if (optionalData != null) {
121                         statusIndicator.set("Unwrap optional done");
122                         data = optionalData.orElse(null);
123                         statusIndicator.set("Read transaction done");
124                         noErrorIndication.set(true);
125                     } else {
126                         statusIndicator.set("optional Data is null");
127                     }
128                 } else {
129                     statusIndicator.set("od feature is null");
130                 }
131             } catch (CancellationException | ExecutionException | InterruptedException | NoSuchElementException e) {
132                 statusIndicator.set(StackTrace.toString(e));
133                 if (e instanceof InterruptedException) {
134                     Thread.currentThread().interrupt();
135                 }
136                 LOG.debug("Exception during read", e);
137             }
138
139         } while (noErrorIndication.get() == false && retry++ < maxRetries);
140
141         LOG.debug("stage 2 noErrorIndication {} status text {}", noErrorIndication.get(), statusIndicator.get());
142
143         return data;
144     }
145
146
147 }