VPP-530: adapt jvpp generation for VPP API splitting

Now jvpp uses *.json instead of *.py api representation.
Multiple *.json files are supported.

Change-Id: I89fa556c7d2a35d42833f2faaa28398ebd2ed012
Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
This commit is contained in:
Marek Gradzki
2016-11-25 08:38:29 +01:00
committed by Ole Trøan
parent c5b1360045
commit 2fee4c8fad
5 changed files with 65 additions and 46 deletions

View File

@ -158,13 +158,13 @@ libjvpp_ioamtrace_la_CPPFLAGS = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/li
BUILT_SOURCES += $(jvpp_root)/io_fd_vpp_jvpp_ioamtrace_JVppIoamtraceImpl.h BUILT_SOURCES += $(jvpp_root)/io_fd_vpp_jvpp_ioamtrace_JVppIoamtraceImpl.h
$(jvpp_root)/io_fd_vpp_jvpp_ioamtrace_JVppIoamtraceImpl.h: defs_ioam_trace_papi.py $(jvpp_root)/io_fd_vpp_jvpp_ioamtrace_JVppIoamtraceImpl.h: ioam_trace.api.json
dir=`pwd`; \ dir=`pwd`; \
mkdir -p $(jvpp_target); \ mkdir -p $(jvpp_target); \
mkdir -p $(jvpp_root)/$(jvpp_package_dir); \ mkdir -p $(jvpp_root)/$(jvpp_package_dir); \
cd $(jvpp_root)/$(jvpp_package_dir); \ cd $(jvpp_root)/$(jvpp_package_dir); \
mkdir -p dto future callfacade callback notification test; \ mkdir -p dto future callfacade callback notification test; \
@srcdir@/$(jvpp_registry_root)/jvpp/gen/jvpp_gen.py -i $${dir}/defs_ioam_trace_papi.py --plugin_name ioamtrace; \ @srcdir@/$(jvpp_registry_root)/jvpp/gen/jvpp_gen.py -i $${dir}/ioam_trace.api.json --plugin_name ioamtrace; \
cd -; \ cd -; \
mv -f $(jvpp_root)/$(jvpp_package_dir)/jvpp_ioamtrace_gen.h $(jvpp_root)/jvpp_ioam_trace_gen.h; \ mv -f $(jvpp_root)/$(jvpp_package_dir)/jvpp_ioamtrace_gen.h $(jvpp_root)/jvpp_ioam_trace_gen.h; \
cp $(srcdir)/$(jvpp_root)/$(jvpp_package_dir)/test/*.java $(jvpp_root)/$(jvpp_package_dir)/test/; \ cp $(srcdir)/$(jvpp_root)/$(jvpp_package_dir)/test/*.java $(jvpp_root)/$(jvpp_package_dir)/test/; \
@ -184,8 +184,8 @@ $(jioam_trace_jarfile): libjvpp_ioamtrace.la
cd $(jvpp_target); \ cd $(jvpp_target); \
$(JAR) cfv $(JARFLAGS) ../../../$@ libjvpp_ioamtrace.so.0.0.0 $(jvpp_package_dir)/* ; cd ..; $(JAR) cfv $(JARFLAGS) ../../../$@ libjvpp_ioamtrace.so.0.0.0 $(jvpp_package_dir)/* ; cd ..;
defs_ioam_trace_papi.py: ioam_trace.api.json:
@echo " jIoam_trace API"; \ @echo " jIoam_trace API"; \
vppapigen --input $(api_file) --python defs_ioam_trace_papi.py; vppapigen --input $(api_file) --json ioam_trace.api.json;
all-local: $(jioam_trace_jarfile) all-local: $(jioam_trace_jarfile)

View File

@ -83,13 +83,13 @@ libjvpp_snat_la_CPPFLAGS = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux -
BUILT_SOURCES += $(jvpp_root)/io_fd_vpp_jvpp_snat_JVppSnatImpl.h BUILT_SOURCES += $(jvpp_root)/io_fd_vpp_jvpp_snat_JVppSnatImpl.h
$(jvpp_root)/io_fd_vpp_jvpp_snat_JVppSnatImpl.h: defs_snat_papi.py $(jvpp_root)/io_fd_vpp_jvpp_snat_JVppSnatImpl.h: snat.api.json
dir=`pwd`; \ dir=`pwd`; \
mkdir -p $(jvpp_target); \ mkdir -p $(jvpp_target); \
mkdir -p $(jvpp_root)/$(jvpp_package_dir); \ mkdir -p $(jvpp_root)/$(jvpp_package_dir); \
cd $(jvpp_root)/$(jvpp_package_dir); \ cd $(jvpp_root)/$(jvpp_package_dir); \
mkdir -p dto future callfacade callback notification test; \ mkdir -p dto future callfacade callback notification test; \
@srcdir@/$(jvpp_registry_root)/jvpp/gen/jvpp_gen.py -i $${dir}/defs_snat_papi.py --plugin_name snat; \ @srcdir@/$(jvpp_registry_root)/jvpp/gen/jvpp_gen.py -i $${dir}/snat.api.json --plugin_name snat; \
cd -; \ cd -; \
mv -f $(jvpp_root)/$(jvpp_package_dir)/jvpp_snat_gen.h $(jvpp_root)/jvpp_snat_gen.h; \ mv -f $(jvpp_root)/$(jvpp_package_dir)/jvpp_snat_gen.h $(jvpp_root)/jvpp_snat_gen.h; \
cp $(srcdir)/$(jvpp_root)/$(jvpp_package_dir)/test/*.java $(jvpp_root)/$(jvpp_package_dir)/test/; \ cp $(srcdir)/$(jvpp_root)/$(jvpp_package_dir)/test/*.java $(jvpp_root)/$(jvpp_package_dir)/test/; \
@ -109,8 +109,8 @@ $(jsnat_jarfile): libjvpp_snat.la
cd $(jvpp_target); \ cd $(jvpp_target); \
$(JAR) cfv $(JARFLAGS) ../../../$@ libjvpp_snat.so.0.0.0 $(jvpp_package_dir)/* ; cd ..; $(JAR) cfv $(JARFLAGS) ../../../$@ libjvpp_snat.so.0.0.0 $(jvpp_package_dir)/* ; cd ..;
defs_snat_papi.py: snat.api.json:
@echo " jSnat_sfc API"; \ @echo " jSnat_sfc API"; \
vppapigen --input $(api_file) --python defs_snat_papi.py; vppapigen --input $(api_file) --json snat.api.json;
all-local: $(jsnat_jarfile) all-local: $(jsnat_jarfile)

View File

@ -13,13 +13,13 @@
AUTOMAKE_OPTIONS = foreign subdir-objects AUTOMAKE_OPTIONS = foreign subdir-objects
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
AM_CFLAGS = -Wall AM_CFLAGS = -Wall
noinst_PROGRAMS = noinst_PROGRAMS =
BUILT_SOURCES = BUILT_SOURCES =
bin_PROGRAMS = bin_PROGRAMS =
CLEANFILES = CLEANFILES =
lib_LTLIBRARIES = lib_LTLIBRARIES =
# #
# jvpp-common # jvpp-common
@ -80,20 +80,17 @@ libjvpp_core_la_CPPFLAGS = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
jarfile_jvpp_core = jvpp-core-$(PACKAGE_VERSION).jar jarfile_jvpp_core = jvpp-core-$(PACKAGE_VERSION).jar
packagedir_jvpp_core = io/fd/vpp/jvpp/core packagedir_jvpp_core = io/fd/vpp/jvpp/core
api_file = $(prefix)/../vpp/vpp-api/vpe.api
BUILT_SOURCES += jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h BUILT_SOURCES += jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h
jvpp-core/defs_vpp_papi.py: $(api_file) jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h: jvpp-registry/io_fd_vpp_jvpp_VppJNIConnection.h $(abs_builddir)/../vpp-api/vpe.api.json
@echo "jVpp API"
vppapigen --input $(api_file) --python jvpp-core/defs_vpp_papi.py
jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h: jvpp-registry/io_fd_vpp_jvpp_VppJNIConnection.h jvpp-core/defs_vpp_papi.py
cp -rf @srcdir@/jvpp-core/* -t jvpp-core/ cp -rf @srcdir@/jvpp-core/* -t jvpp-core/
mkdir -p jvpp-core/target mkdir -p jvpp-core/target
cd jvpp-core \ cd jvpp-core \
&& mkdir -p types dto future callfacade callback notification \ && mkdir -p types dto future callfacade callback notification \
&& @srcdir@/jvpp/gen/jvpp_gen.py -i defs_vpp_papi.py --plugin_name core \ && @srcdir@/jvpp/gen/jvpp_gen.py --plugin_name core \
-i $(abs_builddir)/../vpp-api/vpe.api.json \
$(abs_builddir)/../vpp-api/interface.api.json \
&& cp -rf types dto future callfacade callback notification *.java -t $(packagedir_jvpp_core) \ && cp -rf types dto future callfacade callback notification *.java -t $(packagedir_jvpp_core) \
&& rm -rf types dto future callfacade callback notification *.java && rm -rf types dto future callfacade callback notification *.java
@ -104,6 +101,7 @@ jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h: jvpp-registry/io_fd_vpp_jvpp_VppJN
jvpp-core/$(packagedir_jvpp_core)/notification/*.java \ jvpp-core/$(packagedir_jvpp_core)/notification/*.java \
jvpp-core/$(packagedir_jvpp_core)/future/*.java \ jvpp-core/$(packagedir_jvpp_core)/future/*.java \
jvpp-core/$(packagedir_jvpp_core)/callfacade/*.java \ jvpp-core/$(packagedir_jvpp_core)/callfacade/*.java \
jvpp-core/$(packagedir_jvpp_core)/test/*.java \
|| (echo "jvpp-core compilation failed: $$?"; exit 1) || (echo "jvpp-core compilation failed: $$?"; exit 1)
$(JAVAH) -force -classpath jvpp-registry/target:jvpp-core/target -d jvpp-core io.fd.vpp.jvpp.core.JVppCoreImpl $(JAVAH) -force -classpath jvpp-registry/target:jvpp-core/target -d jvpp-core io.fd.vpp.jvpp.core.JVppCoreImpl

View File

@ -38,7 +38,7 @@
// TODO: generate jvpp_plugin_name.c files (or at least reuse plugin's main structure) // TODO: generate jvpp_plugin_name.c files (or at least reuse plugin's main structure)
typedef struct { typedef struct {
/* Base message index for the nsh plugin */ /* Base message index for the jvpp-core plugin */
u16 msg_id_base; u16 msg_id_base;
/* Pointer to shared memory queue */ /* Pointer to shared memory queue */

