d55446c828f50a280f197f0bbf0ccbaceef072bf
[hc2vpp.git] /
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.hc2vpp.common.translate.util;
18
19 import io.fd.honeycomb.translate.read.ReadFailedException;
20 import io.fd.honeycomb.translate.write.WriteFailedException;
21 import io.fd.vpp.jvpp.VppBaseCallException;
22 import io.fd.vpp.jvpp.dto.JVppReply;
23 import org.opendaylight.yangtools.yang.binding.DataObject;
24 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
25
26 import javax.annotation.Nonnegative;
27 import javax.annotation.Nonnull;
28 import java.util.concurrent.ExecutionException;
29 import java.util.concurrent.Future;
30 import java.util.concurrent.TimeUnit;
31 import java.util.concurrent.TimeoutException;
32
33 import static com.google.common.base.Preconditions.checkArgument;
34
35 /**
36  * Trait providing logic for consuming reply's to jvpp api calls
37  */
38 public interface JvppReplyConsumer {
39
40     int DEFAULT_TIMEOUT_IN_SECONDS = 5;
41
42     JvppReplyConsumer INSTANCE = new JvppReplyConsumer() {
43     };
44
45     /**
46      * Consumes reply for jvpp call representing any write operation
47      * Should be used in case of calls where it's not clear which write crud operation respective
48      * call represents, for ex. setRouting
49      */
50     default <REP extends JVppReply<?>> REP getReplyForWrite(@Nonnull Future<REP> future,
51                                                             @Nonnull final InstanceIdentifier<?> replyType)
52             throws WriteFailedException {
53         return getReplyForWrite(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS);
54     }
55
56     /**
57      * Consumes reply for jvpp call representing any write operation
58      * Should be used in case of calls where it's not clear which write crud operation respective
59      * call represents, for ex. setRouting
60      */
61     default <REP extends JVppReply<?>> REP getReplyForWrite(@Nonnull Future<REP> future,
62                                                             @Nonnull final InstanceIdentifier<?> replyType,
63                                                             @Nonnegative final int timeoutInSeconds)
64             throws WriteFailedException {
65         try {
66             return getReply(future, timeoutInSeconds);
67         } catch (TimeoutException e) {
68             throw new WriteTimeoutException(replyType, e);
69         } catch (VppBaseCallException e) {
70             throw new WriteFailedException(replyType, e);
71         }
72
73     }
74
75     /**
76      * Consumes reply for jvpp call representing create operation
77      */
78     default <REP extends JVppReply<?>> REP getReplyForCreate(@Nonnull Future<REP> future,
79                                                              @Nonnull final InstanceIdentifier<?> replyType,
80                                                              @Nonnull final DataObject data)
81             throws WriteFailedException {
82         return getReplyForCreate(future, replyType, data, DEFAULT_TIMEOUT_IN_SECONDS);
83     }
84
85     /**
86      * Consumes reply for jvpp call representing create operation
87      */
88     default <REP extends JVppReply<?>> REP getReplyForCreate(@Nonnull Future<REP> future,
89                                                              @Nonnull final InstanceIdentifier<?> replyType,
90                                                              @Nonnull final DataObject data,
91                                                              @Nonnegative final int timeoutInSeconds)
92             throws WriteFailedException {
93         try {
94             return getReply(future, timeoutInSeconds);
95         } catch (VppBaseCallException e) {
96             throw new WriteFailedException.CreateFailedException(replyType, data, e);
97         } catch (TimeoutException e) {
98             throw new WriteTimeoutException(replyType, e);
99         }
100     }
101
102     /**
103      * Consumes reply for jvpp call representing update operation
104      */
105     default <REP extends JVppReply<?>> REP getReplyForUpdate(@Nonnull Future<REP> future,
106                                                              @Nonnull final InstanceIdentifier<?> replyType,
107                                                              @Nonnull final DataObject dataBefore,
108                                                              @Nonnull final DataObject dataAfter)
109             throws WriteFailedException {
110         return getReplyForUpdate(future, replyType, dataBefore, dataAfter, DEFAULT_TIMEOUT_IN_SECONDS);
111     }
112
113     /**
114      * Consumes reply for jvpp call representing update operation
115      */
116     default <REP extends JVppReply<?>> REP getReplyForUpdate(@Nonnull Future<REP> future,
117                                                              @Nonnull final InstanceIdentifier<?> replyType,
118                                                              @Nonnull final DataObject dataBefore,
119                                                              @Nonnull final DataObject dataAfter,
120                                                              @Nonnegative final int timeoutInSeconds)
121             throws WriteFailedException {
122         try {
123             return getReply(future, timeoutInSeconds);
124         } catch (VppBaseCallException e) {
125             throw new WriteFailedException.UpdateFailedException(replyType, dataBefore, dataAfter, e);
126         } catch (TimeoutException e) {
127             throw new WriteTimeoutException(replyType, e);
128         }
129     }
130
131     /**
132      * Consumes reply for jvpp call representing delete operation
133      */
134     default <REP extends JVppReply<?>> REP getReplyForDelete(@Nonnull Future<REP> future,
135                                                              @Nonnull final InstanceIdentifier<?> replyType)
136             throws WriteFailedException {
137         return getReplyForDelete(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS);
138     }
139
140     /**
141      * Consumes reply for jvpp call representing delete operation
142      */
143     default <REP extends JVppReply<?>> REP getReplyForDelete(@Nonnull Future<REP> future,
144                                                              @Nonnull final InstanceIdentifier<?> replyType,
145                                                              @Nonnegative final int timeoutInSeconds)
146             throws WriteFailedException {
147         try {
148             return getReply(future, timeoutInSeconds);
149         } catch (VppBaseCallException e) {
150             throw new WriteFailedException.DeleteFailedException(replyType, e);
151         } catch (TimeoutException e) {
152             throw new WriteTimeoutException(replyType, e);
153         }
154     }
155
156     default <REP extends JVppReply<?>> REP getReplyForRead(@Nonnull Future<REP> future,
157                                                            @Nonnull final InstanceIdentifier<?> replyType)
158             throws ReadFailedException {
159         return getReplyForRead(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS);
160     }
161
162     default <REP extends JVppReply<?>> REP getReplyForRead(@Nonnull Future<REP> future,
163                                                            @Nonnull final InstanceIdentifier<?> replyType,
164                                                            @Nonnegative final int timeoutInSeconds)
165             throws ReadFailedException {
166         try {
167             return getReply(future, timeoutInSeconds);
168         } catch (TimeoutException e) {
169             throw new ReadTimeoutException(replyType, e);
170         } catch (VppBaseCallException e) {
171             throw new ReadFailedException(replyType, e);
172         }
173     }
174
175     default <REP extends JVppReply<?>> REP getReply(@Nonnull Future<REP> future)
176             throws TimeoutException, VppBaseCallException {
177         return getReply(future, DEFAULT_TIMEOUT_IN_SECONDS);
178     }
179
180     default <REP extends JVppReply<?>> REP getReply(@Nonnull Future<REP> future,
181                                                     @Nonnegative final int timeoutInSeconds)
182             throws TimeoutException, VppBaseCallException {
183         try {
184             checkArgument(timeoutInSeconds > 0, "Timeout cannot be < 0");
185             return future.get(timeoutInSeconds, TimeUnit.SECONDS);
186         } catch (InterruptedException e) {
187             Thread.currentThread().interrupt();
188             throw new IllegalStateException("Interrupted", e);
189         } catch (ExecutionException e) {
190             // Execution exception could generally contains any exception
191             // when using exceptions instead of return codes just rethrow it for processing on corresponding place
192             if (e instanceof ExecutionException && (e.getCause() instanceof VppBaseCallException)) {
193                 throw (VppBaseCallException) (e.getCause());
194             }
195             throw new IllegalStateException(e);
196         }
197     }
198 }