2 * Copyright (c) 2016 Cisco and/or its affiliates.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package io.fd.hc2vpp.common.translate.util;
19 import static com.google.common.base.Preconditions.checkArgument;
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.Optional;
26 import java.util.concurrent.ExecutionException;
27 import java.util.concurrent.Future;
28 import java.util.concurrent.TimeUnit;
29 import java.util.concurrent.TimeoutException;
30 import javax.annotation.Nonnegative;
31 import javax.annotation.Nonnull;
32 import org.opendaylight.yangtools.yang.binding.DataObject;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 * Trait providing logic for consuming reply's to jvpp api calls
40 public interface JvppReplyConsumer {
42 JvppReplyConsumer INSTANCE = new JvppReplyConsumer() {
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
50 default <R extends JVppReply<?>> R getReplyForWrite(@Nonnull Future<R> future,
51 @Nonnull final InstanceIdentifier<?> replyType)
52 throws WriteFailedException {
54 return getReplyForWrite(future, replyType, JvppReplyTimeoutHolder.getTimeout());
58 * Consumes reply for jvpp call representing any write operation
59 * Should be used in case of calls where it's not clear which write crud operation respective
60 * call represents, for ex. setRouting
62 default <R extends JVppReply<?>> R getReplyForWrite(@Nonnull Future<R> future,
63 @Nonnull final InstanceIdentifier<?> replyType,
64 @Nonnegative final int timeoutInSeconds)
65 throws WriteFailedException {
67 return getReply(future, timeoutInSeconds);
68 } catch (TimeoutException e) {
69 throw new WriteTimeoutException(replyType, e);
70 } catch (VppBaseCallException e) {
71 throw new WriteFailedException(replyType, e);
77 * Consumes reply for jvpp call representing create operation
79 default <R extends JVppReply<?>> R getReplyForCreate(@Nonnull Future<R> future,
80 @Nonnull final InstanceIdentifier<?> replyType,
81 @Nonnull final DataObject data)
82 throws WriteFailedException.CreateFailedException {
83 return getReplyForCreate(future, replyType, data, JvppReplyTimeoutHolder.getTimeout());
87 * Consumes reply for jvpp call representing create operation
89 default <R extends JVppReply<?>> R getReplyForCreate(@Nonnull Future<R> future,
90 @Nonnull final InstanceIdentifier<?> replyType,
91 @Nonnull final DataObject data,
92 @Nonnegative final int timeoutInSeconds)
93 throws WriteFailedException.CreateFailedException {
95 return getReply(future, timeoutInSeconds);
96 } catch (VppBaseCallException e) {
97 throw new WriteFailedException.CreateFailedException(replyType, data, e);
98 } catch (TimeoutException e) {
99 throw new WriteFailedException.CreateFailedException(replyType, data,
100 new WriteTimeoutException(replyType, e));
105 * Consumes reply for jvpp call representing update operation
107 default <R extends JVppReply<?>> R getReplyForUpdate(@Nonnull Future<R> future,
108 @Nonnull final InstanceIdentifier<?> replyType,
109 @Nonnull final DataObject dataBefore,
110 @Nonnull final DataObject dataAfter)
111 throws WriteFailedException.UpdateFailedException {
112 return getReplyForUpdate(future, replyType, dataBefore, dataAfter, JvppReplyTimeoutHolder.getTimeout());
116 * Consumes reply for jvpp call representing update operation
118 default <R extends JVppReply<?>> R getReplyForUpdate(@Nonnull Future<R> future,
119 @Nonnull final InstanceIdentifier<?> replyType,
120 @Nonnull final DataObject dataBefore,
121 @Nonnull final DataObject dataAfter,
122 @Nonnegative final int timeoutInSeconds)
123 throws WriteFailedException.UpdateFailedException {
125 return getReply(future, timeoutInSeconds);
126 } catch (VppBaseCallException e) {
127 throw new WriteFailedException.UpdateFailedException(replyType, dataBefore, dataAfter, e);
128 } catch (TimeoutException e) {
129 throw new WriteFailedException.UpdateFailedException(replyType, dataBefore, dataAfter,
130 new WriteTimeoutException(replyType, e));
135 * Consumes reply for jvpp call representing delete operation
137 default <R extends JVppReply<?>> R getReplyForDelete(@Nonnull Future<R> future,
138 @Nonnull final InstanceIdentifier<?> replyType)
139 throws WriteFailedException.DeleteFailedException {
140 return getReplyForDelete(future, replyType, JvppReplyTimeoutHolder.getTimeout());
144 * Consumes reply for jvpp call representing delete operation
146 default <R extends JVppReply<?>> R getReplyForDelete(@Nonnull Future<R> future,
147 @Nonnull final InstanceIdentifier<?> replyType,
148 @Nonnegative final int timeoutInSeconds)
149 throws WriteFailedException.DeleteFailedException {
151 return getReply(future, timeoutInSeconds);
152 } catch (VppBaseCallException e) {
153 throw new WriteFailedException.DeleteFailedException(replyType, e);
154 } catch (TimeoutException e) {
155 throw new WriteFailedException.DeleteFailedException(replyType, new WriteTimeoutException(replyType, e));
159 default <R extends JVppReply<?>> R getReplyForRead(@Nonnull Future<R> future,
160 @Nonnull final InstanceIdentifier<?> replyType)
161 throws ReadFailedException {
162 return getReplyForRead(future, replyType, JvppReplyTimeoutHolder.getTimeout());
165 default <R extends JVppReply<?>> R getReplyForRead(@Nonnull Future<R> future,
166 @Nonnull final InstanceIdentifier<?> replyType,
167 @Nonnegative final int timeoutInSeconds)
168 throws ReadFailedException {
170 return getReply(future, timeoutInSeconds);
171 } catch (TimeoutException e) {
172 throw new ReadTimeoutException(replyType, e);
173 } catch (VppBaseCallException e) {
174 throw new ReadFailedException(replyType, e);
178 default <R extends JVppReply<?>> R getReply(@Nonnull Future<R> future)
179 throws TimeoutException, VppBaseCallException {
180 return getReply(future, JvppReplyTimeoutHolder.getTimeout());
183 default <R extends JVppReply<?>> R getReply(@Nonnull Future<R> future,
184 @Nonnegative final int timeoutInSeconds)
185 throws TimeoutException, VppBaseCallException {
187 checkArgument(timeoutInSeconds > 0, "Timeout cannot be < 0");
188 return future.get(timeoutInSeconds, TimeUnit.SECONDS);
189 } catch (InterruptedException e) {
190 Thread.currentThread().interrupt();
191 throw new IllegalStateException("Interrupted", e);
192 } catch (ExecutionException e) {
193 // Execution exception could generally contains any exception
194 // when using exceptions instead of return codes just rethrow it for processing on corresponding place
195 if (e.getCause() instanceof VppBaseCallException) {
196 throw (VppBaseCallException) (e.getCause());
198 throw new IllegalStateException(e);
203 * Wrapper for reply timeout
205 class JvppReplyTimeoutHolder {
206 private static final Logger LOG = LoggerFactory.getLogger(JvppReplyTimeoutHolder.class);
207 private static Optional<Integer> timeout = Optional.empty();
209 private JvppReplyTimeoutHolder() {
210 throw new UnsupportedOperationException("Utility class cannot be instantiated.");
213 public static void setupTimeout(@Nonnegative final int jvppTimeout) {
214 if (timeout.isPresent()) {
215 // do not fail on reconfigure, to not disturb restarts
216 LOG.warn("JVpp timeout already configured");
219 timeout = Optional.of(jvppTimeout);
220 LOG.info("Jvpp reply timeout configured to {} seconds", timeout.get());
223 public static int getTimeout() {
224 return timeout.orElse(5);