Refactor vpp-japi
[vpp.git] / vpp-japi / japi / org / openvpp / vppjapi / vppConn.java
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 package org.openvpp.vppjapi;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.nio.file.Files;
21 import java.nio.file.Path;
22 import java.nio.file.StandardCopyOption;
23 import java.nio.file.attribute.PosixFilePermission;
24 import java.nio.file.attribute.PosixFilePermissions;
25 import java.util.Set;
26 import java.util.concurrent.atomic.AtomicBoolean;
27
28 import org.openvpp.vppjapi.vppVersion;
29 import org.openvpp.vppjapi.vppInterfaceDetails;
30 import org.openvpp.vppjapi.vppInterfaceCounters;
31 import org.openvpp.vppjapi.vppBridgeDomainDetails;
32 import org.openvpp.vppjapi.vppIPv4Address;
33 import org.openvpp.vppjapi.vppIPv6Address;
34 import org.openvpp.vppjapi.vppVxlanTunnelDetails;
35
36 public class vppConn implements AutoCloseable {
37     private static final String LIBNAME = "libvppjni.so.0.0.0";
38
39     static {
40         try {
41             loadLibrary();
42         } catch (IOException | RuntimeException e) {
43             System.out.printf ("Can't find vpp jni library: %s\n", LIBNAME);
44             throw new ExceptionInInitializerError(e);
45         }
46     }
47
48     private static void loadStream(final InputStream is) throws IOException {
49         final Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");
50         final Path p = Files.createTempFile(LIBNAME, null, PosixFilePermissions.asFileAttribute(perms));
51         try {
52             Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
53
54             try {
55                 Runtime.getRuntime().load(p.toString());
56             } catch (UnsatisfiedLinkError e) {
57                 throw new IOException(String.format("Failed to load library %s", p), e);
58             }
59         } finally {
60             try {
61                 Files.deleteIfExists(p);
62             } catch (IOException e) {
63             }
64         }
65     }
66
67     private static void loadLibrary() throws IOException {
68       try (final InputStream is = vppConn.class.getResourceAsStream('/' + LIBNAME)) {
69           if (is == null) {
70             throw new IOException(String.format("Failed to open library resource %s",
71                                                 LIBNAME));
72           }
73           loadStream(is);
74         }
75     }
76
77     private static vppConn currentConnection = null;
78     private final AtomicBoolean disconnected = new AtomicBoolean(false);
79     private final String clientName;
80
81     // Hidden on purpose to prevent external instantiation
82     vppConn(final String clientName) throws IOException {
83         this.clientName = clientName;
84
85         synchronized (vppConn.class) {
86             if (currentConnection != null) {
87                 throw new IOException("Already connected as " + currentConnection.clientName);
88             }
89
90             final int ret = clientConnect(clientName);
91             if (ret != 0) {
92                 throw new IOException("Connection returned error " + ret);
93             }
94
95             currentConnection = this;
96         }
97     }
98
99     @Override
100     public final void close() {
101         if (disconnected.compareAndSet(false, true)) {
102             synchronized (vppConn.class) {
103                 clientDisconnect();
104                 currentConnection = null;
105             }
106         }
107     }
108
109     /**
110      * Check if this instance is connected.
111      *
112      * @throws IllegalStateException if this instance was disconnected.
113      */
114     protected final void checkConnected() {
115         if (disconnected.get()) {
116             throw new IllegalStateException("Disconnected client " + clientName);
117         }
118     }
119
120     public final int getRetval(int context, int release) {
121         checkConnected();
122         return getRetval0(context, release);
123     }
124
125     public final String getInterfaceList (String nameFilter) {
126         checkConnected();
127         return getInterfaceList0(nameFilter);
128     }
129
130     public final int swIfIndexFromName (String interfaceName) {
131         checkConnected();
132         return swIfIndexFromName0(interfaceName);
133     }
134
135     public final String interfaceNameFromSwIfIndex (int swIfIndex) {
136         checkConnected();
137         return interfaceNameFromSwIfIndex0(swIfIndex);
138     }
139
140     public final void clearInterfaceTable () {
141         checkConnected();
142         clearInterfaceTable0();
143     }
144
145     public final vppInterfaceDetails[] swInterfaceDump (byte nameFilterValid, byte [] nameFilter) {
146         checkConnected();
147         return swInterfaceDump0(nameFilterValid, nameFilter);
148     }
149
150     public final int bridgeDomainIdFromName(String bridgeDomain) {
151         checkConnected();
152         return bridgeDomainIdFromName0(bridgeDomain);
153     }
154
155     public final int findOrAddBridgeDomainId(String bridgeDomain) {
156         checkConnected();
157         return findOrAddBridgeDomainId0(bridgeDomain);
158     }
159
160     public final vppVersion getVppVersion() {
161         checkConnected();
162         return getVppVersion0();
163     }
164
165     public final vppInterfaceCounters getInterfaceCounters(int swIfIndex) {
166         checkConnected();
167         return getInterfaceCounters0(swIfIndex);
168     }
169
170     public final int[] bridgeDomainDump(int bdId) {
171         checkConnected();
172         return bridgeDomainDump0(bdId);
173     }
174
175     public final vppBridgeDomainDetails getBridgeDomainDetails(int bdId) {
176         checkConnected();
177         return getBridgeDomainDetails0(bdId);
178     }
179
180     public final vppL2Fib[] l2FibTableDump(int bdId) {
181         checkConnected();
182         return l2FibTableDump0(bdId);
183     }
184
185     public final int bridgeDomainIdFromInterfaceName(String interfaceName) {
186         checkConnected();
187         return bridgeDomainIdFromInterfaceName0(interfaceName);
188     }
189
190     public final vppIPv4Address[] ipv4AddressDump(String interfaceName) {
191         checkConnected();
192         return ipv4AddressDump0(interfaceName);
193     }
194
195     public final vppIPv6Address[] ipv6AddressDump(String interfaceName) {
196         checkConnected();
197         return ipv6AddressDump0(interfaceName);
198     }
199
200     public final vppVxlanTunnelDetails[] vxlanTunnelDump(int swIfIndex) {
201         checkConnected();
202         return vxlanTunnelDump0(swIfIndex);
203     }
204
205     public final int setInterfaceDescription(String ifName, String ifDesc) {
206         checkConnected();
207         return setInterfaceDescription0(ifName, ifDesc);
208     }
209
210     public final String getInterfaceDescription(String ifName) {
211         checkConnected();
212         return getInterfaceDescription0(ifName);
213     }
214
215     private static native int clientConnect(String clientName);
216     private static native void clientDisconnect();
217     private static native int getRetval0(int context, int release);
218     private static native String getInterfaceList0(String nameFilter);
219     private static native int swIfIndexFromName0(String interfaceName);
220     private static native String interfaceNameFromSwIfIndex0(int swIfIndex);
221     private static native void clearInterfaceTable0();
222     private static native vppInterfaceDetails[] swInterfaceDump0(byte nameFilterValid, byte [] nameFilter);
223     private static native int bridgeDomainIdFromName0(String bridgeDomain);
224     private static native int findOrAddBridgeDomainId0(String bridgeDomain);
225     private static native vppVersion getVppVersion0();
226     private static native vppInterfaceCounters getInterfaceCounters0(int swIfIndex);
227     private static native int[] bridgeDomainDump0(int bdId);
228     private static native vppBridgeDomainDetails getBridgeDomainDetails0(int bdId);
229     private static native vppL2Fib[] l2FibTableDump0(int bdId);
230     private static native int bridgeDomainIdFromInterfaceName0(String interfaceName);
231     private static native vppIPv4Address[] ipv4AddressDump0(String interfaceName);
232     private static native vppIPv6Address[] ipv6AddressDump0(String interfaceName);
233     private static native vppVxlanTunnelDetails[] vxlanTunnelDump0(int swIfIndex);
234     private static native int setInterfaceDescription0(String ifName, String ifDesc);
235     private static native String getInterfaceDescription0(String ifName);
236 }