403ba0ad43b7740d2093358bce4c0217a5ce04b5
[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.devicemanager.base.netconf.util;
19
20 import java.util.NoSuchElementException;
21 import java.util.concurrent.CancellationException;
22 import java.util.concurrent.ExecutionException;
23 import java.util.concurrent.atomic.AtomicBoolean;
24 import java.util.concurrent.atomic.AtomicReference;
25 import javax.annotation.Nullable;
26 import org.apache.commons.lang3.exception.ExceptionUtils;
27 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
28 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
29 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
30 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
31 import org.opendaylight.yangtools.yang.binding.DataObject;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35 import com.google.common.base.Optional;
36 import com.google.common.base.Preconditions;
37 import com.google.common.util.concurrent.CheckedFuture;
38
39 @SuppressWarnings("deprecation")
40 public final class GenericTransactionUtils {
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     @Nullable
53     public static <T extends DataObject> T readData(DataBroker dataBroker, LogicalDatastoreType dataStoreType,
54             InstanceIdentifier<T> iid) {
55
56         AtomicBoolean noErrorIndication = new AtomicBoolean();
57         AtomicReference<String> statusText = new AtomicReference<>();
58
59         T obj = readDataOptionalWithStatus(dataBroker, dataStoreType, iid, noErrorIndication, statusText);
60
61         if (!noErrorIndication.get()) {
62             LOG.warn("Read transaction for identifier " + iid + " failed with status " + statusText.get());
63         }
64
65         return obj;
66     }
67
68     /**
69      * Deliver the data back or null
70      *
71      * @param <T> SubType of the DataObject to be handled
72      * @param dataBroker for accessing data
73      * @param dataStoreType to address datastore
74      * @param iid id to access data
75      * @param noErrorIndication (Output) true if data could be read and are available and is not null
76      * @param statusIndicator (Output) String with status indications during the read.
77      * @return null or object
78      */
79     @Nullable
80     public static <T extends DataObject> T readDataOptionalWithStatus(DataBroker dataBroker,
81             LogicalDatastoreType dataStoreType, InstanceIdentifier<T> iid, AtomicBoolean noErrorIndication,
82             AtomicReference<String> statusIndicator) {
83
84         T data = null;
85         noErrorIndication.set(false);
86
87         statusIndicator.set("Preconditions");
88         Preconditions.checkNotNull(dataBroker);
89
90         int retry = 0;
91         int retryDelayMilliseconds = 2000;
92         int maxRetries = 5; // 0 no Retry
93
94         do {
95             if (retry > 0) {
96                 try {
97                     LOG.debug("Sleep {}ms", retryDelayMilliseconds);
98                     Thread.sleep(retryDelayMilliseconds);
99                 } catch (InterruptedException e) {
100                     LOG.debug("Sleep interrupted", e);
101                     Thread.currentThread().interrupt();
102                 }
103             }
104
105             LOG.debug("Sending message with retry {} ", retry);
106             statusIndicator.set("Create Read Transaction");
107
108             try (ReadOnlyTransaction readTransaction = dataBroker.newReadOnlyTransaction();) {
109                 CheckedFuture<Optional<T>, ReadFailedException> od = readTransaction.read(dataStoreType, iid);
110                 statusIndicator.set("Read done");
111                 if (od != null) {
112                     statusIndicator.set("Unwrap checkFuture done");
113                     Optional<T> optionalData = od.get();
114                     if (optionalData != null) {
115                         statusIndicator.set("Unwrap optional done");
116                         data = optionalData.orNull();
117                         statusIndicator.set("Read transaction done");
118                         noErrorIndication.set(true);
119                     }
120                 }
121
122                 readTransaction.close();
123             } catch (CancellationException | ExecutionException | InterruptedException | NoSuchElementException e) {
124                 statusIndicator.set(ExceptionUtils.getStackTrace(e));
125                 if (e instanceof InterruptedException) {
126                     Thread.currentThread().interrupt();
127                 }
128             }
129
130         } while (noErrorIndication.get() == false && retry++ < maxRetries);
131
132         return data;
133     }
134
135
136 }