UT coverage increased in vpp-renderer
[groupbasedpolicy.git] / renderers / vpp / src / main / java / org / opendaylight / groupbasedpolicy / renderer / vpp / util / GbpNetconfTransaction.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.groupbasedpolicy.renderer.vpp.util;
10
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.yangtools.yang.binding.DataObject;
22 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 public class GbpNetconfTransaction {
27
28     public static final byte RETRY_COUNT = 5;
29     private static final Logger LOG = LoggerFactory.getLogger(GbpNetconfTransaction.class);
30
31     /**
32      * Use {@link ConfigCommand} to put data into netconf transaction and submit. Transaction is restarted if failed
33      *
34      * @param mountpoint   to access remote device
35      * @param command      config command with data, datastore type and iid
36      * @param retryCounter number of attempts
37      * @return true if transaction is successful, false otherwise
38      */
39     public synchronized static boolean write(final DataBroker mountpoint, final ConfigCommand command,
40                                              byte retryCounter) {
41         LOG.trace("Netconf WRITE transaction started. RetryCounter: {}", retryCounter);
42         Preconditions.checkNotNull(mountpoint);
43         final ReadWriteTransaction rwTx = mountpoint.newReadWriteTransaction();
44         try {
45             command.execute(rwTx);
46             final CheckedFuture<Void, TransactionCommitFailedException> futureTask = rwTx.submit();
47             futureTask.get();
48             LOG.trace("Netconf WRITE transaction done. Retry counter: {}", retryCounter);
49             return true;
50         } catch (IllegalStateException e) {
51             // Retry
52             if (retryCounter > 0) {
53                 LOG.warn("Assuming that netconf write-transaction failed, restarting ...", e.getMessage());
54                 return write(mountpoint, command, --retryCounter);
55             } else {
56                 LOG.warn("Netconf write-transaction failed. Maximal number of attempts reached", e.getMessage());
57                 return false;
58             }
59         } catch (Exception e) {
60             LOG.warn("Exception while writing data ...", e.getMessage());
61             return false;
62         }
63     }
64
65     /**
66      * Write data to remote device. Transaction is restarted if failed
67      *
68      * @param mountpoint   to access remote device
69      * @param iid          data identifier
70      * @param data         to write
71      * @param retryCounter number of attempts
72      * @param <T>          generic data type. Has to be child of {@link DataObject}
73      * @return true if transaction is successful, false otherwise
74      */
75     public synchronized static <T extends DataObject> boolean write(final DataBroker mountpoint,
76                                                                     final InstanceIdentifier<T> iid,
77                                                                     final T data,
78                                                                     byte retryCounter) {
79         LOG.trace("Netconf WRITE transaction started. RetryCounter: {}", retryCounter);
80         Preconditions.checkNotNull(mountpoint);
81         final ReadWriteTransaction rwTx = mountpoint.newReadWriteTransaction();
82         try {
83             rwTx.put(LogicalDatastoreType.CONFIGURATION, iid, data, true);
84             final CheckedFuture<Void, TransactionCommitFailedException> futureTask = rwTx.submit();
85             futureTask.get();
86             LOG.trace("Netconf WRITE transaction done. Retry counter: {}", retryCounter);
87             return true;
88         } catch (IllegalStateException e) {
89             // Retry
90             if (retryCounter > 0) {
91                 LOG.warn("Assuming that netconf write-transaction failed, restarting ...", e.getMessage());
92                 return write(mountpoint, iid, data, --retryCounter);
93             } else {
94                 LOG.warn("Netconf write-transaction failed. Maximal number of attempts reached", e.getMessage());
95                 return false;
96             }
97         } catch (Exception e) {
98             LOG.warn("Exception while writing data ...", e.getMessage());
99             return false;
100         }
101     }
102
103     /**
104      * Read data from remote device. Transaction is restarted if failed.
105      *
106      * @param mountpoint    to access remote device
107      * @param datastoreType {@link LogicalDatastoreType}
108      * @param iid           data identifier
109      * @param retryCounter  number of attempts
110      * @param <T>           generic data type. Has to be child of {@link DataObject}
111      * @return optional data object if successful, {@link Optional#absent()} if failed
112      */
113     public synchronized static <T extends DataObject> Optional<T> read(final DataBroker mountpoint,
114                                                                        final LogicalDatastoreType datastoreType,
115                                                                        final InstanceIdentifier<T> iid,
116                                                                        byte retryCounter) {
117         LOG.trace("Netconf READ transaction started. RetryCounter: {}", retryCounter);
118         Preconditions.checkNotNull(mountpoint);
119         final ReadOnlyTransaction rTx = mountpoint.newReadOnlyTransaction();
120         Optional<T> data;
121         try {
122             final CheckedFuture<Optional<T>, ReadFailedException> futureData =
123                     rTx.read(datastoreType, iid);
124             data = futureData.get();
125             LOG.trace("Netconf READ transaction done. Data present: {}, Retry counter: {}",
126                     data.isPresent(), retryCounter);
127             return data;
128         } catch (IllegalStateException e) {
129             // Retry
130             if (retryCounter > 0) {
131                 LOG.warn("Assuming that netconf read-transaction failed, restarting ...", e.getMessage());
132                 rTx.close();
133                 return read(mountpoint, datastoreType, iid, --retryCounter);
134             } else {
135                 LOG.warn("Netconf read-transaction failed. Maximal number of attempts reached", e.getMessage());
136                 return Optional.absent();
137             }
138         } catch (Exception e) {
139             LOG.warn("Exception while reading data ...", e.getMessage());
140             return Optional.absent();
141         }
142     }
143
144     /**
145      * Remove data from remote device using {@link ConfigCommand}. Transaction is restarted if failed.
146      *
147      * @param mountpoint   to access remote device
148      * @param command      config command with data, datastore type and iid
149      * @param retryCounter number of attempts
150      * @return true if transaction is successful, false otherwise
151      */
152     public synchronized static boolean delete(final DataBroker mountpoint, final ConfigCommand command,
153                                               byte retryCounter) {
154         LOG.trace("Netconf DELETE transaction started. RetryCounter: {}", retryCounter);
155         Preconditions.checkNotNull(mountpoint);
156         final ReadWriteTransaction rwTx = mountpoint.newReadWriteTransaction();
157         try {
158             command.execute(rwTx);
159             final CheckedFuture<Void, TransactionCommitFailedException> futureTask = rwTx.submit();
160             futureTask.get();
161             LOG.trace("Netconf DELETE transaction done. Retry counter: {}", retryCounter);
162             return true;
163         } catch (IllegalStateException e) {
164             // Retry
165             if (retryCounter > 0) {
166                 LOG.warn("Assuming that netconf delete-transaction failed, restarting ...", e.getMessage());
167                 return delete(mountpoint, command, --retryCounter);
168             } else {
169                 LOG.warn("Netconf delete-transaction failed. Maximal number of attempts reached", e.getMessage());
170                 return false;
171             }
172         } catch (Exception e) {
173             LOG.warn("Exception while removing data ...", e.getMessage());
174             return false;
175         }
176     }
177
178     /**
179      * Remove data from remote device. Transaction is restarted if failed.
180      *
181      * @param mountpoint   to access remote device
182      * @param iid          data identifier
183      * @param retryCounter number of attempts
184      * @param <T>          generic data type. Has to be child of {@link DataObject}
185      * @return true if transaction is successful, false otherwise
186      */
187     public synchronized static <T extends DataObject> boolean delete(final DataBroker mountpoint,
188                                                                      final InstanceIdentifier<T> iid,
189                                                                      byte retryCounter) {
190         LOG.trace("Netconf DELETE transaction started. RetryCounter: {}", retryCounter);
191         Preconditions.checkNotNull(mountpoint);
192         final ReadWriteTransaction rwTx = mountpoint.newReadWriteTransaction();
193         try {
194             rwTx.delete(LogicalDatastoreType.CONFIGURATION, iid);
195             final CheckedFuture<Void, TransactionCommitFailedException> futureTask = rwTx.submit();
196             futureTask.get();
197             LOG.trace("Netconf DELETE transaction done. Retry counter: {}", retryCounter);
198             return true;
199         } catch (IllegalStateException e) {
200             // Retry
201             if (retryCounter > 0) {
202                 LOG.warn("Assuming that netconf delete-transaction failed, restarting ...", e.getMessage());
203                 return delete(mountpoint, iid, --retryCounter);
204             } else {
205                 LOG.warn("Netconf delete-transaction failed. Maximal number of attempts reached", e.getMessage());
206                 return false;
207             }
208         } catch (Exception e) {
209             LOG.warn("Exception while removing data ...", e.getMessage());
210             return false;
211         }
212     }
213
214 }