ed4278923b586ab00c8abd45727216dc20c8d6da
[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.impl.util;
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.apache.commons.lang3.exception.ExceptionUtils;
30 import org.eclipse.jdt.annotation.NonNull;
31 import org.eclipse.jdt.annotation.Nullable;
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 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     @SuppressWarnings("null")
83     public @Nullable <T extends DataObject> T readDataOptionalWithStatus(DataBroker dataBroker,
84             LogicalDatastoreType dataStoreType, InstanceIdentifier<T> iid, AtomicBoolean noErrorIndication,
85             AtomicReference<String> statusIndicator) {
86
87         @Nullable 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 = 5; // 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
111             try (ReadTransaction readTransaction = dataBroker.newReadOnlyTransaction();) {
112                 @NonNull FluentFuture<Optional<T>> od = readTransaction.read(dataStoreType, iid);
113                 statusIndicator.set("Read done");
114                 if (od != null) {
115                     statusIndicator.set("Unwrap checkFuture done");
116                     Optional<T> optionalData = od.get();
117                     if (optionalData != null) {
118                         statusIndicator.set("Unwrap optional done");
119                         data = optionalData.orElse(null);
120                         statusIndicator.set("Read transaction done");
121                         noErrorIndication.set(true);
122                     }
123                 }
124
125                 readTransaction.close();
126             } catch (CancellationException | ExecutionException | InterruptedException | NoSuchElementException e) {
127                 statusIndicator.set(ExceptionUtils.getStackTrace(e));
128                 if (e instanceof InterruptedException) {
129                     Thread.currentThread().interrupt();
130                 }
131             }
132
133         } while (noErrorIndication.get() == false && retry++ < maxRetries);
134
135         return data;
136     }
137
138
139
140 }