VPP-30 sr_replicate requires DPDK
[vpp.git] / vpp-api / java / jvpp / org / openvpp / jvpp / future / FutureJVppInvokerFacade.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 org.openvpp.jvpp.future;
18
19
20 import java.util.Map;
21 import java.util.concurrent.CompletableFuture;
22 import java.util.concurrent.CompletionStage;
23 import org.openvpp.jvpp.JVpp;
24 import org.openvpp.jvpp.dto.ControlPing;
25 import org.openvpp.jvpp.dto.JVppDump;
26 import org.openvpp.jvpp.dto.JVppReply;
27 import org.openvpp.jvpp.dto.JVppReplyDump;
28 import org.openvpp.jvpp.dto.JVppRequest;
29
30 /**
31 * Future facade on top of JVpp
32 */
33 public class FutureJVppInvokerFacade implements FutureJVppInvoker {
34
35     private final JVpp jvpp;
36
37     /**
38      * Guarded by self
39      */
40     private final Map<Integer, CompletableFuture<? extends JVppReply<?>>> requests;
41
42     public FutureJVppInvokerFacade(final JVpp jvpp,
43                      final Map<Integer, CompletableFuture<? extends JVppReply<?>>> requestMap) {
44         // TODO use guava's preconditions for nonNull and state checks
45         // However adding guava as a dependency requires better build system for Java in VPP project
46         // Currently it's just invocation of javac
47         if(jvpp == null) {
48             throw new NullPointerException("Null jvpp");
49         }
50         this.jvpp = jvpp;
51         if(requestMap == null) {
52             throw new NullPointerException("Null requestMap");
53         }
54         // Request map represents the shared state between this facade and it's callback
55         // where facade puts futures in and callback completes + removes them
56         // TODO what if the call never completes ?
57         this.requests = requestMap;
58     }
59
60     // TODO use Optional in Future, java8
61
62     @Override
63     @SuppressWarnings("unchecked")
64     public <REQ extends JVppRequest, REPLY extends JVppReply<REQ>> CompletionStage<REPLY> send(REQ req) {
65         synchronized(requests) {
66             final int contextId = jvpp.send(req);
67
68             final CompletableFuture<REPLY> replyCompletableFuture;
69             if(req instanceof JVppDump) {
70                 replyCompletableFuture = (CompletableFuture<REPLY>) new CompletableDumpFuture<>(contextId);
71             } else {
72                 replyCompletableFuture = new CompletableFuture<>();
73             }
74
75             requests.put(contextId, replyCompletableFuture);
76             if(req instanceof JVppDump) {
77                 requests.put(jvpp.send(new ControlPing()), replyCompletableFuture);
78             }
79             return replyCompletableFuture;
80         }
81     }
82
83     static final class CompletableDumpFuture<T extends JVppReplyDump<?, ?>> extends CompletableFuture<T> {
84         // The reason why this is not final is the instantiation of ReplyDump DTOs
85         // Their instantiation must be generated, so currently the DTOs are created in callback and set when first dump reponses
86         // is handled in the callback.
87         private T replyDump;
88         private final long contextId;
89
90         CompletableDumpFuture(final long contextId) {
91             this.contextId = contextId;
92         }
93
94         long getContextId() {
95             return contextId;
96         }
97
98         T getReplyDump() {
99             return replyDump;
100         }
101
102         void setReplyDump(final T replyDump) {
103             this.replyDump = replyDump;
104         }
105     }
106
107     @Override
108     public void close() throws Exception {
109         // NOOP
110     }
111 }