View File

@ -18,6 +18,7 @@ import argparse
import importlib import importlib
import sys import sys
import os import os
import json
from jvppgen import types_gen from jvppgen import types_gen
from jvppgen import callback_gen from jvppgen import callback_gen
@ -40,22 +41,30 @@ from jvppgen import util
# defs_api_vpp_papi.py - vpe.api in python format (generated by vppapigen) # defs_api_vpp_papi.py - vpe.api in python format (generated by vppapigen)
parser = argparse.ArgumentParser(description='VPP Java API generator') parser = argparse.ArgumentParser(description='VPP Java API generator')
parser.add_argument('-i', action="store", dest="inputfile") parser.add_argument('-i', action="store", dest="inputfiles", nargs='+')
parser.add_argument('--plugin_name', action="store", dest="plugin_name") parser.add_argument('--plugin_name', action="store", dest="plugin_name")
args = parser.parse_args() args = parser.parse_args()
sys.path.append(".") sys.path.append(".")
print "Generating Java API for %s" % args.inputfile print "Generating Java API for %s" % args.inputfiles
importdir = os.path.dirname(args.inputfile) print "inputfiles %s" % args.inputfiles
print "importdir %s" % importdir
inputfile = os.path.basename(args.inputfile)
inputfile = inputfile.replace('.py', '')
print "inputfile %s" % inputfile
plugin_name = args.plugin_name plugin_name = args.plugin_name
print "plugin_name %s" % plugin_name print "plugin_name %s" % plugin_name
sys.path.append(importdir)
cfg = importlib.import_module(inputfile, package=None) cfg = {}
for inputfile in args.inputfiles:
_cfg = json.load(open(inputfile, 'r'))
if 'types' in cfg:
cfg['types'].extend(_cfg['types'])
else:
cfg['types'] = _cfg['types']
if 'messages' in cfg:
cfg['messages'].extend(_cfg['messages'])
else:
cfg['messages'] = _cfg['messages']
def is_request_field(field_name): def is_request_field(field_name):
return field_name not in {'_vl_msg_id', 'client_index', 'context'} return field_name not in {'_vl_msg_id', 'client_index', 'context'}
@ -68,6 +77,8 @@ def is_response_field(field_name):
def get_args(t, filter): def get_args(t, filter):
arg_list = [] arg_list = []
for i in t: for i in t:
if is_crc(i):
continue
if not filter(i[1]): if not filter(i[1]):
continue continue
arg_list.append(i[1]) arg_list.append(i[1])
@ -77,7 +88,11 @@ def get_args(t, filter):
def get_types(t, filter): def get_types(t, filter):
types_list = [] types_list = []
lengths_list = [] lengths_list = []
crc = None
for i in t: for i in t:
if is_crc(i):
crc = ('crc', i['crc'][2:])
continue
if not filter(i[1]): if not filter(i[1]):
continue continue
if len(i) is 3: # array type if len(i) is 3: # array type
@ -89,7 +104,12 @@ def get_types(t, filter):
else: # primitive type else: # primitive type
types_list.append(i[0]) types_list.append(i[0])
lengths_list.append((0, False)) lengths_list.append((0, False))
return types_list, lengths_list return types_list, lengths_list, crc
def is_crc(arg):
""" Check whether the argument inside message definition is just crc """
return 'crc' in arg
def get_definitions(defs): def get_definitions(defs):
@ -101,18 +121,18 @@ def get_definitions(defs):
# For replies include all the arguments except message_id # For replies include all the arguments except message_id
if util.is_reply(java_name): if util.is_reply(java_name):
types, lengths = get_types(a[1:], is_response_field) types, lengths, crc = get_types(a[1:], is_response_field)
func_name[a[0]] = dict( func_name[a[0]] = dict(
[('name', a[0]), ('java_name', java_name), [('name', a[0]), ('java_name', java_name),
('args', get_args(a[1:], is_response_field)), ('full_args', get_args(a[1:], lambda x: True)), ('args', get_args(a[1:], is_response_field)), ('full_args', get_args(a[1:], lambda x: True)),
('types', types), ('lengths', lengths)]) ('types', types), ('lengths', lengths), crc])
# For requests skip message_id, client_id and context # For requests skip message_id, client_id and context
else: else:
types, lengths = get_types(a[1:], is_request_field) types, lengths, crc = get_types(a[1:], is_request_field)
func_name[a[0]] = dict( func_name[a[0]] = dict(
[('name', a[0]), ('java_name', java_name), [('name', a[0]), ('java_name', java_name),
('args', get_args(a[1:], is_request_field)), ('full_args', get_args(a[1:], lambda x: True)), ('args', get_args(a[1:], is_request_field)), ('full_args', get_args(a[1:], lambda x: True)),
('types', types), ('lengths', lengths)]) ('types', types), ('lengths', lengths), crc])
# Indexed by name # Indexed by name
func_list.append(func_name[a[0]]) func_list.append(func_name[a[0]])
@ -129,17 +149,18 @@ future_package = 'future'
# TODO find better package name # TODO find better package name
callback_facade_package = 'callfacade' callback_facade_package = 'callfacade'
types_list, types_name = get_definitions(cfg.types) types_list, types_name = get_definitions(cfg['types'])
types_gen.generate_types(types_list, plugin_package, types_package, inputfile) types_gen.generate_types(types_list, plugin_package, types_package, args.inputfiles)
func_list, func_name = get_definitions(cfg.messages) func_list, func_name = get_definitions(cfg['messages'])
dto_gen.generate_dtos(func_list, base_package, plugin_package, plugin_name.title(), dto_package, args.inputfile)
jvpp_impl_gen.generate_jvpp(func_list, base_package, plugin_package, plugin_name, dto_package, args.inputfile)
callback_gen.generate_callbacks(func_list, base_package, plugin_package, plugin_name.title(), callback_package, dto_package, args.inputfile)
notification_gen.generate_notification_registry(func_list, base_package, plugin_package, plugin_name.title(), notification_package, callback_package, dto_package, args.inputfile)
jvpp_c_gen.generate_jvpp(func_list, plugin_name, args.inputfile)
jvpp_future_facade_gen.generate_jvpp(func_list, base_package, plugin_package, plugin_name.title(), dto_package, callback_package, notification_package, future_package, args.inputfile)
jvpp_callback_facade_gen.generate_jvpp(func_list, base_package, plugin_package, plugin_name.title(), dto_package, callback_package, notification_package, callback_facade_package, args.inputfile)
print "Java API for %s generated successfully" % args.inputfile dto_gen.generate_dtos(func_list, base_package, plugin_package, plugin_name.title(), dto_package, args.inputfiles)
jvpp_impl_gen.generate_jvpp(func_list, base_package, plugin_package, plugin_name, dto_package, args.inputfiles)
callback_gen.generate_callbacks(func_list, base_package, plugin_package, plugin_name.title(), callback_package, dto_package, args.inputfiles)
notification_gen.generate_notification_registry(func_list, base_package, plugin_package, plugin_name.title(), notification_package, callback_package, dto_package, args.inputfiles)
jvpp_c_gen.generate_jvpp(func_list, plugin_name, args.inputfiles)
jvpp_future_facade_gen.generate_jvpp(func_list, base_package, plugin_package, plugin_name.title(), dto_package, callback_package, notification_package, future_package, args.inputfiles)
jvpp_callback_facade_gen.generate_jvpp(func_list, base_package, plugin_package, plugin_name.title(), dto_package, callback_package, notification_package, callback_facade_package, args.inputfiles)
print "Java API for %s generated successfully" % args.inputfiles