2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.groupbasedpolicy.renderer.vpp.util;
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.util.concurrent.CheckedFuture;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
16 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
19 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
20 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.ConfigCommand;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
22 import org.opendaylight.yangtools.yang.binding.DataObject;
23 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 public class GbpNetconfTransaction {
29 public static final byte RETRY_COUNT = 3;
30 private static final Logger LOG = LoggerFactory.getLogger(GbpNetconfTransaction.class);
33 * Use {@link ConfigCommand} to put data into netconf transaction and submit. Transaction is restarted if failed
35 * @param mountpoint to access remote device
36 * @param command config command with data, datastore type and iid
37 * @param retryCounter number of attempts
38 * @return true if transaction is successful, false otherwise
40 public static synchronized boolean write(final DataBroker mountpoint, final ConfigCommand command,
42 LOG.trace("Netconf WRITE transaction started. RetryCounter: {}", retryCounter);
43 Preconditions.checkNotNull(mountpoint);
44 final ReadWriteTransaction rwTx = mountpoint.newReadWriteTransaction();
46 command.execute(rwTx);
47 final CheckedFuture<Void, TransactionCommitFailedException> futureTask = rwTx.submit();
49 LOG.trace("Netconf WRITE transaction done for command {}", command);
51 } catch (Exception e) {
53 if (retryCounter > 0) {
54 LOG.warn("Netconf WRITE transaction failed to {}. Restarting transaction ... ", e.getMessage());
55 return write(mountpoint, command, --retryCounter);
57 LOG.warn("Netconf WRITE transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e);
64 * Write data to remote device. Transaction is restarted if failed
66 * @param mountpoint to access remote device
67 * @param iid data identifier
68 * @param data to write
69 * @param retryCounter number of attempts
70 * @param <T> generic data type. Has to be child of {@link DataObject}
71 * @return true if transaction is successful, false otherwise
73 public static synchronized <T extends DataObject> boolean write(final DataBroker mountpoint,
74 final InstanceIdentifier<T> iid,
77 LOG.trace("Netconf WRITE transaction started. RetryCounter: {}", retryCounter);
78 Preconditions.checkNotNull(mountpoint);
79 final ReadWriteTransaction rwTx = mountpoint.newReadWriteTransaction();
81 rwTx.put(LogicalDatastoreType.CONFIGURATION, iid, data, true);
82 final CheckedFuture<Void, TransactionCommitFailedException> futureTask = rwTx.submit();
84 LOG.trace("Netconf WRITE transaction done for {}", iid);
86 } catch (Exception e) {
88 if (retryCounter > 0) {
89 LOG.warn("Netconf WRITE transaction failed to {}. Restarting transaction ... ", e.getMessage());
90 return write(mountpoint, iid, data, --retryCounter);
92 LOG.warn("Netconf WRITE transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e);
99 * Read data from remote device. Transaction is restarted if failed.
101 * @param mountpoint to access remote device
102 * @param datastoreType {@link LogicalDatastoreType}
103 * @param iid data identifier
104 * @param retryCounter number of attempts
105 * @param <T> generic data type. Has to be child of {@link DataObject}
106 * @return optional data object if successful, {@link Optional#absent()} if failed
108 public static synchronized <T extends DataObject> Optional<T> read(final DataBroker mountpoint,
109 final LogicalDatastoreType datastoreType,
110 final InstanceIdentifier<T> iid,
112 LOG.trace("Netconf READ transaction started. RetryCounter: {}", retryCounter);
113 Preconditions.checkNotNull(mountpoint);
114 final ReadOnlyTransaction rTx = mountpoint.newReadOnlyTransaction();
117 final CheckedFuture<Optional<T>, ReadFailedException> futureData =
118 rTx.read(datastoreType, iid);
119 data = futureData.get();
120 LOG.trace("Netconf READ transaction done. Data present: {}", data.isPresent());
122 } catch (Exception e) {
124 if (retryCounter > 0) {
125 LOG.warn("Netconf READ transaction failed to {}. Restarting transaction ... ", e.getMessage());
127 return read(mountpoint, datastoreType, iid, --retryCounter);
129 LOG.warn("Netconf READ transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e);
130 return Optional.absent();
136 * Remove data from remote device using {@link ConfigCommand}
138 * @param mountpoint to access remote device
139 * @param command config command with data, datastore type and iid
140 * @param retryCounter number of attempts
141 * @return true if transaction is successful, false otherwise
143 public static synchronized boolean deleteIfExists(final DataBroker mountpoint, final ConfigCommand command,
145 Preconditions.checkNotNull(mountpoint);
146 InstanceIdentifier<Interface> iid = VppIidFactory.getInterfaceIID(command.getInterfaceBuilder().getKey());
147 return deleteIfExists(mountpoint, iid, retryCounter);
151 * Remove data from remote device. Data presence is verified before removal. Transaction is restarted if failed.
153 * @param mountpoint to access remote device
154 * @param iid data identifier
155 * @param retryCounter number of attempts
156 * @param <T> generic data type. Has to be child of {@link DataObject}
157 * @return true if transaction is successful, false otherwise
159 public static synchronized <T extends DataObject> boolean deleteIfExists(final DataBroker mountpoint,
160 final InstanceIdentifier<T> iid,
162 LOG.trace("Netconf DELETE transaction started. Data will be read at first. RetryCounter: {}", retryCounter);
163 Preconditions.checkNotNull(mountpoint);
164 final Optional<T> optionalObject = read(mountpoint, LogicalDatastoreType.CONFIGURATION, iid, RETRY_COUNT);
165 if (!optionalObject.isPresent()) {
166 LOG.warn("Netconf DELETE transaction aborted. Data to remove are not present or cannot be read. Iid: {}",
168 // Return true, this state is not considered as an error
171 final ReadWriteTransaction rwTx = mountpoint.newReadWriteTransaction();
173 rwTx.delete(LogicalDatastoreType.CONFIGURATION, iid);
174 final CheckedFuture<Void, TransactionCommitFailedException> futureTask = rwTx.submit();
176 LOG.trace("Netconf DELETE transaction done for {}", iid);
178 } catch (Exception e) {
180 if (retryCounter > 0) {
181 LOG.warn("Netconf DELETE transaction failed to {}. Restarting transaction ... ", e.getMessage());
182 return deleteIfExists(mountpoint, iid, --retryCounter);
184 LOG.warn("Netconf DELETE transaction unsuccessful. Maximal number of attempts reached. Trace: {}", e);