9e85c5d8bdf84840eb7d5fddec82501f818b88ed
[honeycomb.git] / vpp-common / vpp-translate-utils / src / main / java / io / fd / honeycomb / translate / vpp / util / JvppReplyConsumer.java
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.honeycomb.translate.vpp.util;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20
21 import io.fd.honeycomb.translate.read.ReadFailedException;
22 import io.fd.honeycomb.translate.write.WriteFailedException;
23 import io.fd.vpp.jvpp.VppBaseCallException;
24 import io.fd.vpp.jvpp.dto.JVppReply;
25 import java.util.concurrent.ExecutionException;
26 import java.util.concurrent.Future;
27 import java.util.concurrent.TimeUnit;
28 import java.util.concurrent.TimeoutException;
29 import javax.annotation.Nonnegative;
30 import javax.annotation.Nonnull;
31 import org.opendaylight.yangtools.yang.binding.DataObject;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33
34 /**
35  * Trait providing logic for consuming reply's to jvpp api calls
36  */
37 public interface JvppReplyConsumer {
38
39     int DEFAULT_TIMEOUT_IN_SECONDS = 5;
40
41     /**
42      * Consumes reply for jvpp call representing any write operation
43      * Should be used in case of calls where it's not clear which write crud operation respective
44      * call represents, for ex. setRouting
45      */
46     default <REP extends JVppReply<?>> REP getReplyForWrite(@Nonnull Future<REP> future,
47                                                             @Nonnull final InstanceIdentifier<?> replyType)
48             throws WriteFailedException {
49         return getReplyForWrite(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS);
50     }
51
52     /**
53      * Consumes reply for jvpp call representing any write operation
54      * Should be used in case of calls where it's not clear which write crud operation respective
55      * call represents, for ex. setRouting
56      */
57     default <REP extends JVppReply<?>> REP getReplyForWrite(@Nonnull Future<REP> future,
58                                                             @Nonnull final InstanceIdentifier<?> replyType,
59                                                             @Nonnegative final int timeoutInSeconds)
60             throws WriteFailedException {
61         try {
62             return getReply(future, timeoutInSeconds);
63         } catch (TimeoutException e) {
64             throw new WriteTimeoutException(replyType, e);
65         } catch (VppBaseCallException e) {
66             throw new WriteFailedException(replyType, e);
67         }
68
69     }
70
71     /**
72      * Consumes reply for jvpp call representing create operation
73      */
74     default <REP extends JVppReply<?>> REP getReplyForCreate(@Nonnull Future<REP> future,
75                                                              @Nonnull final InstanceIdentifier<?> replyType,
76                                                              @Nonnull final DataObject data)
77             throws WriteFailedException {
78         return getReplyForCreate(future, replyType, data, DEFAULT_TIMEOUT_IN_SECONDS);
79     }
80
81     /**
82      * Consumes reply for jvpp call representing create operation
83      */
84     default <REP extends JVppReply<?>> REP getReplyForCreate(@Nonnull Future<REP> future,
85                                                              @Nonnull final InstanceIdentifier<?> replyType,
86                                                              @Nonnull final DataObject data,
87                                                              @Nonnegative final int timeoutInSeconds)
88             throws WriteFailedException {
89         try {
90             return getReply(future, timeoutInSeconds);
91         } catch (VppBaseCallException e) {
92             throw new WriteFailedException.CreateFailedException(replyType, data, e);
93         } catch (TimeoutException e) {
94             throw new WriteTimeoutException(replyType, e);
95         }
96     }
97
98     /**
99      * Consumes reply for jvpp call representing update operation
100      */
101     default <REP extends JVppReply<?>> REP getReplyForUpdate(@Nonnull Future<REP> future,
102                                                              @Nonnull final InstanceIdentifier<?> replyType,
103                                                              @Nonnull final DataObject dataBefore,
104                                                              @Nonnull final DataObject dataAfter)
105             throws WriteFailedException {
106         return getReplyForUpdate(future, replyType, dataBefore, dataAfter, DEFAULT_TIMEOUT_IN_SECONDS);
107     }
108
109     /**
110      * Consumes reply for jvpp call representing update operation
111      */
112     default <REP extends JVppReply<?>> REP getReplyForUpdate(@Nonnull Future<REP> future,
113                                                              @Nonnull final InstanceIdentifier<?> replyType,
114                                                              @Nonnull final DataObject dataBefore,
115                                                              @Nonnull final DataObject dataAfter,
116                                                              @Nonnegative final int timeoutInSeconds)
117             throws WriteFailedException {
118         try {
119             return getReply(future, timeoutInSeconds);
120         } catch (VppBaseCallException e) {
121             throw new WriteFailedException.UpdateFailedException(replyType, dataBefore, dataAfter, e);
122         } catch (TimeoutException e) {
123             throw new WriteTimeoutException(replyType, e);
124         }
125     }
126
127     /**
128      * Consumes reply for jvpp call representing delete operation
129      */
130     default <REP extends JVppReply<?>> REP getReplyForDelete(@Nonnull Future<REP> future,
131                                                              @Nonnull final InstanceIdentifier<?> replyType)
132             throws WriteFailedException {
133         return getReplyForDelete(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS);
134     }
135
136     /**
137      * Consumes reply for jvpp call representing delete operation
138      */
139     default <REP extends JVppReply<?>> REP getReplyForDelete(@Nonnull Future<REP> future,
140                                                              @Nonnull final InstanceIdentifier<?> replyType,
141                                                              @Nonnegative final int timeoutInSeconds)
142             throws WriteFailedException {
143         try {
144             return getReply(future, timeoutInSeconds);
145         } catch (VppBaseCallException e) {
146             throw new WriteFailedException.DeleteFailedException(replyType, e);
147         } catch (TimeoutException e) {
148             throw new WriteTimeoutException(replyType, e);
149         }
150     }
151
152     default <REP extends JVppReply<?>> REP getReplyForRead(@Nonnull Future<REP> future,
153                                                            @Nonnull final InstanceIdentifier<?> replyType)
154             throws ReadFailedException {
155         return getReplyForRead(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS);
156     }
157
158     default <REP extends JVppReply<?>> REP getReplyForRead(@Nonnull Future<REP> future,
159                                                            @Nonnull final InstanceIdentifier<?> replyType,
160                                                            @Nonnegative final int timeoutInSeconds)
161             throws ReadFailedException {
162         try {
163             return getReply(future, timeoutInSeconds);
164         } catch (TimeoutException e) {
165             throw new ReadTimeoutException(replyType, e);
166         } catch (VppBaseCallException e) {
167             throw new ReadFailedException(replyType, e);
168         }
169     }
170
171     default <REP extends JVppReply<?>> REP getReply(@Nonnull Future<REP> future)
172             throws TimeoutException, VppBaseCallException {
173         return getReply(future, DEFAULT_TIMEOUT_IN_SECONDS);
174     }
175
176     default <REP extends JVppReply<?>> REP getReply(@Nonnull Future<REP> future,
177                                                     @Nonnegative final int timeoutInSeconds)
178             throws TimeoutException, VppBaseCallException {
179         try {
180             checkArgument(timeoutInSeconds > 0, "Timeout cannot be < 0");
181             return future.get(timeoutInSeconds, TimeUnit.SECONDS);
182         } catch (InterruptedException e) {
183             Thread.currentThread().interrupt();
184             throw new IllegalStateException("Interrupted", e);
185         } catch (ExecutionException e) {
186             // Execution exception could generally contains any exception
187             // when using exceptions instead of return codes just rethrow it for processing on corresponding place
188             if (e instanceof ExecutionException && (e.getCause() instanceof VppBaseCallException)) {
189                 throw (VppBaseCallException) (e.getCause());
190             }
191             throw new IllegalStateException(e);
192         }
193     }
194 }