3 # Copyright (c) 2016,2018 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.
16 from string import Template
18 from jvpp_model import is_request, is_dump, is_event
21 def generate_java_impl(work_dir, model, logger):
22 logger.debug("Generating JVpp implementation for %s" % model.json_api_files)
23 messages = filter(_jvpp_impl_filter, model.messages)
24 plugin_package = model.plugin_package
28 methods.append(_JVPP_IMPL_METHOD_TEMPLATE.substitute(
29 name=msg.java_name_lower,
30 plugin_package=plugin_package,
31 type=msg.java_name_upper))
33 methods.append(_JVPP_IMPL_NO_ARG_METHOD_TEMPLATE.substitute(
34 name=msg.java_name_lower,
35 type=msg.java_name_upper))
37 plugin_name = model.plugin_java_name
38 jvpp_impl = _JVPP_IMPL_TEMPLATE.substitute(
39 plugin_package=plugin_package,
40 json_filename=model.json_api_files,
41 plugin_name=model.plugin_java_name,
42 plugin_name_underscore=model.plugin_name,
43 methods="\n".join(methods))
45 with open("%s/JVpp%sImpl.java" % (work_dir, plugin_name), "w") as f:
49 def _jvpp_impl_filter(msg):
50 return is_request(msg) or is_dump(msg) or is_event(msg)
53 _JVPP_IMPL_TEMPLATE = Template("""package $plugin_package;
55 import java.io.IOException;
56 import java.io.InputStream;
57 import java.nio.file.Files;
58 import java.nio.file.Path;
59 import java.nio.file.StandardCopyOption;
60 import java.nio.file.attribute.PosixFilePermission;
61 import java.nio.file.attribute.PosixFilePermissions;
63 import java.util.logging.Logger;
64 import java.util.logging.Level;
65 import io.fd.vpp.jvpp.callback.JVppCallback;
66 import io.fd.vpp.jvpp.VppConnection;
67 import io.fd.vpp.jvpp.JVppRegistry;
70 * <p>Default implementation of JVpp interface.
71 * <br>It was generated by jvpp_impl_gen.py based on $json_filename.
72 * <br>(python representation of api file generated by vppapigen)
74 public final class JVpp${plugin_name}Impl implements $plugin_package.JVpp${plugin_name} {
76 private final static Logger LOG = Logger.getLogger(JVpp${plugin_name}Impl.class.getName());
77 private static final String LIBNAME = "libjvpp_${plugin_name_underscore}.so";
79 // FIXME using NativeLibraryLoader makes load fail could not find (WantInterfaceEventsReply).
83 } catch (Exception e) {
84 LOG.severe("Can't find jvpp jni library: " + LIBNAME);
85 throw new ExceptionInInitializerError(e);
89 private static void loadStream(final InputStream is) throws IOException {
90 final Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");
91 final Path p = Files.createTempFile(LIBNAME, null, PosixFilePermissions.asFileAttribute(perms));
93 Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
96 Runtime.getRuntime().load(p.toString());
97 } catch (UnsatisfiedLinkError e) {
98 throw new IOException("Failed to load library " + p, e);
102 Files.deleteIfExists(p);
103 } catch (IOException e) {
108 private static void loadLibrary() throws IOException {
109 try (final InputStream is = JVpp${plugin_name}Impl.class.getResourceAsStream('/' + LIBNAME)) {
111 throw new IOException("Failed to open library resource " + LIBNAME);
117 private VppConnection connection;
118 private JVppRegistry registry;
120 private static native void init0(final JVppCallback callback, final long queueAddress, final int clientIndex);
122 public void init(final JVppRegistry registry, final JVppCallback callback, final long queueAddress, final int clientIndex) {
123 this.registry = java.util.Objects.requireNonNull(registry, "registry should not be null");
124 this.connection = java.util.Objects.requireNonNull(registry.getConnection(), "connection should not be null");
125 connection.checkActive();
126 init0(callback, queueAddress, clientIndex);
129 private static native void close0();
131 public void close() {
136 public int send(io.fd.vpp.jvpp.dto.JVppRequest request) throws io.fd.vpp.jvpp.VppInvocationException {
137 return request.send(this);
141 public final int controlPing(final io.fd.vpp.jvpp.dto.ControlPing controlPing) throws io.fd.vpp.jvpp.VppInvocationException {
142 return registry.controlPing(JVpp${plugin_name}Impl.class);
148 _JVPP_IMPL_METHOD_TEMPLATE = Template("""
149 private static native int ${name}0($plugin_package.dto.$type request);
150 public final int $name($plugin_package.dto.$type request) throws io.fd.vpp.jvpp.VppInvocationException {
151 java.util.Objects.requireNonNull(request, "Null request object");
152 connection.checkActive();
153 if (LOG.isLoggable(Level.FINE)) {
154 LOG.fine(String.format("Sending $type event message: %s", request));
156 int result=${name}0(request);
158 throw new io.fd.vpp.jvpp.VppInvocationException("${name}", result);
163 _JVPP_IMPL_NO_ARG_METHOD_TEMPLATE = Template("""
164 private static native int ${name}0() throws io.fd.vpp.jvpp.VppInvocationException;
165 public final int $name() throws io.fd.vpp.jvpp.VppInvocationException {
166 connection.checkActive();
167 LOG.fine("Sending $type event message");
168 int result=${name}0();
170 throw new io.fd.vpp.jvpp.VppInvocationException("${name}", result);