diff options
Diffstat (limited to 'vpp-api/java/jvpp/gen/jvppgen')
-rw-r--r-- | vpp-api/java/jvpp/gen/jvppgen/callback_gen.py | 27 | ||||
-rw-r--r-- | vpp-api/java/jvpp/gen/jvppgen/dto_gen.py | 41 | ||||
-rw-r--r-- | vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py | 103 | ||||
-rw-r--r-- | vpp-api/java/jvpp/gen/jvppgen/jvpp_callback_facade_gen.py | 119 | ||||
-rw-r--r-- | vpp-api/java/jvpp/gen/jvppgen/jvpp_future_facade_gen.py | 158 | ||||
-rw-r--r-- | vpp-api/java/jvpp/gen/jvppgen/jvpp_impl_gen.py | 143 | ||||
-rw-r--r-- | vpp-api/java/jvpp/gen/jvppgen/notification_gen.py | 137 | ||||
-rw-r--r-- | vpp-api/java/jvpp/gen/jvppgen/util.py | 13 |
8 files changed, 451 insertions, 290 deletions
diff --git a/vpp-api/java/jvpp/gen/jvppgen/callback_gen.py b/vpp-api/java/jvpp/gen/jvppgen/callback_gen.py index eadf3b5c50d..68f70126a04 100644 --- a/vpp-api/java/jvpp/gen/jvppgen/callback_gen.py +++ b/vpp-api/java/jvpp/gen/jvppgen/callback_gen.py @@ -22,10 +22,10 @@ from util import remove_suffix callback_suffix = "Callback" callback_template = Template(""" -package $base_package.$callback_package; +package $plugin_package.$callback_package; /** - * <p>Represents callback for vpe.api message. + * <p>Represents callback for plugin's api file message. * <br>It was generated by callback_gen.py based on $inputfile preparsed data: * <pre> $docs @@ -39,19 +39,19 @@ public interface $cls_name extends $base_package.$callback_package.$callback_typ """) global_callback_template = Template(""" -package $base_package.$callback_package; +package $plugin_package.$callback_package; /** * <p>Global aggregated callback interface. * <br>It was generated by callback_gen.py based on $inputfile - * <br>(python representation of vpe.api generated by vppapigen). + * <br>(python representation of api file generated by vppapigen). */ -public interface JVppGlobalCallback extends $callbacks { +public interface JVpp${plugin_name}GlobalCallback extends $base_package.$callback_package.ControlPingCallback, $callbacks { } """) -def generate_callbacks(func_list, base_package, callback_package, dto_package, inputfile): +def generate_callbacks(func_list, base_package, plugin_package, plugin_name, callback_package, dto_package, inputfile): """ Generates callback interfaces """ print "Generating Callback interfaces" @@ -61,10 +61,10 @@ def generate_callbacks(func_list, base_package, callback_package, dto_package, i callbacks = [] for func in func_list: - if util.is_ignored(func['name']): - continue - camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name']) + + if util.is_ignored(func['name']) or util.is_control_ping(camel_case_name_with_suffix): + continue if not util.is_reply(camel_case_name_with_suffix) and not util.is_notification(func['name']): continue @@ -76,11 +76,11 @@ def generate_callbacks(func_list, base_package, callback_package, dto_package, i camel_case_name = camel_case_name_with_suffix callback_type = "JVppNotificationCallback" - callbacks.append("{0}.{1}.{2}".format(base_package, callback_package, camel_case_name + callback_suffix)) + callbacks.append("{0}.{1}.{2}".format(plugin_package, callback_package, camel_case_name + callback_suffix)) callback_path = os.path.join(callback_package, camel_case_name + callback_suffix + ".java") callback_file = open(callback_path, 'w') - reply_type = "%s.%s.%s" % (base_package, dto_package, camel_case_name_with_suffix) + reply_type = "%s.%s.%s" % (plugin_package, dto_package, camel_case_name_with_suffix) method = "void on{0}({1} reply);".format(camel_case_name_with_suffix, reply_type) callback_file.write( callback_template.substitute(inputfile=inputfile, @@ -88,15 +88,18 @@ def generate_callbacks(func_list, base_package, callback_package, dto_package, i cls_name=camel_case_name + callback_suffix, callback_method=method, base_package=base_package, + plugin_package=plugin_package, callback_package=callback_package, callback_type=callback_type)) callback_file.flush() callback_file.close() - callback_file = open(os.path.join(callback_package, "JVppGlobalCallback.java"), 'w') + callback_file = open(os.path.join(callback_package, "JVpp%sGlobalCallback.java" % plugin_name), 'w') callback_file.write(global_callback_template.substitute(inputfile=inputfile, callbacks=", ".join(callbacks), base_package=base_package, + plugin_package=plugin_package, + plugin_name=plugin_name, callback_package=callback_package)) callback_file.flush() callback_file.close() diff --git a/vpp-api/java/jvpp/gen/jvppgen/dto_gen.py b/vpp-api/java/jvpp/gen/jvppgen/dto_gen.py index 426cd96b2ac..785e47e9ef7 100644 --- a/vpp-api/java/jvpp/gen/jvppgen/dto_gen.py +++ b/vpp-api/java/jvpp/gen/jvppgen/dto_gen.py @@ -19,7 +19,7 @@ from string import Template import util dto_template = Template(""" -package $base_package.$dto_package; +package $plugin_package.$dto_package; /** * <p>This class represents $description. @@ -39,11 +39,11 @@ field_template = Template(""" public $type $name;\n""") send_template = Template(""" @Override public int send(final $base_package.JVpp jvpp) throws org.openvpp.jvpp.VppInvocationException { - return jvpp.$method_name($args); + return (($plugin_package.JVpp${plugin_name})jvpp).$method_name($args); }\n""") -def generate_dtos(func_list, base_package, dto_package, inputfile): +def generate_dtos(func_list, base_package, plugin_package, plugin_name, dto_package, inputfile): """ Generates dto objects in a dedicated package """ print "Generating DTOs" @@ -55,7 +55,7 @@ def generate_dtos(func_list, base_package, dto_package, inputfile): camel_case_method_name = util.underscore_to_camelcase(func['name']) dto_path = os.path.join(dto_package, camel_case_dto_name + ".java") - if util.is_ignored(func['name']): + if util.is_ignored(func['name']) or util.is_control_ping(camel_case_dto_name): continue fields = "" @@ -72,44 +72,46 @@ def generate_dtos(func_list, base_package, dto_package, inputfile): # Generate request/reply or dump/dumpReply even if structure can be used as notification if not util.is_just_notification(func["name"]): if util.is_reply(camel_case_dto_name): - description = "vpe.api reply DTO" + description = "reply DTO" request_dto_name = get_request_name(camel_case_dto_name, func['name']) if util.is_details(camel_case_dto_name): # FIXME assumption that dump calls end with "Dump" suffix. Not enforced in vpe.api - base_type += "JVppReply<%s.%s.%s>" % (base_package, dto_package, request_dto_name + "Dump") - generate_dump_reply_dto(request_dto_name, base_package, dto_package, camel_case_dto_name, + base_type += "JVppReply<%s.%s.%s>" % (plugin_package, dto_package, request_dto_name + "Dump") + generate_dump_reply_dto(request_dto_name, base_package, plugin_package, dto_package, camel_case_dto_name, camel_case_method_name, func) else: - base_type += "JVppReply<%s.%s.%s>" % (base_package, dto_package, request_dto_name) + base_type += "JVppReply<%s.%s.%s>" % (plugin_package, dto_package, request_dto_name) else: args = "" if fields is "" else "this" methods = send_template.substitute(method_name=camel_case_method_name, base_package=base_package, + plugin_package=plugin_package, + plugin_name=plugin_name, args=args) if util.is_dump(camel_case_dto_name): base_type += "JVppDump" - description = "vpe.api dump request DTO" + description = "dump request DTO" else: base_type += "JVppRequest" - description = "vpe.api request DTO" + description = "request DTO" - write_dto_file(base_package, base_type, camel_case_dto_name, description, dto_package, dto_path, fields, func, + write_dto_file(base_package, plugin_package, base_type, camel_case_dto_name, description, dto_package, dto_path, fields, func, inputfile, methods) # for structures that are also used as notifications, generate dedicated notification DTO if util.is_notification(func["name"]): base_type = "JVppNotification" - description = "vpe.api notification DTO" + description = "notification DTO" camel_case_dto_name = util.add_notification_suffix(camel_case_dto_name) methods = "" dto_path = os.path.join(dto_package, camel_case_dto_name + ".java") - write_dto_file(base_package, base_type, camel_case_dto_name, description, dto_package, dto_path, fields, func, + write_dto_file(base_package, plugin_package, base_type, camel_case_dto_name, description, dto_package, dto_path, fields, func, inputfile, methods) flush_dump_reply_dtos(inputfile) -def write_dto_file(base_package, base_type, camel_case_dto_name, description, dto_package, dto_path, fields, func, +def write_dto_file(base_package, plugin_package, base_type, camel_case_dto_name, description, dto_package, dto_path, fields, func, inputfile, methods): dto_file = open(dto_path, 'w') dto_file.write(dto_template.substitute(inputfile=inputfile, @@ -119,6 +121,7 @@ def write_dto_file(base_package, base_type, camel_case_dto_name, description, dt fields=fields, methods=methods, base_package=base_package, + plugin_package=plugin_package, base_type=base_type, dto_package=dto_package)) dto_file.flush() @@ -141,11 +144,12 @@ def flush_dump_reply_dtos(inputfile): dump_reply_artificial_dto['cls_name'] + ".java") dto_file = open(dto_path, 'w') dto_file.write(dto_template.substitute(inputfile=inputfile, - description="vpe.api dump reply wrapper", + description="dump reply wrapper", docs=dump_reply_artificial_dto['docs'], cls_name=dump_reply_artificial_dto['cls_name'], fields=dump_reply_artificial_dto['fields'], methods=dump_reply_artificial_dto['methods'], + plugin_package=dump_reply_artificial_dto['plugin_package'], base_package=dump_reply_artificial_dto['base_package'], base_type=dump_reply_artificial_dto['base_type'], dto_package=dump_reply_artificial_dto['dto_package'])) @@ -153,11 +157,11 @@ def flush_dump_reply_dtos(inputfile): dto_file.close() -def generate_dump_reply_dto(request_dto_name, base_package, dto_package, camel_case_dto_name, camel_case_method_name, +def generate_dump_reply_dto(request_dto_name, base_package, plugin_package, dto_package, camel_case_dto_name, camel_case_method_name, func): base_type = "JVppReplyDump<%s.%s.%s, %s.%s.%s>" % ( - base_package, dto_package, util.remove_reply_suffix(camel_case_dto_name) + "Dump", - base_package, dto_package, camel_case_dto_name) + plugin_package, dto_package, util.remove_reply_suffix(camel_case_dto_name) + "Dump", + plugin_package, dto_package, camel_case_dto_name) fields = " public java.util.List<%s> %s = new java.util.ArrayList<>();" % (camel_case_dto_name, camel_case_method_name) cls_name = camel_case_dto_name + dump_dto_suffix @@ -171,6 +175,7 @@ def generate_dump_reply_dto(request_dto_name, base_package, dto_package, camel_c 'cls_name': cls_name, 'fields': fields, 'methods': "", + 'plugin_package': plugin_package, 'base_package': base_package, 'base_type': base_type, 'dto_package': dto_package, diff --git a/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py b/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py index 1796ac1719b..cd3a3566f42 100644 --- a/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py +++ b/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py @@ -17,7 +17,7 @@ import os, util from string import Template -def is_manually_generated(f_name): +def is_manually_generated(f_name, plugin_name): return f_name in {'control_ping_reply'} @@ -25,7 +25,7 @@ class_reference_template = Template("""jclass ${ref_name}Class; """) find_class_invocation_template = Template(""" - ${ref_name}Class = (jclass)(*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/openvpp/jvpp/dto/${class_name}")); + ${ref_name}Class = (jclass)(*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/openvpp/jvpp/${plugin_name}/dto/${class_name}")); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionDescribe(env); return JNI_ERR; @@ -38,53 +38,71 @@ find_class_template = Template(""" return JNI_ERR; }""") +delete_class_invocation_template = Template(""" + if (${ref_name}Class) { + (*env)->DeleteGlobalRef(env, ${ref_name}Class); + }""") + class_cache_template = Template(""" $class_references static int cache_class_references(JNIEnv* env) { $find_class_invocations return 0; +} + +static void delete_class_references(JNIEnv* env) { + $delete_class_invocations }""") -def generate_class_cache(func_list): +def generate_class_cache(func_list, plugin_name): class_references = [] find_class_invocations = [] + delete_class_invocations = [] for f in func_list: c_name = f['name'] class_name = util.underscore_to_camelcase_upper(c_name) ref_name = util.underscore_to_camelcase(c_name) - if util.is_ignored(c_name): + if util.is_ignored(c_name) or util.is_control_ping(class_name): continue if util.is_reply(class_name): class_references.append(class_reference_template.substitute( ref_name=ref_name)) find_class_invocations.append(find_class_invocation_template.substitute( + plugin_name=plugin_name, ref_name=ref_name, class_name=class_name)) + delete_class_invocations.append(delete_class_invocation_template.substitute(ref_name=ref_name)) elif util.is_notification(c_name): class_references.append(class_reference_template.substitute( ref_name=util.add_notification_suffix(ref_name))) find_class_invocations.append(find_class_invocation_template.substitute( + plugin_name=plugin_name, ref_name=util.add_notification_suffix(ref_name), class_name=util.add_notification_suffix(class_name))) + delete_class_invocations.append(delete_class_invocation_template.substitute( + ref_name=util.add_notification_suffix(ref_name))) # add exception class to class cache ref_name = 'callbackException' class_name = 'org/openvpp/jvpp/VppCallbackException' class_references.append(class_reference_template.substitute( - ref_name=ref_name)) + ref_name=ref_name)) find_class_invocations.append(find_class_template.substitute( ref_name=ref_name, class_name=class_name)) + delete_class_invocations.append(delete_class_invocation_template.substitute(ref_name=ref_name)) + return class_cache_template.substitute( - class_references="".join(class_references), find_class_invocations="".join(find_class_invocations)) + class_references="".join(class_references), find_class_invocations="".join(find_class_invocations), + delete_class_invocations="".join(delete_class_invocations)) # TODO: cache method and field identifiers to achieve better performance # https://jira.fd.io/browse/HONEYCOMB-42 request_class_template = Template(""" - jclass requestClass = (*env)->FindClass(env, "org/openvpp/jvpp/dto/${java_name_upper}");""") + jclass requestClass = (*env)->FindClass(env, "org/openvpp/jvpp/${plugin_name}/dto/${java_name_upper}");""") request_field_identifier_template = Template(""" jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, requestClass, "${java_name}", "${jni_signature}"); @@ -178,37 +196,40 @@ struct_setter_templates = {'u8': u8_struct_setter_template, jni_impl_template = Template(""" /** - * JNI binding for sending ${c_name} vpe.api message. + * JNI binding for sending ${c_name} message. * Generated based on $inputfile preparsed data: $api_data */ -JNIEXPORT jint JNICALL Java_org_openvpp_jvpp_JVppImpl_${java_name}0 +JNIEXPORT jint JNICALL Java_org_openvpp_jvpp_${plugin_name}_JVpp${java_plugin_name}Impl_${java_name}0 (JNIEnv * env, jclass clazz$args) { - vppjni_main_t *jm = &vppjni_main; + ${plugin_name}_main_t *plugin_main = &${plugin_name}_main; vl_api_${c_name}_t * mp; - u32 my_context_id; - int rv; - rv = vppjni_sanity_check (jm); - if (rv) return rv; - my_context_id = vppjni_get_context_id (jm); + u32 my_context_id = vppjni_get_context_id (&jvpp_main); $request_class $field_identifiers - M(${c_name_uppercase}, ${c_name}); + + // create message: + mp = vl_msg_api_alloc(sizeof(*mp)); + memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_${c_name_uppercase} + plugin_main->msg_id_base); + mp->client_index = plugin_main->my_client_index; mp->context = clib_host_to_net_u32 (my_context_id); + $struct_setters - S; + // send message: + vl_msg_api_send_shmem (plugin_main->vl_input_queue, (u8 *)&mp); if ((*env)->ExceptionCheck(env)) { return JNI_ERR; } return my_context_id; }""") -def generate_jni_impl(func_list, inputfile): +def generate_jni_impl(func_list, plugin_name, inputfile): jni_impl = [] for f in func_list: f_name = f['name'] camel_case_function_name = util.underscore_to_camelcase(f_name) - if is_manually_generated(f_name) or util.is_reply(camel_case_function_name) \ + if is_manually_generated(f_name, plugin_name) or util.is_reply(camel_case_function_name) \ or util.is_ignored(f_name) or util.is_just_notification(f_name): continue @@ -222,7 +243,9 @@ def generate_jni_impl(func_list, inputfile): arguments = ', jobject request' camel_case_function_name_upper = util.underscore_to_camelcase_upper(f_name) - request_class = request_class_template.substitute(java_name_upper=camel_case_function_name_upper) + request_class = request_class_template.substitute( + java_name_upper=camel_case_function_name_upper, + plugin_name=plugin_name) # field identifiers for t in zip(f['types'], f['args']): @@ -261,6 +284,8 @@ def generate_jni_impl(func_list, inputfile): java_name=camel_case_function_name, c_name_uppercase=f_name_uppercase, c_name=f_name, + plugin_name=plugin_name, + java_plugin_name=plugin_name.title(), request_class=request_class, field_identifiers=field_identifiers, struct_setters=struct_setters, @@ -357,7 +382,7 @@ dto_field_setter_templates = {'u8': default_dto_field_setter_template, callback_err_handler_template = Template(""" // for negative result don't send callback message but send error callback if (mp->retval<0) { - CallOnError("${handler_name}",mp->context,mp->retval); + call_on_error("${handler_name}", mp->context, mp->retval, plugin_main->callbackClass, plugin_main->callbackObject, callbackExceptionClass); return; } if (mp->retval == VNET_API_ERROR_IN_PROGRESS) { @@ -368,32 +393,34 @@ callback_err_handler_template = Template(""" msg_handler_template = Template(""" /** - * Handler for ${handler_name} vpe.api message. + * Handler for ${handler_name} message. * Generated based on $inputfile preparsed data: $api_data */ static void vl_api_${handler_name}_t_handler (vl_api_${handler_name}_t * mp) { - vppjni_main_t * jm = &vppjni_main; - JNIEnv *env = jm->jenv; + ${plugin_name}_main_t *plugin_main = &${plugin_name}_main; + JNIEnv *env = jvpp_main.jenv; + $err_handler jmethodID constructor = (*env)->GetMethodID(env, ${class_ref_name}Class, "<init>", "()V"); - jmethodID callbackMethod = (*env)->GetMethodID(env, jm->callbackClass, "on${dto_name}", "(Lorg/openvpp/jvpp/dto/${dto_name};)V"); + jmethodID callbackMethod = (*env)->GetMethodID(env, plugin_main->callbackClass, "on${dto_name}", "(Lorg/openvpp/jvpp/${plugin_name}/dto/${dto_name};)V"); jobject dto = (*env)->NewObject(env, ${class_ref_name}Class, constructor); $dto_setters - (*env)->CallVoidMethod(env, jm->callback, callbackMethod, dto); + + (*env)->CallVoidMethod(env, plugin_main->callbackObject, callbackMethod, dto); }""") -def generate_msg_handlers(func_list, inputfile): +def generate_msg_handlers(func_list, plugin_name, inputfile): handlers = [] for f in func_list: handler_name = f['name'] dto_name = util.underscore_to_camelcase_upper(handler_name) ref_name = util.underscore_to_camelcase(handler_name) - if is_manually_generated(handler_name) or util.is_ignored(handler_name): + if is_manually_generated(handler_name, plugin_name) or util.is_ignored(handler_name): continue if not util.is_reply(dto_name) and not util.is_notification(handler_name): @@ -455,6 +482,7 @@ def generate_msg_handlers(func_list, inputfile): inputfile=inputfile, api_data=util.api_message_to_javadoc(f), handler_name=handler_name, + plugin_name=plugin_name, dto_name=dto_name, class_ref_name=ref_name, dto_setters=dto_setters, @@ -468,12 +496,13 @@ handler_registration_template = Template("""_(${upercase_name}, ${name}) \\ def generate_handler_registration(func_list): - handler_registration = ["#define foreach_vpe_api_msg \\\n"] + handler_registration = ["#define foreach_api_reply_handler \\\n"] for f in func_list: name = f['name'] camelcase_name = util.underscore_to_camelcase(f['name']) - if (not util.is_reply(camelcase_name) and not util.is_notification(name)) or util.is_ignored(name): + if (not util.is_reply(camelcase_name) and not util.is_notification(name)) or util.is_ignored(name) \ + or util.is_control_ping(camelcase_name): continue handler_registration.append(handler_registration_template.substitute( @@ -486,11 +515,9 @@ def generate_handler_registration(func_list): jvpp_c_template = Template("""/** * This file contains JNI bindings for jvpp Java API. * It was generated by jvpp_c_gen.py based on $inputfile - * (python representation of vpe.api generated by vppapigen). + * (python representation of api file generated by vppapigen). */ -void CallOnError(const char* call, int context, int retval); - // JAVA class reference cache $class_cache @@ -504,16 +531,16 @@ $msg_handlers $handler_registration """) -def generate_jvpp(func_list, inputfile): +def generate_jvpp(func_list, plugin_name, inputfile): """ Generates jvpp C file """ print "Generating jvpp C" - class_cache = generate_class_cache(func_list) - jni_impl = generate_jni_impl(func_list, inputfile) - msg_handlers = generate_msg_handlers(func_list, inputfile) + class_cache = generate_class_cache(func_list, plugin_name) + jni_impl = generate_jni_impl(func_list, plugin_name, inputfile) + msg_handlers = generate_msg_handlers(func_list, plugin_name, inputfile) handler_registration = generate_handler_registration(func_list) - jvpp_c_file = open("jvpp_gen.h", 'w') + jvpp_c_file = open("jvpp_%s_gen.h" % plugin_name, 'w') jvpp_c_file.write(jvpp_c_template.substitute( inputfile=inputfile, class_cache=class_cache, diff --git a/vpp-api/java/jvpp/gen/jvppgen/jvpp_callback_facade_gen.py b/vpp-api/java/jvpp/gen/jvppgen/jvpp_callback_facade_gen.py index 7df17486a60..ac096a7163d 100644 --- a/vpp-api/java/jvpp/gen/jvppgen/jvpp_callback_facade_gen.py +++ b/vpp-api/java/jvpp/gen/jvppgen/jvpp_callback_facade_gen.py @@ -20,17 +20,14 @@ import callback_gen import dto_gen jvpp_ifc_template = Template(""" -package $base_package.$callback_facade_package; +package $plugin_package.$callback_facade_package; /** - * <p>Callback Java API representation of vpe.api. + * <p>Callback Java API representation of $plugin_package plugin. * <br>It was generated by jvpp_callback_facade_gen.py based on $inputfile - * <br>(python representation of vpe.api generated by vppapigen). + * <br>(python representation of api file generated by vppapigen). */ -public interface CallbackJVpp extends $base_package.$notification_package.NotificationRegistryProvider, java.lang.AutoCloseable { - - @Override - void close(); +public interface CallbackJVpp${plugin_name} extends $base_package.$notification_package.NotificationRegistryProvider, java.lang.AutoCloseable { // TODO add send @@ -39,20 +36,20 @@ $methods """) jvpp_impl_template = Template(""" -package $base_package.$callback_facade_package; +package $plugin_package.$callback_facade_package; /** - * <p>Default implementation of CallbackJVpp interface. + * <p>Default implementation of Callback${plugin_name}JVpp interface. * <br>It was generated by jvpp_callback_facade_gen.py based on $inputfile - * <br>(python representation of vpe.api generated by vppapigen). + * <br>(python representation of api file generated by vppapigen). */ -public final class CallbackJVppFacade extends $base_package.$notification_package.NotificationRegistryProviderContext implements $base_package.$callback_facade_package.CallbackJVpp { +public final class CallbackJVpp${plugin_name}Facade implements CallbackJVpp${plugin_name} { - private final $base_package.JVpp jvpp; + private final $plugin_package.JVpp${plugin_name} jvpp; private final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> callbacks; - + private final $plugin_package.$notification_package.${plugin_name}NotificationRegistryImpl notificationRegistry = new $plugin_package.$notification_package.${plugin_name}NotificationRegistryImpl(); /** - * <p>Create CallbackJVppFacade object for provided JVpp instance. + * <p>Create CallbackJVpp${plugin_name}Facade object for provided JVpp instance. * Constructor internally creates CallbackJVppFacadeCallback class for processing callbacks * and then connects to provided JVpp instance * @@ -60,14 +57,21 @@ public final class CallbackJVppFacade extends $base_package.$notification_packag * * @throws java.io.IOException in case instance cannot connect to JVPP */ - public CallbackJVppFacade(final $base_package.JVpp jvpp) throws java.io.IOException { + public CallbackJVpp${plugin_name}Facade(final $base_package.JVppRegistry registry, final $plugin_package.JVpp${plugin_name} jvpp) throws java.io.IOException { this.jvpp = java.util.Objects.requireNonNull(jvpp,"jvpp is null"); this.callbacks = new java.util.HashMap<>(); - this.jvpp.connect(new CallbackJVppFacadeCallback(this.callbacks, getNotificationCallback())); + java.util.Objects.requireNonNull(registry, "JVppRegistry should not be null"); + registry.register(jvpp, new CallbackJVpp${plugin_name}FacadeCallback(this.callbacks, notificationRegistry)); + } + + @Override + public $plugin_package.$notification_package.${plugin_name}NotificationRegistry getNotificationRegistry() { + return notificationRegistry; } @Override - public void close() { + public void close() throws Exception { + jvpp.close(); } // TODO add send() @@ -77,17 +81,17 @@ $methods """) method_template = Template( - """ void $name($base_package.$dto_package.$request request, $base_package.$callback_package.$callback callback) throws org.openvpp.jvpp.VppInvocationException;""") + """ void $name($plugin_package.$dto_package.$request request, $plugin_package.$callback_package.$callback callback) throws $base_package.VppInvocationException;""") -method_impl_template = Template(""" public final void $name($base_package.$dto_package.$request request, $base_package.$callback_package.$callback callback) throws org.openvpp.jvpp.VppInvocationException { +method_impl_template = Template(""" public final void $name($plugin_package.$dto_package.$request request, $plugin_package.$callback_package.$callback callback) throws $base_package.VppInvocationException { synchronized (callbacks) { callbacks.put(jvpp.$name(request), callback); } } """) -no_arg_method_template = Template(""" void $name($base_package.$callback_package.$callback callback) throws org.openvpp.jvpp.VppInvocationException;""") -no_arg_method_impl_template = Template(""" public final void $name($base_package.$callback_package.$callback callback) throws org.openvpp.jvpp.VppInvocationException { +no_arg_method_template = Template(""" void $name($plugin_package.$callback_package.$callback callback) throws $base_package.VppInvocationException;""") +no_arg_method_impl_template = Template(""" public final void $name($plugin_package.$callback_package.$callback callback) throws $base_package.VppInvocationException { synchronized (callbacks) { callbacks.put(jvpp.$name(), callback); } @@ -95,7 +99,7 @@ no_arg_method_impl_template = Template(""" public final void $name($base_pack """) -def generate_jvpp(func_list, base_package, dto_package, callback_package, notification_package, callback_facade_package, inputfile): +def generate_jvpp(func_list, base_package, plugin_package, plugin_name, dto_package, callback_package, notification_package, callback_facade_package, inputfile): """ Generates callback facade """ print "Generating JVpp callback facade" @@ -109,12 +113,11 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, notifi for func in func_list: if util.is_notification(func['name']) or util.is_ignored(func['name']): - # TODO handle notifications continue camel_case_name = util.underscore_to_camelcase(func['name']) camel_case_name_upper = util.underscore_to_camelcase_upper(func['name']) - if util.is_reply(camel_case_name): + if util.is_reply(camel_case_name) or util.is_control_ping(camel_case_name): continue # Strip suffix for dump calls @@ -123,11 +126,13 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, notifi if len(func['args']) == 0: methods.append(no_arg_method_template.substitute(name=camel_case_name, base_package=base_package, + plugin_package=plugin_package, dto_package=dto_package, callback_package=callback_package, callback=callback_type)) methods_impl.append(no_arg_method_impl_template.substitute(name=camel_case_name, base_package=base_package, + plugin_package=plugin_package, dto_package=dto_package, callback_package=callback_package, callback=callback_type)) @@ -135,32 +140,38 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, notifi methods.append(method_template.substitute(name=camel_case_name, request=camel_case_name_upper, base_package=base_package, + plugin_package=plugin_package, dto_package=dto_package, callback_package=callback_package, callback=callback_type)) methods_impl.append(method_impl_template.substitute(name=camel_case_name, request=camel_case_name_upper, base_package=base_package, + plugin_package=plugin_package, dto_package=dto_package, callback_package=callback_package, callback=callback_type)) - join = os.path.join(callback_facade_package, "CallbackJVpp.java") + join = os.path.join(callback_facade_package, "CallbackJVpp%s.java" % plugin_name) jvpp_file = open(join, 'w') jvpp_file.write( jvpp_ifc_template.substitute(inputfile=inputfile, methods="\n".join(methods), base_package=base_package, + plugin_package=plugin_package, + plugin_name=plugin_name, dto_package=dto_package, notification_package=notification_package, callback_facade_package=callback_facade_package)) jvpp_file.flush() jvpp_file.close() - jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVppFacade.java"), 'w') + jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVpp%sFacade.java" % plugin_name), 'w') jvpp_file.write(jvpp_impl_template.substitute(inputfile=inputfile, methods="\n".join(methods_impl), base_package=base_package, + plugin_package=plugin_package, + plugin_name=plugin_name, dto_package=dto_package, notification_package=notification_package, callback_package=callback_package, @@ -168,31 +179,31 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, notifi jvpp_file.flush() jvpp_file.close() - generate_callback(func_list, base_package, dto_package, callback_package, notification_package, callback_facade_package, inputfile) + generate_callback(func_list, base_package, plugin_package, plugin_name, dto_package, callback_package, notification_package, callback_facade_package, inputfile) jvpp_facade_callback_template = Template(""" -package $base_package.$callback_facade_package; +package $plugin_package.$callback_facade_package; /** * <p>Implementation of JVppGlobalCallback interface for Java Callback API. * <br>It was generated by jvpp_callback_facade_gen.py based on $inputfile - * <br>(python representation of vpe.api generated by vppapigen). + * <br>(python representation of api file generated by vppapigen). */ -public final class CallbackJVppFacadeCallback implements $base_package.$callback_package.JVppGlobalCallback { +public final class CallbackJVpp${plugin_name}FacadeCallback implements $plugin_package.$callback_package.JVpp${plugin_name}GlobalCallback { private final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> requests; - private final $base_package.$notification_package.GlobalNotificationCallback notificationCallback; - private static final java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(CallbackJVppFacadeCallback.class.getName()); + private final $plugin_package.$notification_package.Global${plugin_name}NotificationCallback notificationCallback; + private static final java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(CallbackJVpp${plugin_name}FacadeCallback.class.getName()); - public CallbackJVppFacadeCallback(final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> requestMap, - final $base_package.$notification_package.GlobalNotificationCallback notificationCallback) { + public CallbackJVpp${plugin_name}FacadeCallback(final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> requestMap, + final $plugin_package.$notification_package.Global${plugin_name}NotificationCallback notificationCallback) { this.requests = requestMap; this.notificationCallback = notificationCallback; } @Override - public void onError(org.openvpp.jvpp.VppCallbackException reply) { + public void onError($base_package.VppCallbackException reply) { $base_package.$callback_package.JVppCallback failedCall; synchronized(requests) { @@ -209,6 +220,20 @@ public final class CallbackJVppFacadeCallback implements $base_package.$callback } } + @Override + @SuppressWarnings("unchecked") + public void onControlPingReply($base_package.$dto_package.ControlPingReply reply) { + + $base_package.$callback_package.ControlPingCallback callback; + synchronized(requests) { + callback = ($base_package.$callback_package.ControlPingCallback) requests.remove(reply.context); + } + + if(callback != null) { + callback.onControlPingReply(reply); + } + } + $methods } """) @@ -216,11 +241,11 @@ $methods jvpp_facade_callback_method_template = Template(""" @Override @SuppressWarnings("unchecked") - public void on$callback_dto($base_package.$dto_package.$callback_dto reply) { + public void on$callback_dto($plugin_package.$dto_package.$callback_dto reply) { - $base_package.$callback_package.$callback callback; + $plugin_package.$callback_package.$callback callback; synchronized(requests) { - callback = ($base_package.$callback_package.$callback) requests.remove(reply.context); + callback = ($plugin_package.$callback_package.$callback) requests.remove(reply.context); } if(callback != null) { @@ -232,23 +257,23 @@ jvpp_facade_callback_method_template = Template(""" jvpp_facade_callback_notification_method_template = Template(""" @Override @SuppressWarnings("unchecked") - public void on$callback_dto($base_package.$dto_package.$callback_dto notification) { + public void on$callback_dto($plugin_package.$dto_package.$callback_dto notification) { notificationCallback.on$callback_dto(notification); } """) -def generate_callback(func_list, base_package, dto_package, callback_package, notification_package, callback_facade_package, inputfile): +def generate_callback(func_list, base_package, plugin_package, plugin_name, dto_package, callback_package, notification_package, callback_facade_package, inputfile): callbacks = [] for func in func_list: - if util.is_ignored(func['name']): - continue - camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name']) + if util.is_ignored(func['name']) or util.is_control_ping(camel_case_name_with_suffix): + continue + if util.is_reply(camel_case_name_with_suffix): - callbacks.append(jvpp_facade_callback_method_template.substitute(base_package=base_package, + callbacks.append(jvpp_facade_callback_method_template.substitute(plugin_package=plugin_package, dto_package=dto_package, callback_package=callback_package, callback=util.remove_reply_suffix(camel_case_name_with_suffix) + callback_gen.callback_suffix, @@ -256,15 +281,17 @@ def generate_callback(func_list, base_package, dto_package, callback_package, no if util.is_notification(func["name"]): with_notification_suffix = util.add_notification_suffix(camel_case_name_with_suffix) - callbacks.append(jvpp_facade_callback_notification_method_template.substitute(base_package=base_package, + callbacks.append(jvpp_facade_callback_notification_method_template.substitute(plugin_package=plugin_package, dto_package=dto_package, callback_package=callback_package, callback=with_notification_suffix + callback_gen.callback_suffix, callback_dto=with_notification_suffix)) - jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVppFacadeCallback.java"), 'w') + jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVpp%sFacadeCallback.java" % plugin_name), 'w') jvpp_file.write(jvpp_facade_callback_template.substitute(inputfile=inputfile, base_package=base_package, + plugin_package=plugin_package, + plugin_name=plugin_name, dto_package=dto_package, notification_package=notification_package, callback_package=callback_package, diff --git a/vpp-api/java/jvpp/gen/jvppgen/jvpp_future_facade_gen.py b/vpp-api/java/jvpp/gen/jvppgen/jvpp_future_facade_gen.py index e1ca4d022e0..06c1073b756 100644 --- a/vpp-api/java/jvpp/gen/jvppgen/jvpp_future_facade_gen.py +++ b/vpp-api/java/jvpp/gen/jvppgen/jvpp_future_facade_gen.py @@ -20,27 +20,28 @@ import dto_gen import util jvpp_facade_callback_template = Template(""" -package $base_package.$future_package; +package $plugin_package.$future_package; /** * <p>Async facade callback setting values to future objects * <br>It was generated by jvpp_future_facade_gen.py based on $inputfile - * <br>(python representation of vpe.api generated by vppapigen). + * <br>(python representation of api file generated by vppapigen). */ -public final class FutureJVppFacadeCallback implements $base_package.$callback_package.JVppGlobalCallback { +public final class FutureJVpp${plugin_name}FacadeCallback implements $plugin_package.$callback_package.JVpp${plugin_name}GlobalCallback { private final java.util.Map<java.lang.Integer, java.util.concurrent.CompletableFuture<? extends $base_package.$dto_package.JVppReply<?>>> requests; - private final $base_package.$notification_package.GlobalNotificationCallback notificationCallback; + private final $plugin_package.$notification_package.Global${plugin_name}NotificationCallback notificationCallback; - public FutureJVppFacadeCallback(final java.util.Map<java.lang.Integer, java.util.concurrent.CompletableFuture<? extends $base_package.$dto_package.JVppReply<?>>> requestMap, - final $base_package.$notification_package.GlobalNotificationCallback notificationCallback) { + public FutureJVpp${plugin_name}FacadeCallback( + final java.util.Map<java.lang.Integer, java.util.concurrent.CompletableFuture<? extends $base_package.$dto_package.JVppReply<?>>> requestMap, + final $plugin_package.$notification_package.Global${plugin_name}NotificationCallback notificationCallback) { this.requests = requestMap; this.notificationCallback = notificationCallback; } @Override @SuppressWarnings("unchecked") - public void onError(org.openvpp.jvpp.VppCallbackException reply) { + public void onError($base_package.VppCallbackException reply) { final java.util.concurrent.CompletableFuture<$base_package.$dto_package.JVppReply<?>> completableFuture; synchronized(requests) { @@ -56,14 +57,9 @@ public final class FutureJVppFacadeCallback implements $base_package.$callback_p } } -$methods -} -""") - -jvpp_facade_callback_method_template = Template(""" @Override @SuppressWarnings("unchecked") - public void on$callback_dto($base_package.$dto_package.$callback_dto reply) { + public void onControlPingReply($base_package.$dto_package.ControlPingReply reply) { final java.util.concurrent.CompletableFuture<$base_package.$dto_package.JVppReply<?>> completableFuture; synchronized(requests) { @@ -71,27 +67,31 @@ jvpp_facade_callback_method_template = Template(""" } if(completableFuture != null) { - completableFuture.complete(reply); + // Finish dump call + if (completableFuture instanceof $base_package.$future_package.AbstractFutureJVppInvoker.CompletableDumpFuture) { + completableFuture.complete((($base_package.$future_package.AbstractFutureJVppInvoker.CompletableDumpFuture) completableFuture).getReplyDump()); + // Remove future mapped to dump call context id + synchronized(requests) { + requests.remove((($base_package.$future_package.AbstractFutureJVppInvoker.CompletableDumpFuture) completableFuture).getContextId()); + } + } else { + completableFuture.complete(reply); + } synchronized(requests) { requests.remove(reply.context); } } } -""") -jvpp_facade_callback_notification_method_template = Template(""" - @Override - public void on$callback_dto($base_package.$dto_package.$callback_dto notification) { - notificationCallback.on$callback_dto(notification); - } +$methods +} """) -# TODO reuse common parts with generic method callback -jvpp_facade_control_ping_method_template = Template(""" +jvpp_facade_callback_method_template = Template(""" @Override @SuppressWarnings("unchecked") - public void on$callback_dto($base_package.$dto_package.$callback_dto reply) { + public void on$callback_dto($plugin_package.$dto_package.$callback_dto reply) { final java.util.concurrent.CompletableFuture<$base_package.$dto_package.JVppReply<?>> completableFuture; synchronized(requests) { @@ -99,16 +99,7 @@ jvpp_facade_control_ping_method_template = Template(""" } if(completableFuture != null) { - // Finish dump call - if (completableFuture instanceof $base_package.$future_package.FutureJVppFacade.CompletableDumpFuture) { - completableFuture.complete((($base_package.$future_package.FutureJVppFacade.CompletableDumpFuture) completableFuture).getReplyDump()); - // Remove future mapped to dump call context id - synchronized(requests) { - requests.remove((($base_package.$future_package.FutureJVppFacade.CompletableDumpFuture) completableFuture).getContextId()); - } - } else { - completableFuture.complete(reply); - } + completableFuture.complete(reply); synchronized(requests) { requests.remove(reply.context); @@ -117,20 +108,27 @@ jvpp_facade_control_ping_method_template = Template(""" } """) +jvpp_facade_callback_notification_method_template = Template(""" + @Override + public void on$callback_dto($plugin_package.$dto_package.$callback_dto notification) { + notificationCallback.on$callback_dto(notification); + } +""") + jvpp_facade_details_callback_method_template = Template(""" @Override @SuppressWarnings("unchecked") - public void on$callback_dto($base_package.$dto_package.$callback_dto reply) { - final FutureJVppFacade.CompletableDumpFuture<$base_package.$dto_package.$callback_dto_reply_dump> completableFuture; + public void on$callback_dto($plugin_package.$dto_package.$callback_dto reply) { + final $base_package.$future_package.AbstractFutureJVppInvoker.CompletableDumpFuture<$plugin_package.$dto_package.$callback_dto_reply_dump> completableFuture; synchronized(requests) { - completableFuture = ($base_package.$future_package.FutureJVppFacade.CompletableDumpFuture<$base_package.$dto_package.$callback_dto_reply_dump>) requests.get(reply.context); + completableFuture = ($base_package.$future_package.AbstractFutureJVppInvoker.CompletableDumpFuture<$plugin_package.$dto_package.$callback_dto_reply_dump>) requests.get(reply.context); } if(completableFuture != null) { - $base_package.$dto_package.$callback_dto_reply_dump replyDump = completableFuture.getReplyDump(); + $plugin_package.$dto_package.$callback_dto_reply_dump replyDump = completableFuture.getReplyDump(); if(replyDump == null) { - replyDump = new $base_package.$dto_package.$callback_dto_reply_dump(); + replyDump = new $plugin_package.$dto_package.$callback_dto_reply_dump(); completableFuture.setReplyDump(replyDump); } @@ -140,7 +138,7 @@ jvpp_facade_details_callback_method_template = Template(""" """) -def generate_jvpp(func_list, base_package, dto_package, callback_package, notification_package, future_facade_package, inputfile): +def generate_jvpp(func_list, base_package, plugin_package, plugin_name, dto_package, callback_package, notification_package, future_facade_package, inputfile): """ Generates JVpp interface and JNI implementation """ print "Generating JVpp future facade" @@ -151,11 +149,11 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, notifi methods_impl = [] callbacks = [] for func in func_list: + camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name']) - if util.is_ignored(func['name']): + if util.is_ignored(func['name']) or util.is_control_ping(camel_case_name_with_suffix): continue - camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name']) if not util.is_reply(camel_case_name_with_suffix) and not util.is_notification(func['name']): continue @@ -167,20 +165,21 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, notifi camel_case_reply_name = get_standard_dump_reply_name(util.underscore_to_camelcase_upper(func['name']), func['name']) callbacks.append(jvpp_facade_details_callback_method_template.substitute(base_package=base_package, + plugin_package=plugin_package, dto_package=dto_package, callback_dto=camel_case_name_with_suffix, callback_dto_field=camel_case_method_name, callback_dto_reply_dump=camel_case_reply_name + dto_gen.dump_dto_suffix, future_package=future_facade_package)) - methods.append(future_jvpp_method_template.substitute(base_package=base_package, + methods.append(future_jvpp_method_template.substitute(plugin_package=plugin_package, dto_package=dto_package, method_name=camel_case_request_method_name + util.underscore_to_camelcase_upper(util.dump_suffix), reply_name=camel_case_reply_name + dto_gen.dump_dto_suffix, request_name=util.remove_reply_suffix(camel_case_reply_name) + util.underscore_to_camelcase_upper(util.dump_suffix))) - methods_impl.append(future_jvpp_method_impl_template.substitute(base_package=base_package, + methods_impl.append(future_jvpp_method_impl_template.substitute(plugin_package=plugin_package, dto_package=dto_package, method_name=camel_case_request_method_name + util.underscore_to_camelcase_upper(util.dump_suffix), @@ -191,36 +190,32 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, notifi request_name = util.underscore_to_camelcase_upper(util.unconventional_naming_rep_req[func['name']]) \ if func['name'] in util.unconventional_naming_rep_req else util.remove_reply_suffix(camel_case_name_with_suffix) - methods.append(future_jvpp_method_template.substitute(base_package=base_package, + methods.append(future_jvpp_method_template.substitute(plugin_package=plugin_package, dto_package=dto_package, method_name=camel_case_request_method_name, reply_name=camel_case_name_with_suffix, request_name=request_name)) - methods_impl.append(future_jvpp_method_impl_template.substitute(base_package=base_package, + methods_impl.append(future_jvpp_method_impl_template.substitute(plugin_package=plugin_package, dto_package=dto_package, method_name=camel_case_request_method_name, reply_name=camel_case_name_with_suffix, request_name=request_name)) - # Callback handler is a bit special and a different template has to be used - if util.is_control_ping(camel_case_name_with_suffix): - callbacks.append(jvpp_facade_control_ping_method_template.substitute(base_package=base_package, - dto_package=dto_package, - callback_dto=camel_case_name_with_suffix, - future_package=future_facade_package)) - else: - callbacks.append(jvpp_facade_callback_method_template.substitute(base_package=base_package, - dto_package=dto_package, - callback_dto=camel_case_name_with_suffix)) + callbacks.append(jvpp_facade_callback_method_template.substitute(base_package=base_package, + plugin_package=plugin_package, + dto_package=dto_package, + callback_dto=camel_case_name_with_suffix)) if util.is_notification(func["name"]): - callbacks.append(jvpp_facade_callback_notification_method_template.substitute(base_package=base_package, + callbacks.append(jvpp_facade_callback_notification_method_template.substitute(plugin_package=plugin_package, dto_package=dto_package, callback_dto=util.add_notification_suffix(camel_case_name_with_suffix))) - jvpp_file = open(os.path.join(future_facade_package, "FutureJVppFacadeCallback.java"), 'w') + jvpp_file = open(os.path.join(future_facade_package, "FutureJVpp%sFacadeCallback.java" % plugin_name), 'w') jvpp_file.write(jvpp_facade_callback_template.substitute(inputfile=inputfile, base_package=base_package, + plugin_package=plugin_package, + plugin_name=plugin_name, dto_package=dto_package, notification_package=notification_package, callback_package=callback_package, @@ -229,18 +224,24 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, notifi jvpp_file.flush() jvpp_file.close() - jvpp_file = open(os.path.join(future_facade_package, "FutureJVpp.java"), 'w') + jvpp_file = open(os.path.join(future_facade_package, "FutureJVpp%s.java" % plugin_name), 'w') jvpp_file.write(future_jvpp_template.substitute(inputfile=inputfile, base_package=base_package, + plugin_package=plugin_package, + plugin_name=plugin_name, + notification_package=notification_package, methods="".join(methods), future_package=future_facade_package)) jvpp_file.flush() jvpp_file.close() - jvpp_file = open(os.path.join(future_facade_package, "FutureJVppFacade.java"), 'w') + jvpp_file = open(os.path.join(future_facade_package, "FutureJVpp%sFacade.java" % plugin_name), 'w') jvpp_file.write(future_jvpp_facade_template.substitute(inputfile=inputfile, base_package=base_package, + plugin_package=plugin_package, + plugin_name=plugin_name, dto_package=dto_package, + notification_package=notification_package, methods="".join(methods_impl), future_package=future_facade_package)) jvpp_file.flush() @@ -248,35 +249,41 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, notifi future_jvpp_template = Template(''' -package $base_package.$future_package; +package $plugin_package.$future_package; /** * <p>Async facade extension adding specific methods for each request invocation * <br>It was generated by jvpp_future_facade_gen.py based on $inputfile - * <br>(python representation of vpe.api generated by vppapigen). + * <br>(python representation of api file generated by vppapigen). */ -public interface FutureJVpp extends FutureJVppInvoker { +public interface FutureJVpp${plugin_name} extends $base_package.$future_package.FutureJVppInvoker { $methods + + @Override + public $plugin_package.$notification_package.${plugin_name}NotificationRegistry getNotificationRegistry(); + } ''') future_jvpp_method_template = Template(''' - java.util.concurrent.CompletionStage<$base_package.$dto_package.$reply_name> $method_name($base_package.$dto_package.$request_name request); + java.util.concurrent.CompletionStage<$plugin_package.$dto_package.$reply_name> $method_name($plugin_package.$dto_package.$request_name request); ''') future_jvpp_facade_template = Template(''' -package $base_package.$future_package; +package $plugin_package.$future_package; /** - * <p>Implementation of FutureJVpp based on FutureJVppInvokerFacade + * <p>Implementation of FutureJVpp based on AbstractFutureJVppInvoker * <br>It was generated by jvpp_future_facade_gen.py based on $inputfile - * <br>(python representation of vpe.api generated by vppapigen). + * <br>(python representation of api file generated by vppapigen). */ -public class FutureJVppFacade extends FutureJVppInvokerFacade implements FutureJVpp { +public class FutureJVpp${plugin_name}Facade extends $base_package.$future_package.AbstractFutureJVppInvoker implements FutureJVpp${plugin_name} { + + private final $plugin_package.$notification_package.${plugin_name}NotificationRegistryImpl notificationRegistry = new $plugin_package.$notification_package.${plugin_name}NotificationRegistryImpl(); /** - * <p>Create FutureJVppFacade object for provided JVpp instance. + * <p>Create FutureJVpp${plugin_name}Facade object for provided JVpp instance. * Constructor internally creates FutureJVppFacadeCallback class for processing callbacks * and then connects to provided JVpp instance * @@ -284,17 +291,24 @@ public class FutureJVppFacade extends FutureJVppInvokerFacade implements FutureJ * * @throws java.io.IOException in case instance cannot connect to JVPP */ - public FutureJVppFacade(final $base_package.JVpp jvpp) throws java.io.IOException { - super(jvpp, new java.util.HashMap<>()); - jvpp.connect(new FutureJVppFacadeCallback(getRequests(), getNotificationCallback())); + public FutureJVpp${plugin_name}Facade(final $base_package.JVppRegistry registry, final $base_package.JVpp jvpp) throws java.io.IOException { + super(jvpp, registry, new java.util.HashMap<>()); + java.util.Objects.requireNonNull(registry, "JVppRegistry should not be null"); + registry.register(jvpp, new FutureJVpp${plugin_name}FacadeCallback(getRequests(), notificationRegistry)); + } + + @Override + public $plugin_package.$notification_package.${plugin_name}NotificationRegistry getNotificationRegistry() { + return notificationRegistry; } + $methods } ''') future_jvpp_method_impl_template = Template(''' @Override - public java.util.concurrent.CompletionStage<$base_package.$dto_package.$reply_name> $method_name($base_package.$dto_package.$request_name request) { + public java.util.concurrent.CompletionStage<$plugin_package.$dto_package.$reply_name> $method_name($plugin_package.$dto_package.$request_name request) { return send(request); } ''') diff --git a/vpp-api/java/jvpp/gen/jvppgen/jvpp_impl_gen.py b/vpp-api/java/jvpp/gen/jvppgen/jvpp_impl_gen.py index 93ffd0fb359..41df4f2ae18 100644 --- a/vpp-api/java/jvpp/gen/jvppgen/jvpp_impl_gen.py +++ b/vpp-api/java/jvpp/gen/jvppgen/jvpp_impl_gen.py @@ -17,25 +17,14 @@ import os, util from string import Template jvpp_ifc_template = Template(""" -package $base_package; - +package $plugin_package; /** - * <p>Java representation of vpe.api. + * <p>Java representation of plugin's api file. * <br>It was generated by jvpp_impl_gen.py based on $inputfile - * <br>(python representation of vpe.api generated by vppapigen). + * <br>(python representation of api file generated by vppapigen). */ -public interface JVpp extends java.lang.AutoCloseable { - - /** - * Generic connect with $base_package.callback.JVppCallback callback handler - * providing connecting to VPP - * - * @param callback JVppCallback instance providing callback handling - * - * @throws java.io.IOException if connection cannot be initiated - */ - void connect($base_package.callback.JVppCallback callback) throws java.io.IOException; +public interface JVpp${plugin_name} extends $base_package.JVpp { /** * Generic dispatch method for sending requests to VPP @@ -44,52 +33,110 @@ public interface JVpp extends java.lang.AutoCloseable { */ int send($base_package.$dto_package.JVppRequest request) throws org.openvpp.jvpp.VppInvocationException; - @Override - void close(); - $methods } """) jvpp_impl_template = Template(""" -package $base_package; +package $plugin_package; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.PosixFilePermissions; +import java.util.Set; +import java.util.logging.Logger; +import $base_package.callback.JVppCallback; +import $base_package.VppConnection; +import $base_package.JVppRegistry; /** * <p>Default implementation of JVpp interface. * <br>It was generated by jvpp_impl_gen.py based on $inputfile - * <br>(python representation of vpe.api generated by vppapigen). + * <br>(python representation of api file generated by vppapigen). */ -public final class JVppImpl implements $base_package.JVpp { +public final class JVpp${plugin_name}Impl implements $plugin_package.JVpp${plugin_name} { + + private final static Logger LOG = Logger.getLogger(JVpp${plugin_name}Impl.class.getName()); + private static final String LIBNAME = "libjvpp_${plugin_name_underscore}.so.0.0.0"; + + // FIXME using NativeLibraryLoader makes load fail could not find (WantInterfaceEventsReply). + static { + try { + loadLibrary(); + } catch (Exception e) { + LOG.severe("Can't find jvpp jni library: " + LIBNAME); + throw new ExceptionInInitializerError(e); + } + } - private final $base_package.VppConnection connection; + private static void loadStream(final InputStream is) throws IOException { + final Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---"); + final Path p = Files.createTempFile(LIBNAME, null, PosixFilePermissions.asFileAttribute(perms)); + try { + Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING); + + try { + Runtime.getRuntime().load(p.toString()); + } catch (UnsatisfiedLinkError e) { + throw new IOException("Failed to load library " + p, e); + } + } finally { + try { + Files.deleteIfExists(p); + } catch (IOException e) { + } + } + } - public JVppImpl(final $base_package.VppConnection connection) { - this.connection = java.util.Objects.requireNonNull(connection,"Connection is null"); + private static void loadLibrary() throws IOException { + try (final InputStream is = JVpp${plugin_name}Impl.class.getResourceAsStream('/' + LIBNAME)) { + if (is == null) { + throw new IOException("Failed to open library resource " + LIBNAME); + } + loadStream(is); + } } + private VppConnection connection; + private JVppRegistry registry; + + private static native void init0(final JVppCallback callback, final long queueAddress, final int clientIndex); @Override - public void connect($base_package.callback.JVppCallback callback) throws java.io.IOException { - connection.connect(callback); + public void init(final JVppRegistry registry, final JVppCallback callback, final long queueAddress, final int clientIndex) { + this.registry = java.util.Objects.requireNonNull(registry, "registry should not be null"); + this.connection = java.util.Objects.requireNonNull(registry.getConnection(), "connection should not be null"); + connection.checkActive(); + init0(callback, queueAddress, clientIndex); } + private static native void close0(); @Override public void close() { - connection.close(); + close0(); } @Override - public int send($base_package.$dto_package.JVppRequest request) throws org.openvpp.jvpp.VppInvocationException { + public int send($base_package.$dto_package.JVppRequest request) throws org.openvpp.jvpp.VppInvocationException { return request.send(this); } + @Override + public final int controlPing(final org.openvpp.jvpp.dto.ControlPing controlPing) throws org.openvpp.jvpp.VppInvocationException { + return registry.controlPing(JVpp${plugin_name}Impl.class); + } + $methods } """) -method_template = Template(""" int $name($base_package.$dto_package.$request request) throws org.openvpp.jvpp.VppInvocationException;""") +method_template = Template(""" int $name($plugin_package.$dto_package.$request request) throws org.openvpp.jvpp.VppInvocationException;""") method_native_template = Template( - """ private static native int ${name}0($base_package.$dto_package.$request request);""") -method_impl_template = Template(""" public final int $name($base_package.$dto_package.$request request) throws org.openvpp.jvpp.VppInvocationException { + """ private static native int ${name}0($plugin_package.$dto_package.$request request);""") +method_impl_template = Template(""" public final int $name($plugin_package.$dto_package.$request request) throws org.openvpp.jvpp.VppInvocationException { java.util.Objects.requireNonNull(request,"Null request object"); connection.checkActive(); int result=${name}0(request); @@ -113,9 +160,10 @@ no_arg_method_impl_template = Template(""" public final int $name() throws or """) -def generate_jvpp(func_list, base_package, dto_package, inputfile): +def generate_jvpp(func_list, base_package, plugin_package, plugin_name_underscore, control_ping_class, dto_package, inputfile): """ Generates JVpp interface and JNI implementation """ print "Generating JVpp" + plugin_name = util.underscore_to_camelcase_upper(plugin_name_underscore) methods = [] methods_impl = [] @@ -131,43 +179,42 @@ def generate_jvpp(func_list, base_package, dto_package, inputfile): continue if len(func['args']) == 0: - methods.append(no_arg_method_template.substitute(name=camel_case_name, - base_package=base_package, - dto_package=dto_package)) - methods_impl.append( - no_arg_method_native_template.substitute(name=camel_case_name, - base_package=base_package, - dto_package=dto_package)) - methods_impl.append(no_arg_method_impl_template.substitute(name=camel_case_name, - base_package=base_package, - dto_package=dto_package)) + methods.append(no_arg_method_template.substitute(name=camel_case_name)) + methods_impl.append(no_arg_method_native_template.substitute(name=camel_case_name)) + methods_impl.append(no_arg_method_impl_template.substitute(name=camel_case_name)) else: methods.append(method_template.substitute(name=camel_case_name, request=camel_case_name_upper, - base_package=base_package, + plugin_package=plugin_package, dto_package=dto_package)) methods_impl.append(method_native_template.substitute(name=camel_case_name, request=camel_case_name_upper, - base_package=base_package, + plugin_package=plugin_package, dto_package=dto_package)) methods_impl.append(method_impl_template.substitute(name=camel_case_name, request=camel_case_name_upper, - base_package=base_package, + plugin_package=plugin_package, dto_package=dto_package)) - jvpp_file = open("JVpp.java", 'w') + jvpp_file = open("JVpp%s.java" % plugin_name, 'w') jvpp_file.write( jvpp_ifc_template.substitute(inputfile=inputfile, methods="\n".join(methods), base_package=base_package, + plugin_package=plugin_package, + plugin_name=plugin_name, dto_package=dto_package)) jvpp_file.flush() jvpp_file.close() - jvpp_file = open("JVppImpl.java", 'w') + jvpp_file = open("JVpp%sImpl.java" % plugin_name, 'w') jvpp_file.write(jvpp_impl_template.substitute(inputfile=inputfile, methods="\n".join(methods_impl), base_package=base_package, - dto_package=dto_package)) + plugin_package=plugin_package, + plugin_name=plugin_name, + plugin_name_underscore=plugin_name_underscore, + dto_package=dto_package, + control_ping_class=control_ping_class)) jvpp_file.flush() jvpp_file.close() diff --git a/vpp-api/java/jvpp/gen/jvppgen/notification_gen.py b/vpp-api/java/jvpp/gen/jvppgen/notification_gen.py index df6407f845d..eb380fc8ea3 100644 --- a/vpp-api/java/jvpp/gen/jvppgen/notification_gen.py +++ b/vpp-api/java/jvpp/gen/jvppgen/notification_gen.py @@ -19,17 +19,15 @@ import callback_gen import util from string import Template -from util import remove_suffix - notification_registry_template = Template(""" -package $base_package.$notification_package; +package $plugin_package.$notification_package; /** - * <p>Registry for notification callbacks. + * <p>Registry for notification callbacks defined in ${plugin_name}. * <br>It was generated by notification_gen.py based on $inputfile - * <br>(python representation of vpe.api generated by vppapigen). + * <br>(python representation of api file generated by vppapigen). */ -public interface NotificationRegistry extends java.lang.AutoCloseable { +public interface ${plugin_name}NotificationRegistry extends $base_package.$notification_package.NotificationRegistry { $register_callback_methods @@ -39,27 +37,27 @@ public interface NotificationRegistry extends java.lang.AutoCloseable { """) global_notification_callback_template = Template(""" -package $base_package.$notification_package; +package $plugin_package.$notification_package; /** * <p>Aggregated callback interface for notifications only. * <br>It was generated by notification_gen.py based on $inputfile - * <br>(python representation of vpe.api generated by vppapigen). + * <br>(python representation of api file generated by vppapigen). */ -public interface GlobalNotificationCallback extends $callbacks { +public interface Global${plugin_name}NotificationCallback$callbacks { } """) notification_registry_impl_template = Template(""" -package $base_package.$notification_package; +package $plugin_package.$notification_package; /** * <p>Notification registry delegating notification processing to registered callbacks. * <br>It was generated by notification_gen.py based on $inputfile - * <br>(python representation of vpe.api generated by vppapigen). + * <br>(python representation of api file generated by vppapigen). */ -public final class NotificationRegistryImpl implements NotificationRegistry, GlobalNotificationCallback { +public final class ${plugin_name}NotificationRegistryImpl implements ${plugin_name}NotificationRegistry, Global${plugin_name}NotificationCallback { // TODO add a special NotificationCallback interface and only allow those to be registered private final java.util.concurrent.ConcurrentMap<Class<? extends $base_package.$dto_package.JVppNotification>, $base_package.$callback_package.JVppNotificationCallback> registeredCallbacks = @@ -76,30 +74,45 @@ public final class NotificationRegistryImpl implements NotificationRegistry, Glo """) register_callback_impl_template = Template(""" - public java.lang.AutoCloseable register$callback(final $base_package.$callback_package.$callback callback){ - if(null != registeredCallbacks.putIfAbsent($base_package.$dto_package.$notification.class, callback)){ - throw new IllegalArgumentException("Callback for " + $base_package.$dto_package.$notification.class + + public java.lang.AutoCloseable register$callback(final $plugin_package.$callback_package.$callback callback){ + if(null != registeredCallbacks.putIfAbsent($plugin_package.$dto_package.$notification.class, callback)){ + throw new IllegalArgumentException("Callback for " + $plugin_package.$dto_package.$notification.class + "notification already registered"); } - return () -> registeredCallbacks.remove($base_package.$dto_package.$notification.class); + return () -> registeredCallbacks.remove($plugin_package.$dto_package.$notification.class); } """) handler_impl_template = Template(""" @Override public void on$notification( - final $base_package.$dto_package.$notification notification) { - final $base_package.$callback_package.JVppNotificationCallback JVppNotificationCallback = registeredCallbacks.get($base_package.$dto_package.$notification.class); - if (null != JVppNotificationCallback) { - (($base_package.$callback_package.$callback) registeredCallbacks - .get($base_package.$dto_package.$notification.class)) + final $plugin_package.$dto_package.$notification notification) { + final $base_package.$callback_package.JVppNotificationCallback jVppNotificationCallback = registeredCallbacks.get($plugin_package.$dto_package.$notification.class); + if (null != jVppNotificationCallback) { + (($plugin_package.$callback_package.$callback) registeredCallbacks + .get($plugin_package.$dto_package.$notification.class)) .on$notification(notification); } } """) +notification_provider_template = Template(""" +package $plugin_package.$notification_package; + + /** + * Provides ${plugin_name}NotificationRegistry. + * <br>The file was generated by notification_gen.py based on $inputfile + * <br>(python representation of api file generated by vppapigen). + */ +public interface ${plugin_name}NotificationRegistryProvider extends $base_package.$notification_package.NotificationRegistryProvider { -def generate_notification_registry(func_list, base_package, notification_package, callback_package, dto_package, inputfile): + @Override + public ${plugin_name}NotificationRegistry getNotificationRegistry(); +} +""") + + +def generate_notification_registry(func_list, base_package, plugin_package, plugin_name, notification_package, callback_package, dto_package, inputfile): """ Generates notification registry interface and implementation """ print "Generating Notification interfaces and implementation" @@ -118,47 +131,69 @@ def generate_notification_registry(func_list, base_package, notification_package camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name']) notification_dto = util.add_notification_suffix(camel_case_name_with_suffix) callback_ifc = notification_dto + callback_gen.callback_suffix - fully_qualified_callback_ifc = "{0}.{1}.{2}".format(base_package, callback_package, callback_ifc) + fully_qualified_callback_ifc = "{0}.{1}.{2}".format(plugin_package, callback_package, callback_ifc) callbacks.append(fully_qualified_callback_ifc) # TODO create NotificationListenerRegistration and return that instead of AutoCloseable to better indicate # that the registration should be closed register_callback_methods.append("java.lang.AutoCloseable register{0}({1} callback);" .format(callback_ifc, fully_qualified_callback_ifc)) - register_callback_methods_impl.append(register_callback_impl_template.substitute(base_package=base_package, + register_callback_methods_impl.append(register_callback_impl_template.substitute(plugin_package=plugin_package, callback_package=callback_package, dto_package=dto_package, notification=notification_dto, callback=callback_ifc)) handler_methods.append(handler_impl_template.substitute(base_package=base_package, + plugin_package=plugin_package, callback_package=callback_package, dto_package=dto_package, notification=notification_dto, callback=callback_ifc)) - if(callbacks): - callback_file = open(os.path.join(notification_package, "NotificationRegistry.java"), 'w') - callback_file.write(notification_registry_template.substitute(inputfile=inputfile, - register_callback_methods="\n ".join(register_callback_methods), - base_package=base_package, - notification_package=notification_package)) - callback_file.flush() - callback_file.close() - - callback_file = open(os.path.join(notification_package, "GlobalNotificationCallback.java"), 'w') - callback_file.write(global_notification_callback_template.substitute(inputfile=inputfile, - callbacks=", ".join(callbacks), - base_package=base_package, - notification_package=notification_package)) - callback_file.flush() - callback_file.close() - - callback_file = open(os.path.join(notification_package, "NotificationRegistryImpl.java"), 'w') - callback_file.write(notification_registry_impl_template.substitute(inputfile=inputfile, - callback_package=callback_package, - dto_package=dto_package, - register_callback_methods="".join(register_callback_methods_impl), - handler_methods="".join(handler_methods), - base_package=base_package, - notification_package=notification_package)) - callback_file.flush() - callback_file.close() + + + callback_file = open(os.path.join(notification_package, "%sNotificationRegistry.java" % plugin_name), 'w') + callback_file.write(notification_registry_template.substitute(inputfile=inputfile, + register_callback_methods="\n ".join(register_callback_methods), + base_package=base_package, + plugin_package=plugin_package, + plugin_name=plugin_name, + notification_package=notification_package)) + callback_file.flush() + callback_file.close() + + callback_file = open(os.path.join(notification_package, "Global%sNotificationCallback.java" % plugin_name), 'w') + + global_notification_callback_callbacks = "" + if (callbacks): + global_notification_callback_callbacks = " extends " + ", ".join(callbacks) + + callback_file.write(global_notification_callback_template.substitute(inputfile=inputfile, + callbacks=global_notification_callback_callbacks, + plugin_package=plugin_package, + plugin_name=plugin_name, + notification_package=notification_package)) + callback_file.flush() + callback_file.close() + + callback_file = open(os.path.join(notification_package, "%sNotificationRegistryImpl.java" % plugin_name), 'w') + callback_file.write(notification_registry_impl_template.substitute(inputfile=inputfile, + callback_package=callback_package, + dto_package=dto_package, + register_callback_methods="".join(register_callback_methods_impl), + handler_methods="".join(handler_methods), + base_package=base_package, + plugin_package=plugin_package, + plugin_name=plugin_name, + notification_package=notification_package)) + callback_file.flush() + callback_file.close() + + callback_file = open(os.path.join(notification_package, "%sNotificationRegistryProvider.java" % plugin_name), 'w') + callback_file.write(notification_provider_template.substitute(inputfile=inputfile, + base_package=base_package, + plugin_package=plugin_package, + plugin_name=plugin_name, + notification_package=notification_package)) + callback_file.flush() + callback_file.close() + diff --git a/vpp-api/java/jvpp/gen/jvppgen/util.py b/vpp-api/java/jvpp/gen/jvppgen/util.py index f22132dfbc1..0018e014dc4 100644 --- a/vpp-api/java/jvpp/gen/jvppgen/util.py +++ b/vpp-api/java/jvpp/gen/jvppgen/util.py @@ -120,15 +120,18 @@ jni_field_accessors = { 'jfloatArray': 'ObjectField' } -# TODO watch out for unsigned types +# Mapping according to: # http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html -vpp_2_jni_type_mapping = {'u8': 'jbyte', # fixme +# +# Unsigned types are converted to signed java types that have the same size. +# It is the API user responsibility to interpret them correctly. +vpp_2_jni_type_mapping = {'u8': 'jbyte', 'i8': 'jbyte', 'u16': 'jshort', 'i16': 'jshort', - 'u32': 'jint', # fixme + 'u32': 'jint', 'i32': 'jint', - 'u64': 'jlong', # fixme + 'u64': 'jlong', 'i64': 'jlong', 'f64': 'jdouble' } @@ -179,7 +182,7 @@ def remove_suffix(camel_case_name_with_suffix, suffix): def is_control_ping(camel_case_name_with_suffix): - return "controlping" in camel_case_name_with_suffix.lower() + return camel_case_name_with_suffix.lower().startswith("controlping"); def api_message_to_javadoc(api_message): """ Converts vpe.api message description to javadoc """ |