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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
16 * ============LICENSE_END==========================================================================
17 ******************************************************************************/
18 package org.onap.ccsdk.features.sdnr.wt.devicemanager.base.netconf.util;
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.binding.api.WriteTransaction;
30 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
31 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
32 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
33 import org.opendaylight.yangtools.yang.binding.DataObject;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37 import com.google.common.base.Optional;
38 import com.google.common.base.Preconditions;
39 import com.google.common.util.concurrent.CheckedFuture;
41 @SuppressWarnings("deprecation")
42 public final class GenericTransactionUtils {
43 static final Logger LOG = LoggerFactory.getLogger(GenericTransactionUtils.class);
45 public static <T extends DataObject> boolean writeData(DataBroker dataBroker,
46 LogicalDatastoreType logicalDatastoreType, InstanceIdentifier<T> iid, T dataObject, boolean isAdd) {
47 Preconditions.checkNotNull(dataBroker);
48 WriteTransaction modification = dataBroker.newWriteOnlyTransaction();
50 if (dataObject == null) {
51 LOG.warn("Invalid attempt to add a non-existent object to path {}", iid);
54 modification.merge(logicalDatastoreType, iid, dataObject, true /* createMissingParents */);
56 modification.delete(LogicalDatastoreType.CONFIGURATION, iid);
58 CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
60 commitFuture.checkedGet();
61 LOG.debug("Transaction success for {} of object {}", isAdd ? "add" : "delete", dataObject);
63 } catch (Exception e) {
64 LOG.warn("Transaction failed with error {} for {} of object {}", e.getMessage(), isAdd ? "add" : "delete",
66 modification.cancel();
72 * Deliver the data back or null. Warning
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 * @return null or object
81 public static <T extends DataObject> T readData(DataBroker dataBroker, LogicalDatastoreType dataStoreType,
82 InstanceIdentifier<T> iid) {
84 AtomicBoolean noErrorIndication = new AtomicBoolean();
85 AtomicReference<String> statusText = new AtomicReference<>();
87 T obj = readDataOptionalWithStatus(dataBroker, dataStoreType, iid, noErrorIndication, statusText);
89 if (!noErrorIndication.get()) {
90 LOG.warn("Read transaction for identifier " + iid + " failed with status " + statusText.get());
97 * Deliver the data back or null
99 * @param <T> SubType of the DataObject to be handled
100 * @param dataBroker for accessing data
101 * @param dataStoreType to address datastore
102 * @param iid id to access data
103 * @param noErrorIndication (Output) true if data could be read and are available and is not null
104 * @param statusIndicator (Output) String with status indications during the read.
105 * @return null or object
108 public static <T extends DataObject> T readDataOptionalWithStatus(DataBroker dataBroker,
109 LogicalDatastoreType dataStoreType, InstanceIdentifier<T> iid, AtomicBoolean noErrorIndication,
110 AtomicReference<String> statusIndicator) {
113 noErrorIndication.set(false);
115 statusIndicator.set("Preconditions");
116 Preconditions.checkNotNull(dataBroker);
119 int retryDelayMilliseconds = 2000;
120 int maxRetries = 5; // 0 no Retry
125 LOG.debug("Sleep {}ms", retryDelayMilliseconds);
126 Thread.sleep(retryDelayMilliseconds);
127 } catch (InterruptedException e) {
128 LOG.debug("Sleep interrupted", e);
129 Thread.currentThread().interrupt();
133 LOG.debug("Sending message with retry {} ", retry);
134 statusIndicator.set("Create Read Transaction");
136 try (ReadOnlyTransaction readTransaction = dataBroker.newReadOnlyTransaction();) {
137 CheckedFuture<Optional<T>, ReadFailedException> od = readTransaction.read(dataStoreType, iid);
138 statusIndicator.set("Read done");
140 statusIndicator.set("Unwrap checkFuture done");
141 Optional<T> optionalData = od.get();
142 if (optionalData != null) {
143 statusIndicator.set("Unwrap optional done");
144 data = optionalData.orNull();
145 statusIndicator.set("Read transaction done");
146 noErrorIndication.set(true);
150 readTransaction.close();
151 } catch (CancellationException | ExecutionException | InterruptedException | NoSuchElementException e) {
152 statusIndicator.set(ExceptionUtils.getStackTrace(e));
153 if (e instanceof InterruptedException) {
154 Thread.currentThread().interrupt();
158 } while (noErrorIndication.get() == false && retry++ < maxRetries);