diff --git a/.clang-tidy b/.clang-tidy index 18a83e657..382cc7ff9 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -68,5 +68,5 @@ Checks: > # clang-analyzer-optin.cplusplus.VirtualCall, # Turn all the warnings from the checks above into errors. -HeaderFilterRegex: '(src|test/unit|test/drivers|test/mock)/*' +HeaderFilterRegex: '((?!build/)src|test/unit|test/drivers|test/function|test/mock)/*' FormatStyle: file diff --git a/.github/workflows/merge-request-ascend.yml b/.github/workflows/merge-request-ascend.yml index 1c8fa13b5..a3ff2bf9d 100644 --- a/.github/workflows/merge-request-ascend.yml +++ b/.github/workflows/merge-request-ascend.yml @@ -5,6 +5,10 @@ on: branches: - main +concurrency: + group: ${{ github.head_ref && github.workflow}} + cancel-in-progress: true + env: BUILD_TYPE: Release @@ -17,16 +21,32 @@ jobs: steps: - uses: actions/checkout@v3 - run: apt update + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + maven-version: '3.6.2' + cache: 'maven' + - name: Set up Maven + uses: stCarolas/setup-maven@v4.4 + with: + maven-version: 3.8.2 + - uses: actions/cache@v1 + with: + path: /root/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('src/java/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- - name: ccache uses: hendrikmuhs/ccache-action@v1.2 with: key: ubuntu-latest - max-size: 1024M + max-size: 512M - name: Configure CMake run: | mkdir build cd build - cmake .. -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DWITH_WEBUI=off -DCLANG_TIDY=on -DCLANG_TIDY_AS_ERROR=on + cmake .. -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DWITH_WEBUI=off -DCLANG_TIDY=on -DCLANG_TIDY_AS_ERROR=on -DWITH_JAVA=on - name: Build working-directory: build diff --git a/.github/workflows/merge-request-cuda.yml b/.github/workflows/merge-request-cuda.yml index 69513f050..d94282dac 100644 --- a/.github/workflows/merge-request-cuda.yml +++ b/.github/workflows/merge-request-cuda.yml @@ -5,6 +5,10 @@ on: branches: - main +concurrency: + group: ${{ github.head_ref && github.workflow}} + cancel-in-progress: true + env: BUILD_TYPE: Release @@ -16,17 +20,33 @@ jobs: steps: - uses: actions/checkout@v3 - - run: apt update + - run: apt update + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + maven-version: '3.6.2' + cache: 'maven' + - name: Set up Maven + uses: stCarolas/setup-maven@v4.4 + with: + maven-version: 3.8.2 + - uses: actions/cache@v1 + with: + path: /root/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('src/java/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- - name: ccache uses: hendrikmuhs/ccache-action@v1.2 with: key: ubuntu-latest - max-size: 1024M + max-size: 512M - name: Configure CMake run: | mkdir build cd build - cmake .. -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DWITH_WEBUI=off -DCLANG_TIDY=on -DCLANG_TIDY_AS_ERROR=on + cmake .. -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DWITH_WEBUI=off -DCLANG_TIDY=on -DCLANG_TIDY_AS_ERROR=on -DWITH_JAVA=on - name: Build working-directory: build diff --git a/README.md b/README.md index e81fe36d9..e33415a26 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ModelBox是一个适用于端边云场景的AI推理应用开发框架,提供 ## ModelBox特点 1. **易于开发** - AI推理业务可视化编排开发,功能模块化,丰富组件库;c++,python多语言支持。 + AI推理业务可视化编排开发,功能模块化,丰富组件库;c++,python, Java多语言支持。 1. **易于集成** 集成云上对接的组件,云上对接更容易。 diff --git a/README_en.md b/README_en.md index b22d9f401..dd1713afe 100644 --- a/README_en.md +++ b/README_en.md @@ -7,7 +7,7 @@ ModelBox is an AI application development framework featuring device-edge-cloud ## ModelBox Highlights 1. **Easy to develop** - Simplified orchestration and development of inference applications via a graphical interface, modularized functions, rich component libraries, and multi-language support (C++, Python). + Simplified orchestration and development of inference applications via a graphical interface, modularized functions, rich component libraries, and multi-language support (C++, Python, Java). 1. **Easy to integrate** Easy to integrate different components on the cloud. diff --git a/src/demo/hello_world/flowunit/hello_world/hello_world.py b/src/demo/hello_world/flowunit/hello_world/hello_world.py index 6ebd754b7..e6e6f11ba 100644 --- a/src/demo/hello_world/flowunit/hello_world/hello_world.py +++ b/src/demo/hello_world/flowunit/hello_world/hello_world.py @@ -34,7 +34,7 @@ def process(self, data_context): out_data = data_context.output("out_data") for buffer in in_data: - request_body = json.loads(buffer.as_object().strip(chr(0))) + request_body = json.loads(str(buffer)) msg = request_body.get("msg") msg = msg.title() msg = addTimestamp(msg) diff --git a/src/drivers/virtual/inference/virtualdriver_inference.h b/src/drivers/virtual/inference/virtualdriver_inference.h index 2c4812ff3..c3f5137ca 100644 --- a/src/drivers/virtual/inference/virtualdriver_inference.h +++ b/src/drivers/virtual/inference/virtualdriver_inference.h @@ -49,9 +49,7 @@ class VirtualInferenceFlowUnitDesc : public modelbox::FlowUnitDesc { std::shared_ptr config_; }; -class InferenceVirtualDriver - : public modelbox::VirtualDriver, - public std::enable_shared_from_this { +class InferenceVirtualDriver : public modelbox::VirtualDriver { public: InferenceVirtualDriver() = default; ~InferenceVirtualDriver() override = default; diff --git a/src/drivers/virtual/java/virtualdriver_java.h b/src/drivers/virtual/java/virtualdriver_java.h index 416b73e5a..c428f92b0 100644 --- a/src/drivers/virtual/java/virtualdriver_java.h +++ b/src/drivers/virtual/java/virtualdriver_java.h @@ -54,9 +54,7 @@ class VirtualJavaFlowUnitDesc : public modelbox::FlowUnitDesc { std::string jar_file_path_; }; -class JavaVirtualDriver - : public modelbox::VirtualDriver, - public std::enable_shared_from_this { +class JavaVirtualDriver : public modelbox::VirtualDriver { public: JavaVirtualDriver() = default; ~JavaVirtualDriver() override = default; diff --git a/src/drivers/virtual/python/virtualdriver_python.h b/src/drivers/virtual/python/virtualdriver_python.h index e7d8c3d64..e182138c6 100644 --- a/src/drivers/virtual/python/virtualdriver_python.h +++ b/src/drivers/virtual/python/virtualdriver_python.h @@ -54,9 +54,7 @@ class VirtualPythonFlowUnitDesc : public modelbox::FlowUnitDesc { std::string python_file_path_; }; -class PythonVirtualDriver - : public modelbox::VirtualDriver, - public std::enable_shared_from_this { +class PythonVirtualDriver : public modelbox::VirtualDriver { public: PythonVirtualDriver() = default; ~PythonVirtualDriver() override = default; diff --git a/src/drivers/virtual/yolobox/virtualdriver_yolobox.h b/src/drivers/virtual/yolobox/virtualdriver_yolobox.h index 1bd6043ea..ed4f0e1ce 100644 --- a/src/drivers/virtual/yolobox/virtualdriver_yolobox.h +++ b/src/drivers/virtual/yolobox/virtualdriver_yolobox.h @@ -46,9 +46,7 @@ class YoloBoxVirtualFlowUnitDesc : public modelbox::FlowUnitDesc { std::shared_ptr config_; }; -class YoloBoxVirtualDriver - : public modelbox::VirtualDriver, - public std::enable_shared_from_this { +class YoloBoxVirtualDriver : public modelbox::VirtualDriver { public: YoloBoxVirtualDriver() = default; ~YoloBoxVirtualDriver() override = default; diff --git a/src/java/CMakeLists.txt b/src/java/CMakeLists.txt index 5ac0e60ca..2f807a68a 100644 --- a/src/java/CMakeLists.txt +++ b/src/java/CMakeLists.txt @@ -46,16 +46,32 @@ endif() set(TEST_CONFIG_JSON_FILE ${CMAKE_CURRENT_BINARY_DIR}/src/test/java/com/modelbox/TestConfig.json) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/test/java/com/modelbox/TestConfig.json.in ${TEST_CONFIG_JSON_FILE}) set(MODELBOX_JNI_HEADER_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(JAVA_NATIVE_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src/main/java/com/modelbox) + +file(MAKE_DIRECTORY ${MODELBOX_JNI_HEADER_DIR}) add_subdirectory(jni) +ADD_CUSTOM_TARGET(modelbox-java-jni-header + DEPENDS ${MODELBOX_JNI_HEADER_DIR}/*.h +) + +add_custom_command(OUTPUT ${MODELBOX_JNI_HEADER_DIR}/*.h + COMMAND javac -h ${MODELBOX_JNI_HEADER_DIR} ${JAVA_NATIVE_SOURCE}/* -cp ${CMAKE_CURRENT_BINARY_DIR}/*.jar -d ${MODELBOX_JNI_HEADER_DIR} + DEPENDS ${JAVA_NATIVE_SOURCE} +) +set_source_files_properties(${MODELBOX_JNI_HEADER_DIR} PROPERTIES + GENERATED TRUE +) + +add_dependencies(modelbox-java-jni-header modelbox-java) + add_custom_target( modelbox-java COMMAND mvn package -DskipTests -DbuildDirectory=${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) - add_custom_target( unittest-java ${CMAKE_COMMAND} -E env "TEST_CONFIG_JSON_FILE=${TEST_CONFIG_JSON_FILE}" @@ -74,4 +90,5 @@ install(CODE ) add_dependencies(unittest-java modelbox-java) -add_dependencies(unittest-java modelbox-jni) \ No newline at end of file +add_dependencies(unittest-java modelbox-jni) +add_dependencies(unittest-java all-drivers) \ No newline at end of file diff --git a/src/java/jni/CMakeLists.txt b/src/java/jni/CMakeLists.txt index 59fa37cec..ae40c5726 100644 --- a/src/java/jni/CMakeLists.txt +++ b/src/java/jni/CMakeLists.txt @@ -31,21 +31,24 @@ include_directories(${LIBMODELBOX_INCLUDE}) include_directories(${LIBMODELBOX_BASE_INCLUDE}) include_directories(${CMAKE_CURRENT_LIST_DIR}/include) include_directories(${JNI_INCLUDE_DIRS}) +include_directories(${CMAKE_CURRENT_LIST_DIR}) include_directories(${MODELBOX_JNI_HEADER_DIR}) +include_directories(${HUAWEI_SECURE_C_INCLUDE_DIR}) +set(MODELBOX_JNI "modelbox-jni") file(GLOB_RECURSE LIBMODELBOX_JAVA_JNI_SOURCES *.cpp *.cc *.c) -add_library(modelbox-jni SHARED ${LIBMODELBOX_JAVA_JNI_SOURCES}) - -add_dependencies(modelbox-jni modelbox-java) +add_library(${MODELBOX_JNI} SHARED ${LIBMODELBOX_JAVA_JNI_SOURCES}) +target_compile_options(${MODELBOX_JNI} PUBLIC -fvisibility=hidden) +add_dependencies(${MODELBOX_JNI} modelbox-java-jni-header) -set(MODELBOX_JNI "modelbox-jni") target_link_libraries(${MODELBOX_JNI} ${LIBMODELBOX_SHARED}) set(JNI_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(JNI_PACKAGE_INSTALLDIR "/usr/java/packages/lib") -install(TARGETS modelbox-jni +install(TARGETS ${MODELBOX_JNI} COMPONENT cpu-device-flowunit RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} + LIBRARY DESTINATION ${JNI_PACKAGE_INSTALLDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} OPTIONAL ) diff --git a/src/java/jni/jni_export/buffer.cc b/src/java/jni/jni_export/buffer.cc new file mode 100644 index 000000000..366b9404b --- /dev/null +++ b/src/java/jni/jni_export/buffer.cc @@ -0,0 +1,280 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modelbox/buffer.h" + +#include + +#include "com_modelbox_Buffer.h" +#include "jni_native_object.h" +#include "modelbox/buffer.h" +#include "securec.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_Buffer + * Method: BufferBuild + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Buffer_BufferBuild__J(JNIEnv *env, + jobject j_this, + jlong j_size) { + auto n_buffer = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto ret = n_buffer->Build(j_size); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_Buffer + * Method: BufferBuild + * Signature: ([B)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Buffer_BufferBuild___3B( + JNIEnv *env, jobject j_this, jbyteArray j_data_array) { + if (j_data_array == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_buffer = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto j_data_len = env->GetArrayLength(j_data_array); + if (j_data_len <= 0) { + return; + } + + jbyte *j_data_ptr = env->GetByteArrayElements(j_data_array, nullptr); + if (j_data_ptr == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "Buffer data array is invalid"); + return; + } + Defer { env->ReleaseByteArrayElements(j_data_array, j_data_ptr, (jint)0); }; + + auto ret = n_buffer->BuildFromHost(j_data_ptr, j_data_len); + if (ret != modelbox::STATUS_SUCCESS) { + modelbox::ModelBoxJNIThrow(env, ret); + return; + } + + ret = n_buffer->Build(j_data_ptr, j_data_len); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_Buffer + * Method: BufferGetData + * Signature: ()[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_modelbox_Buffer_BufferGetData(JNIEnv *env, jobject j_this) { + auto n_buffer = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + const void *n_buffer_ptr = n_buffer->ConstData(); + if (n_buffer_ptr == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_NOBUFS, + "Buffer data is null"); + return nullptr; + } + + int n_buffer_len = n_buffer->GetBytes(); + auto *j_data_array = env->NewByteArray(n_buffer_len); + if (j_data_array == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_NOMEM, + "alloc memory for Buffer byte failed."); + return nullptr; + } + + env->SetByteArrayRegion(j_data_array, 0, n_buffer_len, (jbyte *)n_buffer_ptr); + return j_data_array; +} + +/* + * Class: com_modelbox_Buffer + * Method: BufferHasError + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL +Java_com_modelbox_Buffer_BufferHasError(JNIEnv *env, jobject j_this) { + auto n_buffer = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return false; + } + + return (jboolean)n_buffer->HasError(); +} + +/* + * Class: com_modelbox_Buffer + * Method: BufferSetError + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Buffer_BufferSetError( + JNIEnv *env, jobject j_this, jstring j_code, jstring j_message) { + if (j_code == nullptr || j_message == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_buffer = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_buffer->SetError(modelbox::jstring2string(env, j_code), + modelbox::jstring2string(env, j_message)); +} + +/* + * Class: com_modelbox_Buffer + * Method: BufferGetErrorCode + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_modelbox_Buffer_BufferGetErrorCode(JNIEnv *env, jobject j_this) { + auto n_buffer = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return env->NewStringUTF(n_buffer->GetErrorCode().c_str()); +} + +/* + * Class: com_modelbox_Buffer + * Method: BufferGetErrorMsg + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_modelbox_Buffer_BufferGetErrorMsg(JNIEnv *env, jobject j_this) { + auto n_buffer = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return env->NewStringUTF(n_buffer->GetErrorMsg().c_str()); +} + +/* + * Class: com_modelbox_Buffer + * Method: BufferGetBytes + * Signature: ()J + */ +JNIEXPORT jlong JNICALL +Java_com_modelbox_Buffer_BufferGetBytes(JNIEnv *env, jobject j_this) { + auto n_buffer = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return 0; + } + + return (jlong)n_buffer->GetBytes(); +} + +/* + * Class: com_modelbox_Buffer + * Method: BufferCopyMeta + * Signature: (Lcom/modelbox/Buffer;Z)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Buffer_BufferCopyMeta( + JNIEnv *env, jobject j_this, jobject j_buffer, jboolean j_is_overwrite) { + if (j_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_buffer = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto n_buffer_other = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_buffer); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto ret = n_buffer->CopyMeta(n_buffer_other, j_is_overwrite); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_Buffer + * Method: BufferGetDevice + * Signature: ()Lcom/modelbox/Device; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_Buffer_BufferGetDevice(JNIEnv *env, jobject j_this) { + auto n_buffer = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_device = n_buffer->GetDevice(); + auto *j_device = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/Device", n_device); + if (j_device == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_device; +} diff --git a/src/java/jni/jni_export/bufferlist.cc b/src/java/jni/jni_export/bufferlist.cc new file mode 100644 index 000000000..734cb0c99 --- /dev/null +++ b/src/java/jni/jni_export/bufferlist.cc @@ -0,0 +1,291 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "com_modelbox_BufferList.h" +#include "jni_native_object.h" +#include "modelbox/buffer_list.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_BufferList + * Method: BufferListBuild + * Signature: ([I)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_BufferList_BufferListBuild( + JNIEnv *env, jobject j_this, jintArray j_size_list) { + if (j_size_list == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_bufferlist = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_bufferlist == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + jsize j_size_list_len = env->GetArrayLength(j_size_list); + if (j_size_list_len <= 0) { + return; + } + + jint *j_size_list_data = env->GetIntArrayElements(j_size_list, nullptr); + if (j_size_list_data == nullptr) { + modelbox::Status ret = {modelbox::STATUS_NOMEM, + "Get Buffer list array element failed."}; + modelbox::ModelBoxJNIThrow(env, ret); + return; + } + + std::vector size_list; + size_list.reserve(j_size_list_len); + for (int i = 0; i < j_size_list_len; i++) { + size_list.push_back(j_size_list_data[i]); + } + + env->ReleaseIntArrayElements(j_size_list, j_size_list_data, (jint)0); + + auto ret = n_bufferlist->Build(size_list, true); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_BufferList + * Method: BufferListAt + * Signature: (J)Lcom/modelbox/Buffer; + */ +JNIEXPORT jobject JNICALL Java_com_modelbox_BufferList_BufferListAt( + JNIEnv *env, jobject j_this, jlong j_index) { + auto n_bufferlist = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_bufferlist == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_buffer = n_bufferlist->At((size_t)j_index); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_RANGE, + "Bufferlist index is invalid."); + return nullptr; + } + + auto *j_buffer = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/Buffer", n_buffer); + if (j_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_buffer; +} + +/* + * Class: com_modelbox_BufferList + * Method: BufferListSize + * Signature: ()J + */ +JNIEXPORT jlong JNICALL +Java_com_modelbox_BufferList_BufferListSize(JNIEnv *env, jobject j_this) { + auto n_bufferlist = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_bufferlist == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return 0; + } + + return (jlong)n_bufferlist->Size(); +} + +/* + * Class: com_modelbox_BufferList + * Method: BufferListPushBack + * Signature: (Lcom/modelbox/Buffer;)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_BufferList_BufferListPushBack__Lcom_modelbox_Buffer_2( + JNIEnv *env, jobject j_this, jobject j_buffer) { + if (j_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_bufferlist = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_bufferlist == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto n_buffer = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_buffer); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_bufferlist->PushBack(n_buffer); +} + +/* + * Class: com_modelbox_BufferList + * Method: BufferListPushBack + * Signature: ([B)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_BufferList_BufferListPushBack___3B( + JNIEnv *env, jobject j_this, jbyteArray j_data_array) { + if (j_data_array == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_bufferlist = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_bufferlist == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto j_data_len = env->GetArrayLength(j_data_array); + if (j_data_len <= 0) { + return; + } + + jbyte *j_data_ptr = env->GetByteArrayElements(j_data_array, nullptr); + if (j_data_ptr == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "Buffer data array is invalid"); + return; + } + Defer { env->ReleaseByteArrayElements(j_data_array, j_data_ptr, (jint)0); }; + + auto n_buffer = std::make_shared(n_bufferlist->GetDevice()); + auto ret = n_buffer->BuildFromHost(j_data_ptr, j_data_len); + if (ret != modelbox::STATUS_SUCCESS) { + modelbox::ModelBoxJNIThrow(env, ret); + return; + } + + n_bufferlist->PushBack(n_buffer); +} + +/* + * Class: com_modelbox_BufferList + * Method: BufferListAssign + * Signature: ([Lcom/modelbox/Buffer;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_BufferList_BufferListAssign( + JNIEnv *env, jobject j_this, jobjectArray j_buffer_list) { + auto n_bufferlist = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_bufferlist == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_NOTSUPPORT, "not supported"); +} + +/* + * Class: com_modelbox_BufferList + * Method: BufferListGetData + * Signature: ()[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_modelbox_BufferList_BufferListGetData(JNIEnv *env, jobject j_this) { + auto n_bufferlist = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_bufferlist == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto *j_data = env->NewByteArray(n_bufferlist->GetBytes()); + if (j_data == nullptr) { + modelbox::Status ret = {modelbox::STATUS_NOMEM, + "alloc memory for buffer list data failed."}; + modelbox::ModelBoxJNIThrow(env, ret); + return nullptr; + } + + env->SetByteArrayRegion(j_data, 0, n_bufferlist->GetBytes(), + (jbyte *)n_bufferlist->ConstData()); + return j_data; +} + +/* + * Class: com_modelbox_BufferList + * Method: BufferListGetDevice + * Signature: ()Lcom/modelbox/Device; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_BufferList_BufferListGetDevice(JNIEnv *env, jobject j_this) { + auto n_bufferlist = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_bufferlist == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_device = n_bufferlist->GetDevice(); + if (n_device == nullptr) { + return nullptr; + } + + auto *j_device = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/Device", n_device); + if (j_device == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_device; +} + +/* + * Class: com_modelbox_BufferList + * Method: BufferListReset + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_BufferList_BufferListReset(JNIEnv *env, jobject j_this) { + auto n_bufferlist = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_bufferlist == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto ret = n_bufferlist->Reset(); + modelbox::ModelBoxJNIThrow(env, ret); +} diff --git a/src/java/jni/jni_export/configuration.cc b/src/java/jni/jni_export/configuration.cc new file mode 100644 index 000000000..c15bbd31a --- /dev/null +++ b/src/java/jni/jni_export/configuration.cc @@ -0,0 +1,507 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modelbox/base/configuration.h" + +#include + +#include "com_modelbox_Configuration.h" +#include "jni_native_object.h" +#include "scoped_jvm.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationGetBoolean + * Signature: (Ljava/lang/String;Z)Z + */ +JNIEXPORT jboolean JNICALL +Java_com_modelbox_Configuration_ConfigurationGetBoolean(JNIEnv *env, + jobject j_this, + jstring j_key, + jboolean j_default) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return false; + } + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return false; + } + + return (jboolean)n_config->GetBool(modelbox::jstring2string(env, j_key), + (bool)j_default); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationGetInt + * Signature: (Ljava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_modelbox_Configuration_ConfigurationGetInt( + JNIEnv *env, jobject j_this, jstring j_key, jint j_default) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return 0; + } + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return 0; + } + + return (jint)n_config->GetInt32(modelbox::jstring2string(env, j_key), + (jint)j_default); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationGetLong + * Signature: (Ljava/lang/String;J)J + */ +JNIEXPORT jlong JNICALL Java_com_modelbox_Configuration_ConfigurationGetLong( + JNIEnv *env, jobject j_this, jstring j_key, jlong j_default) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return 0; + } + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return 0; + } + + return (jlong)n_config->GetInt64(modelbox::jstring2string(env, j_key), + (jlong)j_default); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationGetString + * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_modelbox_Configuration_ConfigurationGetString(JNIEnv *env, + jobject j_this, + jstring j_key, + jstring j_default) { + std::string defaultValue; + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return nullptr; + } + + if (j_default) { + defaultValue = modelbox::jstring2string(env, j_default); + } + + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto retvalue = + n_config->GetString(modelbox::jstring2string(env, j_key), defaultValue); + return env->NewStringUTF(retvalue.c_str()); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationGetFloat + * Signature: (Ljava/lang/String;F)F + */ +JNIEXPORT jfloat JNICALL Java_com_modelbox_Configuration_ConfigurationGetFloat( + JNIEnv *env, jobject j_this, jstring j_key, jfloat j_default) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return (jfloat)0; + } + + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return (jfloat)0; + } + + return (jfloat)n_config->GetFloat(modelbox::jstring2string(env, j_key), + (jfloat)j_default); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationGetDouble + * Signature: (Ljava/lang/String;D)D + */ +JNIEXPORT jdouble JNICALL +Java_com_modelbox_Configuration_ConfigurationGetDouble(JNIEnv *env, + jobject j_this, + jstring j_key, + jdouble j_default) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return 0; + } + + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return 0; + } + + return (jdouble)n_config->GetDouble(modelbox::jstring2string(env, j_key), + (jdouble)j_default); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationSet + * Signature: (Ljava/lang/String;Z)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_Configuration_ConfigurationSet__Ljava_lang_String_2Z( + JNIEnv *env, jobject j_this, jstring j_key, jboolean j_value) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_config->SetProperty(modelbox::jstring2string(env, j_key), + (bool)j_value); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationSet + * Signature: (Ljava/lang/String;I)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_Configuration_ConfigurationSet__Ljava_lang_String_2I( + JNIEnv *env, jobject j_this, jstring j_key, jint j_value) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_config->SetProperty(modelbox::jstring2string(env, j_key), + (int32_t)j_value); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationSet + * Signature: (Ljava/lang/String;J)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_Configuration_ConfigurationSet__Ljava_lang_String_2J( + JNIEnv *env, jobject j_this, jstring j_key, jlong j_value) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_config->SetProperty(modelbox::jstring2string(env, j_key), + (int64_t)j_value); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationSet + * Signature: (Ljava/lang/String;F)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_Configuration_ConfigurationSet__Ljava_lang_String_2F( + JNIEnv *env, jobject j_this, jstring j_key, jfloat j_value) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_config->SetProperty(modelbox::jstring2string(env, j_key), + (float)j_value); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationSet + * Signature: (Ljava/lang/String;D)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_Configuration_ConfigurationSet__Ljava_lang_String_2D( + JNIEnv *env, jobject j_this, jstring j_key, jdouble j_value) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_config->SetProperty(modelbox::jstring2string(env, j_key), + (double)j_value); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationSet + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_Configuration_ConfigurationSet__Ljava_lang_String_2Ljava_lang_String_2( + JNIEnv *env, jobject j_this, jstring j_key, jstring j_value) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto n_value = modelbox::jstring2string(env, j_value); + + n_config->SetProperty(modelbox::jstring2string(env, j_key), + n_value); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationGetStrings + * Signature: (Ljava/lang/String;Ljava/util/ArrayList;)Ljava/util/ArrayList; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_Configuration_ConfigurationGetStrings(JNIEnv *env, + jobject j_this, + jstring j_key, + jobject j_default) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return nullptr; + } + + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_values = n_config->GetStrings(modelbox::jstring2string(env, j_key)); + if (n_values.empty()) { + return j_default; + } + + auto *j_arraylist_cls = env->FindClass("java/util/ArrayList"); + if (j_arraylist_cls == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_FAULT, + "cannot find array list"); + return nullptr; + } + Defer { env->DeleteLocalRef(j_arraylist_cls); }; + + jmethodID j_list_add_ID = + env->GetMethodID(j_arraylist_cls, "add", "(Ljava/lang/Object;)Z"); + jmethodID j_list_init_ID = + env->GetMethodID(j_arraylist_cls, "", "(I)V"); + + if (j_list_add_ID == nullptr || j_list_init_ID == nullptr) { + modelbox::ModelBoxJNIThrow( + env, modelbox::STATUS_FAULT, + "Cannot find arraylist functions add and "); + return nullptr; + } + + auto *j_arraylist = + env->NewObject(j_arraylist_cls, j_list_init_ID, n_values.size()); + if (j_arraylist == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_NOMEM, + "cannot create arraylist"); + return nullptr; + } + + for (const auto &n_value : n_values) { + auto *j_obj = env->NewStringUTF(n_value.c_str()); + env->CallBooleanMethod(j_arraylist, j_list_add_ID, j_obj); + env->DeleteLocalRef(j_obj); + } + + return j_arraylist; +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationSet + * Signature: (Ljava/lang/String;Ljava/util/ArrayList;)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_Configuration_ConfigurationSet__Ljava_lang_String_2Ljava_util_ArrayList_2( + JNIEnv *env, jobject j_this, jstring j_key, jobject j_array_string) { + if (j_key == nullptr || j_array_string == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_config = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto *j_arraylist_cls = env->FindClass("java/util/ArrayList"); + if (j_arraylist_cls == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_FAULT, + "cannot find array list"); + return; + } + Defer { env->DeleteLocalRef(j_arraylist_cls); }; + + jmethodID j_list_get_ID = + env->GetMethodID(j_arraylist_cls, "get", "(I)Ljava/lang/Object;"); + jmethodID j_list_size_ID = env->GetMethodID(j_arraylist_cls, "size", "()I"); + + if (j_list_get_ID == nullptr || j_list_size_ID == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_FAULT, + "Cannot find arraylist functions get and size"); + return; + } + + jsize j_arraylist_size = env->CallIntMethod(j_array_string, j_list_size_ID); + if (j_arraylist_size <= 0) { + return; + } + + std::vector n_values; + n_values.reserve(j_arraylist_size); + for (int i = 0; i < j_arraylist_size; i++) { + auto *j_obj = + (jstring)env->CallObjectMethod(j_array_string, j_list_get_ID, i); + Defer { env->DeleteLocalRef(j_obj); }; + + auto n_value = modelbox::jstring2string(env, j_obj); + n_values.emplace_back(n_value); + } + + n_config->SetProperty(modelbox::jstring2string(env, j_key), + n_values); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationParser + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Configuration_ConfigurationParser( + JNIEnv *env, jobject j_this, jstring j_file) { + if (j_file == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + modelbox::ConfigurationBuilder builder; + auto n_newconfig = builder.Build(modelbox::jstring2string(env, j_file)); + if (n_newconfig == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto ret = + modelbox::JNINativeObject::SetNativeSharedPtr(env, j_this, n_newconfig); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_Configuration + * Method: ConfigurationNew + * Signature: ()J + */ +JNIEXPORT jlong JNICALL +Java_com_modelbox_Configuration_ConfigurationNew(JNIEnv *env, jobject j_this) { + return modelbox::JNINativeObject::NewHandle( + j_this, std::make_shared()); +} diff --git a/src/java/jni/jni_export/data_meta.cc b/src/java/jni/jni_export/data_meta.cc new file mode 100644 index 000000000..a2c1cb8a2 --- /dev/null +++ b/src/java/jni/jni_export/data_meta.cc @@ -0,0 +1,97 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "com_modelbox_DataMeta.h" +#include "jni_native_object.h" +#include "modelbox/external_data_map.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_DataMeta + * Method: DataMetaNew + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_modelbox_DataMeta_DataMetaNew(JNIEnv *env, + jobject j_this) { + return modelbox::JNINativeObject::NewHandle( + j_this, std::make_shared()); +} + +/* + * Class: com_modelbox_DataMeta + * Method: DataMetaSet + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_DataMeta_DataMetaSet(JNIEnv *env, + jobject j_this, + jstring j_key, + jstring j_value) { + if (j_key == nullptr || j_value == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_datameta = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_datameta == nullptr || j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_datameta->SetMeta( + modelbox::jstring2string(env, j_key), + std::make_shared(modelbox::jstring2string(env, j_value))); +} + +/* + * Class: com_modelbox_DataMeta + * Method: DataMetaGetString + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_modelbox_DataMeta_DataMetaGetString( + JNIEnv *env, jobject j_this, jstring j_key) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return nullptr; + } + + auto n_datameta = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_datameta == nullptr || j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto value = n_datameta->GetMeta(modelbox::jstring2string(env, j_key)); + if (value == nullptr) { + return nullptr; + } + + auto n_value = std::static_pointer_cast(value); + if (value == nullptr) { + return nullptr; + } + + return env->NewStringUTF(n_value->c_str()); +} diff --git a/src/java/jni/jni_export/datacontext.cc b/src/java/jni/jni_export/datacontext.cc new file mode 100644 index 000000000..f3643bbe2 --- /dev/null +++ b/src/java/jni/jni_export/datacontext.cc @@ -0,0 +1,410 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "com_modelbox_DataContext.h" +#include "jni_native_object.h" +#include "modelbox/data_context.h" +#include "scoped_jvm.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_DataContext + * Method: DataContext_Input + * Signature: (Ljava/lang/String;)Lcom/modelbox/BufferList; + */ +JNIEXPORT jobject JNICALL Java_com_modelbox_DataContext_DataContext_1Input( + JNIEnv *env, jobject j_this, jstring j_portname) { + if (j_portname == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return nullptr; + } + + auto n_data_ctx = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_data_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_buffer_list = + n_data_ctx->Input(modelbox::jstring2string(env, j_portname)); + if (n_buffer_list) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input port not exists"); + return nullptr; + } + + auto *j_buffer_list = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/BufferList", n_buffer_list); + if (j_buffer_list == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_buffer_list; +} + +/* + * Class: com_modelbox_DataContext + * Method: DataContext_Output + * Signature: (Ljava/lang/String;)Lcom/modelbox/BufferList; + */ +JNIEXPORT jobject JNICALL Java_com_modelbox_DataContext_DataContext_1Output( + JNIEnv *env, jobject j_this, jstring j_portname) { + if (j_portname == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return nullptr; + } + + auto n_data_ctx = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_data_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_buffer_list = + n_data_ctx->Output(modelbox::jstring2string(env, j_portname)); + if (n_buffer_list) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "output port not exists"); + return nullptr; + } + + auto *j_buffer_list = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/BufferList", n_buffer_list); + if (j_buffer_list == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_buffer_list; +} + +/* + * Class: com_modelbox_DataContext + * Method: DataContext_External + * Signature: ()Lcom/modelbox/BufferList; + */ +JNIEXPORT jobject JNICALL Java_com_modelbox_DataContext_DataContext_1External( + JNIEnv *env, jobject j_this) { + auto n_data_ctx = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_data_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_buffer_list = n_data_ctx->External(); + if (n_buffer_list) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "external port not exists"); + return nullptr; + } + + auto *j_buffer_list = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/BufferList", n_buffer_list); + if (j_buffer_list == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_buffer_list; +} + +/* + * Class: com_modelbox_DataContext + * Method: DataContext_HasError + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_com_modelbox_DataContext_DataContext_1HasError( + JNIEnv *env, jobject j_this) { + auto n_data_ctx = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_data_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return false; + } + + return n_data_ctx->HasError(); +} + +/* + * Class: com_modelbox_DataContext + * Method: DataContext_SendEvent + * Signature: (Lcom/modelbo::DataContext;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_DataContext_DataContext_1SendEvent( + JNIEnv *env, jobject j_this, jobject j_event) { + if (j_event == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_data_ctx = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_data_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto n_event = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_event); + if (n_event == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_data_ctx->SendEvent(n_event); +} + +/* + * Class: com_modelbox_DataContext + * Method: DataContext_SetPrivate + * Signature: (Ljava/lang/String;Ljava/lang/Object;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_DataContext_DataContext_1SetPrivate( + JNIEnv *env, jobject j_this, jstring j_key, jobject j_object) { + if (j_object == nullptr || j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_data_ctx = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_data_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto *j_global_object = env->NewGlobalRef(j_object); + std::shared_ptr priv_ptr( + (void *)j_global_object, [](void *j_global_object) { + modelbox::ScopedJvm scoped; + scoped.GetJNIEnv()->DeleteGlobalRef((jobject)j_global_object); + }); + n_data_ctx->SetPrivate(modelbox::jstring2string(env, j_key), priv_ptr); +} + +/* + * Class: com_modelbox_DataContext + * Method: DataContext_GetPrivate + * Signature: (Ljava/lang/String;)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_com_modelbox_DataContext_DataContext_1GetPrivate( + JNIEnv *env, jobject j_this, jstring j_key) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return nullptr; + } + + auto n_data_ctx = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_data_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_object = n_data_ctx->GetPrivate(modelbox::jstring2string(env, j_key)); + if (n_object == nullptr) { + return nullptr; + } + + return (jobject)n_object.get(); +} + +/* + * Class: com_modelbox_DataContext + * Method: DataContext_GetInputMeta + * Signature: (Ljava/lang/String;)Lcom/modelbox/DataMeta; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_DataContext_DataContext_1GetInputMeta(JNIEnv *env, + jobject j_this, + jstring j_portname) { + if (j_portname == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return nullptr; + } + + auto n_data_ctx = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_data_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_datameta = + n_data_ctx->GetInputMeta(modelbox::jstring2string(env, j_portname)); + if (n_datameta == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "port meta not exists"); + return nullptr; + } + + auto *j_datameta = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/DataMeta", n_datameta); + if (j_datameta == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + } + + return j_datameta; +} + +/* + * Class: com_modelbox_DataContext + * Method: DataContext_SetOututMeta + * Signature: (Ljava/lang/String;Lcom/modelbox/DataMeta;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_DataContext_DataContext_1SetOututMeta( + JNIEnv *env, jobject j_this, jstring j_portname, jobject j_datameta) { + if (j_portname == nullptr || j_datameta == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_data_ctx = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_data_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto n_datameta = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_datameta); + if (n_datameta == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_data_ctx->SetOutputMeta(modelbox::jstring2string(env, j_portname), + n_datameta); +} + +/* + * Class: com_modelbox_DataContext + * Method: DataContext_GetSessionContext + * Signature: ()Lcom/modelbox/SessionContext; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_DataContext_DataContext_1GetSessionContext(JNIEnv *env, + jobject j_this) { + auto n_data_ctx = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_data_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_session_config = n_data_ctx->GetSessionConfig(); + if (n_session_config == nullptr) { + return nullptr; + } + + auto *j_session_config = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/SessionConfig", n_session_config); + if (j_session_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_session_config; +} + +/* + * Class: com_modelbox_DataContext + * Method: DataContext_GetSessionConfig + * Signature: ()Lcom/modelbox/Configuration; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_DataContext_DataContext_1GetSessionConfig(JNIEnv *env, + jobject j_this) { + auto n_data_ctx = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_data_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_session_context = n_data_ctx->GetSessionContext(); + if (n_session_context == nullptr) { + return nullptr; + } + + auto *j_session_ctx = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/SessionContext", n_session_context); + if (j_session_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_session_ctx; +} + +/* + * Class: com_modelbox_DataContext + * Method: DataContext_GetStatistics + * Signature: ()Lcom/modelbox/StatisticsItem; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_DataContext_DataContext_1GetStatistics(JNIEnv *env, + jobject j_this) { + auto n_data_ctx = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_data_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_statistics = n_data_ctx->GetStatistics(); + if (n_statistics == nullptr) { + return nullptr; + } + + auto *j_statistics = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/StatisticsItem", n_statistics); + if (j_statistics == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_statistics; +} \ No newline at end of file diff --git a/src/java/jni/jni_export/device.cc b/src/java/jni/jni_export/device.cc new file mode 100644 index 000000000..86796567e --- /dev/null +++ b/src/java/jni/jni_export/device.cc @@ -0,0 +1,61 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modelbox/base/device.h" + +#include + +#include "com_modelbox_Device.h" +#include "jni_native_object.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_Device + * Method: DeviceGetType + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_modelbox_Device_DeviceGetType(JNIEnv *env, jobject j_this) { + auto n_device = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_device == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return env->NewStringUTF(n_device->GetType().c_str()); +} + +/* + * Class: com_modelbox_Device + * Method: DeviceGetDeviceID + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_modelbox_Device_DeviceGetDeviceID(JNIEnv *env, jobject j_this) { + auto n_device = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_device == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return env->NewStringUTF(n_device->GetDeviceID().c_str()); +} diff --git a/src/java/jni/jni_export/external_data_map.cc b/src/java/jni/jni_export/external_data_map.cc new file mode 100644 index 000000000..fa3fd8f81 --- /dev/null +++ b/src/java/jni/jni_export/external_data_map.cc @@ -0,0 +1,311 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modelbox/external_data_map.h" + +#include + +#include "com_modelbox_ExternalDataMap.h" +#include "jni_native_object.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_ExternalDataMap + * Method: ExternalDataMap_CreateBufferList + * Signature: ()Lcom/modelbox/BufferList; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_ExternalDataMap_ExternalDataMap_1CreateBufferList( + JNIEnv *env, jobject j_this) { + auto n_datamap = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_datamap == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_bufflist = n_datamap->CreateBufferList(); + if (n_bufflist == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_NOMEM, + "create buffer list failed."); + return nullptr; + } + + auto *j_buffer_list = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/BufferList", n_bufflist); + if (j_buffer_list == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_buffer_list; +} + +/* + * Class: com_modelbox_ExternalDataMap + * Method: ExternalDataMap_SetOutputMeta + * Signature: (Ljava/lang/String;Lcom/modelbox/DataMeta;)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_ExternalDataMap_ExternalDataMap_1SetOutputMeta( + JNIEnv *env, jobject j_this, jstring j_name, jobject j_data_meta) { + if (j_name == nullptr || j_data_meta) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_datamap = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_datamap == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto n_data_meta = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_data_meta); + if (n_data_meta == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto ret = n_datamap->SetOutputMeta(modelbox::jstring2string(env, j_name), + n_data_meta); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_ExternalDataMap + * Method: ExternalDataMap_Send + * Signature: (Ljava/lang/String;Lcom/modelbox/BufferList;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_ExternalDataMap_ExternalDataMap_1Send( + JNIEnv *env, jobject j_this, jstring j_port_name, jobject j_bufferlist) { + if (j_port_name == nullptr || j_bufferlist == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_datamap = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_datamap == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto j_buffer_list = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_bufferlist); + if (j_buffer_list == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto ret = n_datamap->Send(modelbox::jstring2string(env, j_port_name), + j_buffer_list); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_ExternalDataMap + * Method: ExternalDataMap_Recv + * Signature: (J)Ljava/util/HashMap; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_ExternalDataMap_ExternalDataMap_1Recv(JNIEnv *env, + jobject j_this, + jlong j_timeout) { + auto n_datamap = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_datamap == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + modelbox::OutputBufferList map_buffer_list; + auto ret = n_datamap->Recv(map_buffer_list, (int32_t)j_timeout); + if (ret != modelbox::STATUS_SUCCESS) { + if (ret == modelbox::STATUS_EOF) { + return nullptr; + } + + modelbox::ModelBoxJNIThrow(env, ret); + return nullptr; + } + + jclass j_map_cls = env->FindClass("java/util/HashMap"); + if (j_map_cls == nullptr) { + ret = {modelbox::STATUS_INTERNAL, "cannot found hash map class"}; + modelbox::ModelBoxJNIThrow(env, ret); + return nullptr; + } + + Defer { env->DeleteLocalRef(j_map_cls); }; + + jmethodID init = env->GetMethodID(j_map_cls, "", "()V"); + jobject j_hashmap = env->NewObject(j_map_cls, init, 10); + jmethodID put = env->GetMethodID( + j_map_cls, "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + + for (const auto &item : map_buffer_list) { + jstring j_key = env->NewStringUTF(item.first.c_str()); + auto *j_bufflist = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/BufferList", item.second); + env->CallObjectMethod(j_hashmap, put, j_key, j_bufflist); + env->DeleteLocalRef(j_key); + env->DeleteLocalRef(j_bufflist); + } + + return j_hashmap; +} + +/* + * Class: com_modelbox_ExternalDataMap + * Method: ExternalDataMap_Close + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_modelbox_ExternalDataMap_ExternalDataMap_1Close( + JNIEnv *env, jobject j_this) { + auto n_datamap = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_datamap == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_datamap->Close(); +} + +/* + * Class: com_modelbox_ExternalDataMap + * Method: ExternalDataMap_Shutdown + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_ExternalDataMap_ExternalDataMap_1Shutdown(JNIEnv *env, + jobject j_this) { + auto n_datamap = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_datamap == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_datamap->Shutdown(); +} + +/* + * Class: com_modelbox_ExternalDataMap + * Method: ExternalDataMap_GetSessionContext + * Signature: ()Lcom/modelbox/SessionContext; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_ExternalDataMap_ExternalDataMap_1GetSessionContext( + JNIEnv *env, jobject j_this) { + auto n_datamap = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_datamap == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_session_context = n_datamap->GetSessionContext(); + if (n_session_context == nullptr) { + return nullptr; + } + + auto *j_session_ctx = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/SessionContext", n_session_context); + if (j_session_ctx == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_session_ctx; +} + +/* + * Class: com_modelbox_ExternalDataMap + * Method: ExternalDataMap_GetSessionConfig + * Signature: ()Lcom/modelbox/Configuration; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_ExternalDataMap_ExternalDataMap_1GetSessionConfig( + JNIEnv *env, jobject j_this) { + auto n_datamap = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_datamap == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_session_config = n_datamap->GetSessionConfig(); + if (n_session_config == nullptr) { + return nullptr; + } + + auto *j_session_config = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/SessionConfig", n_session_config); + if (j_session_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_session_config; +} + +/* + * Class: com_modelbox_ExternalDataMap + * Method: ExternalDataMap_GetLastError + * Signature: ()Lcom/modelbox/FlowUnitError; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_ExternalDataMap_ExternalDataMap_1GetLastError( + JNIEnv *env, jobject j_this) { + auto n_datamap = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_datamap == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_laste_error = n_datamap->GetLastError(); + if (n_laste_error == nullptr) { + return nullptr; + } + + auto *j_last_error = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/FlowUnitError", n_laste_error); + if (j_last_error == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_last_error; +} diff --git a/src/java/jni/jni_export/external_data_select.cc b/src/java/jni/jni_export/external_data_select.cc new file mode 100644 index 000000000..b8acfd1a7 --- /dev/null +++ b/src/java/jni/jni_export/external_data_select.cc @@ -0,0 +1,175 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "com_modelbox_ExternalDataSelect.h" +#include "jni_native_object.h" +#include "modelbox/external_data_map.h" +#include "throw.h" +#include "utils.h" +#include "scoped_jvm.h" + +/* + * Class: com_modelbox_ExternalDataSelect + * Method: ExternalDataSelect_New + * Signature: ()J + */ +JNIEXPORT jlong JNICALL +Java_com_modelbox_ExternalDataSelect_ExternalDataSelect_1New(JNIEnv *env, + jobject j_this) { + return modelbox::JNINativeObject::NewHandle( + j_this, std::make_shared()); +} + +/* + * Class: com_modelbox_ExternalDataSelect + * Method: ExternalDataSelect_RegisterExternalData + * Signature: (Lcom/modelbox/ExternalDataMap;)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_ExternalDataSelect_ExternalDataSelect_1RegisterExternalData( + JNIEnv *env, jobject j_this, jobject j_data_map) { + if (j_data_map == nullptr) { + modelbox::ModelBoxJNIThrow( + env, modelbox::STATUS_INVALID, + "ExternalDataSelect Register: input argument is null"); + return; + } + + auto n_data_select = modelbox::JNINativeObject::GetNativeSharedPtr< + modelbox::ExternalDataSelect>(env, j_this); + if (n_data_select == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto n_data_map = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_data_map); + if (n_data_map == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto *j_global_data_map = env->NewGlobalRef(j_data_map); + std::shared_ptr priv_ptr( + (void *)j_global_data_map, [](void *global_data_map) { + modelbox::ScopedJvm scoped; + scoped.GetJNIEnv()->DeleteGlobalRef((jobject)global_data_map); + }); + n_data_map->SetPrivate(priv_ptr); + n_data_select->RegisterExternalData(n_data_map); +} + +/* + * Class: com_modelbox_ExternalDataSelect + * Method: ExternalDataSelect_RemoveExternalData + * Signature: (Lcom/modelbox/ExternalDataMap;)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_ExternalDataSelect_ExternalDataSelect_1RemoveExternalData( + JNIEnv *env, jobject j_this, jobject j_data_map) { + if (j_data_map == nullptr) { + modelbox::ModelBoxJNIThrow( + env, modelbox::STATUS_INVALID, + "ExternalDataSelect Remove: input argument is null"); + return; + } + + auto n_data_select = modelbox::JNINativeObject::GetNativeSharedPtr< + modelbox::ExternalDataSelect>(env, j_this); + if (n_data_select == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto n_data_map = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_data_map); + if (n_data_map == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_data_select->RemoveExternalData(n_data_map); +} + +/* + * Class: com_modelbox_ExternalDataSelect + * Method: ExternalDataSelect_SelectExternalData + * Signature: (J)Ljava/util/ArrayList; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_ExternalDataSelect_ExternalDataSelect_1SelectExternalData( + JNIEnv *env, jobject j_this, jlong j_timeout) { + auto n_data_select = modelbox::JNINativeObject::GetNativeSharedPtr< + modelbox::ExternalDataSelect>(env, j_this); + if (n_data_select == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + std::list> datamap_list; + auto ret = n_data_select->SelectExternalData( + datamap_list, std::chrono::milliseconds((int64_t)j_timeout)); + if (ret != modelbox::STATUS_SUCCESS) { + if (ret == modelbox::STATUS_TIMEDOUT) { + return nullptr; + } + modelbox::ModelBoxJNIThrow(env, ret); + return nullptr; + } + + auto *j_arraylist_cls = env->FindClass("java/util/ArrayList"); + if (j_arraylist_cls == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_FAULT, + "cannot find array list"); + return nullptr; + } + Defer { env->DeleteLocalRef(j_arraylist_cls); }; + + jmethodID j_list_add_ID = + env->GetMethodID(j_arraylist_cls, "add", "(Ljava/lang/Object;)Z"); + jmethodID j_list_init_ID = + env->GetMethodID(j_arraylist_cls, "", "(I)V"); + + if (j_list_add_ID == nullptr || j_list_init_ID == nullptr) { + modelbox::ModelBoxJNIThrow( + env, modelbox::STATUS_FAULT, + "Cannot find arraylist functions add and "); + return nullptr; + } + + auto *j_arraylist = + env->NewObject(j_arraylist_cls, j_list_init_ID, datamap_list.size()); + if (j_arraylist == nullptr) { + ret = {modelbox::STATUS_NOMEM, "cannot create arraylist"}; + modelbox::ModelBoxJNIThrow(env, ret); + return nullptr; + } + + for (const auto &datamap : datamap_list) { + std::shared_ptr object = datamap->GetPrivate(); + if (object == nullptr) { + continue; + } + + env->CallBooleanMethod(j_arraylist, j_list_add_ID, (jobject)object.get()); + } + + return j_arraylist; +} \ No newline at end of file diff --git a/src/java/jni/jni_export/flow.cc b/src/java/jni/jni_export/flow.cc new file mode 100644 index 000000000..2c4d7a8af --- /dev/null +++ b/src/java/jni/jni_export/flow.cc @@ -0,0 +1,305 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modelbox/flow.h" + +#include + +#include "com_modelbox_Flow.h" +#include "jni_native_object.h" +#include "modelbox/base/log.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_Flow + * Method: FlowNew + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_modelbox_Flow_FlowNew(JNIEnv *env, + jobject j_this) { + return modelbox::JNINativeObject::NewHandle( + j_this, std::make_shared()); +} + +/* + * Class: com_modelbox_Flow + * Method: FlowWait + * Signature: (JLcom/modelbox/Status;)Z + */ +JNIEXPORT jboolean JNICALL Java_com_modelbox_Flow_FlowWait(JNIEnv *env, + jobject j_this, + jlong j_timeout, + jobject j_status) { + auto n_flow = modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flow == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return false; + } + + modelbox::Status wait_ret; + auto ret = n_flow->Wait((int64_t)j_timeout, &wait_ret); + if (ret != modelbox::STATUS_SUCCESS) { + if (ret == modelbox::STATUS_TIMEDOUT) { + return false; + } + + modelbox::ModelBoxJNIThrow(env, ret); + return false; + } + + if (j_status) { + auto n_status = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_status); + if (n_status) { + *n_status = wait_ret; + } + } + + return true; +} + +/* + * Class: com_modelbox_Flow + * Method: FlowStartRun + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Flow_FlowStartRun(JNIEnv *env, + jobject j_this) { + auto n_flow = modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flow == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto ret = n_flow->StartRun(); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_Flow + * Method: FlowInit + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_Flow_FlowInit__Ljava_lang_String_2Ljava_lang_String_2( + JNIEnv *env, jobject j_this, jstring j_name, jstring j_graph) { + if (j_graph == nullptr || j_name == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_flow = modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flow == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto ret = n_flow->Init(modelbox::jstring2string(env, j_name), + modelbox::jstring2string(env, j_graph)); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_Flow + * Method: FlowInit + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Flow_FlowInit__Ljava_lang_String_2( + JNIEnv *env, jobject j_this, jstring j_file) { + if (j_file == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_flow = modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flow == nullptr || j_file == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto ret = n_flow->Init(modelbox::jstring2string(env, j_file)); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_Flow + * Method: FlowInit + * Signature: + * (Ljava/lang/String;Lcom/modelbox/Configuration;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_Flow_FlowInitByName__Ljava_lang_String_2Lcom_modelbox_Configuration_2Ljava_lang_String_2( + JNIEnv *env, jobject j_this, jstring j_name, jobject j_args, + jstring j_flowdir) { + if (j_name == nullptr || j_args == nullptr || j_flowdir == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_flow = modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flow == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + std::unordered_map m_args; + if (j_args != nullptr) { + auto n_args = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_args); + if (n_args == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + for (const auto &key : n_args->GetKeys()) { + m_args[key] = n_args->GetString(key); + } + } + + auto ret = n_flow->InitByName(modelbox::jstring2string(env, j_name), m_args, + modelbox::jstring2string(env, j_flowdir)); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_Flow + * Method: FlowInit + * Signature: (Ljava/lang/String;Lcom/modelbox/Configuration;)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_Flow_FlowInitByName__Ljava_lang_String_2Lcom_modelbox_Configuration_2( + JNIEnv *env, jobject j_this, jstring j_name, jobject j_args) { + if (j_name == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + } + + auto n_flow = modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flow == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + std::unordered_map m_args; + if (j_args != nullptr) { + auto n_args = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_args); + if (n_args == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + for (const auto &key : n_args->GetKeys()) { + m_args[key] = n_args->GetString(key); + } + } + + auto ret = n_flow->InitByName(modelbox::jstring2string(env, j_name), m_args); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_Flow + * Method: FlowStop + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Flow_FlowStop(JNIEnv *env, + jobject j_this) { + auto n_flow = modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flow == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_flow->Stop(); +} + +/* + * Class: com_modelbox_Flow + * Method: FlowCreateExternalDataMap + * Signature: ()Lcom/modelbox/ExternalDataMap; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_Flow_FlowCreateExternalDataMap(JNIEnv *env, jobject j_this) { + auto n_flow = modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flow == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto datamap = n_flow->CreateExternalDataMap(); + if (datamap == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_FAULT, + "Create External data failed."); + return nullptr; + } + + jobject j_data_map = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/ExternalDataMap", datamap); + if (j_data_map == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_data_map; +} + +/* + * Class: com_modelbox_Flow + * Method: FlowCreateStreamIO + * Signature: ()Lcom/modelbox/FlowStreamIO; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_Flow_FlowCreateStreamIO(JNIEnv *env, jobject j_this) { + auto n_flow = modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flow == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto stream_io = n_flow->CreateStreamIO(); + if (stream_io == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_FAULT, + "Create External data failed."); + return nullptr; + } + + jobject j_stream_io = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/FlowStreamIO", stream_io); + if (j_stream_io == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_stream_io; +} diff --git a/src/java/jni/jni_export/flow_streamio.cc b/src/java/jni/jni_export/flow_streamio.cc new file mode 100644 index 000000000..ead5e40c0 --- /dev/null +++ b/src/java/jni/jni_export/flow_streamio.cc @@ -0,0 +1,195 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "com_modelbox_FlowStreamIO.h" +#include "jni_native_object.h" +#include "modelbox/flow_stream_io.h" +#include "scoped_jvm.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_FlowStreamIO + * Method: FlowStreamIO_CreateBuffer + * Signature: ()Lcom/modelbox/Buffer; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_FlowStreamIO_FlowStreamIO_1CreateBuffer(JNIEnv *env, + jobject j_this) { + auto n_stream_io = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_stream_io == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_buff = n_stream_io->CreateBuffer(); + if (n_buff == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_NOMEM, + "create buffer list failed."); + return nullptr; + } + + auto *j_buffer = + modelbox::JNINativeObject::NewJObject(env, "com/modelbox/Buffer", n_buff); + if (j_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_buffer; +} + +/* + * Class: com_modelbox_FlowStreamIO + * Method: FlowStreamIO_Send + * Signature: (Ljava/lang/String;Lcom/modelbox/Buffer;)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_FlowStreamIO_FlowStreamIO_1Send__Ljava_lang_String_2Lcom_modelbox_Buffer_2( + JNIEnv *env, jobject j_this, jstring j_inport_name, jobject j_buffer) { + if (j_inport_name == nullptr || j_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_stream_io = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_stream_io == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto n_buffer = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_buffer); + if (n_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto ret = + n_stream_io->Send(modelbox::jstring2string(env, j_inport_name), n_buffer); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_FlowStreamIO + * Method: FlowStreamIO_Send + * Signature: (Ljava/lang/String;[B)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_FlowStreamIO_FlowStreamIO_1Send__Ljava_lang_String_2_3B( + JNIEnv *env, jobject j_this, jstring j_inport_name, + jbyteArray j_data_array) { + if (j_inport_name == nullptr || j_data_array == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_stream_io = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_stream_io == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto j_data_len = env->GetArrayLength(j_data_array); + if (j_data_len <= 0) { + return; + } + + jbyte *j_data_ptr = env->GetByteArrayElements(j_data_array, nullptr); + if (j_data_ptr == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "Buffer data array is invalid"); + return; + } + Defer { env->ReleaseByteArrayElements(j_data_array, j_data_ptr, (jint)0); }; + + auto n_buffer = n_stream_io->CreateBuffer(); + auto ret = n_buffer->BuildFromHost(j_data_ptr, j_data_len); + if (ret != modelbox::STATUS_SUCCESS) { + modelbox::ModelBoxJNIThrow(env, ret); + return; + } + + ret = + n_stream_io->Send(modelbox::jstring2string(env, j_inport_name), n_buffer); + modelbox::ModelBoxJNIThrow(env, ret); +} + +/* + * Class: com_modelbox_FlowStreamIO + * Method: FlowStreamIO_Recv + * Signature: (Ljava/lang/String;J)Lcom/modelbox/Buffer; + */ +JNIEXPORT jobject JNICALL Java_com_modelbox_FlowStreamIO_FlowStreamIO_1Recv( + JNIEnv *env, jobject j_this, jstring j_outport_name, jlong j_timeout) { + auto n_stream_io = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_stream_io == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + std::shared_ptr n_buff; + auto ret = n_stream_io->Recv(modelbox::jstring2string(env, j_outport_name), + n_buff, (int64_t)j_timeout); + if (ret != modelbox::STATUS_SUCCESS) { + if (ret == modelbox::STATUS_EOF) { + return nullptr; + } + + modelbox::ModelBoxJNIThrow(env, ret, "recv buffer failed."); + return nullptr; + } + + auto *j_buffer = + modelbox::JNINativeObject::NewJObject(env, "com/modelbox/Buffer", n_buff); + if (j_buffer == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return j_buffer; +} + +/* + * Class: com_modelbox_FlowStreamIO + * Method: FlowStreamIO_CloseInput + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_modelbox_FlowStreamIO_FlowStreamIO_1CloseInput( + JNIEnv *env, jobject j_this) { + auto n_stream_io = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_stream_io == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_stream_io->CloseInput(); +} \ No newline at end of file diff --git a/src/java/jni/jni_export/flowunit_error.cc b/src/java/jni/jni_export/flowunit_error.cc new file mode 100644 index 000000000..809972cac --- /dev/null +++ b/src/java/jni/jni_export/flowunit_error.cc @@ -0,0 +1,115 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "com_modelbox_FlowUnitError.h" +#include "jni_native_object.h" +#include "modelbox/error.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_FlowUnitError + * Method: FlowUnitError_New + * Signature: (Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL +Java_com_modelbox_FlowUnitError_FlowUnitError_1New__Ljava_lang_String_2( + JNIEnv *env, jobject j_this, jstring j_desc) { + if (j_desc == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::JNIEXCEPT_NullPointer, + "input argument is null"); + return 0; + } + + return modelbox::JNINativeObject::NewHandle( + j_this, std::make_shared( + modelbox::jstring2string(env, j_desc))); +} + +/* + * Class: com_modelbox_FlowUnitError + * Method: FlowUnitError_New + * Signature: (Ljava/lang/String;Ljava/lang/String;Lcom/modelbox/Status;)J + */ +JNIEXPORT jlong JNICALL +Java_com_modelbox_FlowUnitError_FlowUnitError_1New__Ljava_lang_String_2Ljava_lang_String_2Lcom_modelbox_Status_2( + JNIEnv *env, jobject j_this, jstring j_node, jstring j_pos, + jobject j_status) { + if (j_node == nullptr || j_pos == nullptr || j_status == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::JNIEXCEPT_NullPointer, + "input argument is null"); + return 0; + } + + auto n_flowunit_status = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_status); + if (j_status == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return 0; + } + + return modelbox::JNINativeObject::NewHandle( + j_this, std::make_shared( + modelbox::jstring2string(env, j_node), + modelbox::jstring2string(env, j_pos), *n_flowunit_status)); +} + +/* + * Class: com_modelbox_FlowUnitError + * Method: FlowUnitError_GetDesc + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_modelbox_FlowUnitError_FlowUnitError_1GetDesc(JNIEnv *env, + jobject j_this) { + auto n_flowunit_error = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flowunit_error == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return env->NewStringUTF(n_flowunit_error->GetDesc().c_str()); +} + +/* + * Class: com_modelbox_FlowUnitError + * Method: FlowUnitError_GetStatus + * Signature: ()Lcom/modelbox/Status; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_FlowUnitError_FlowUnitError_1GetStatus(JNIEnv *env, + jobject j_this) { + auto n_flowunit_error = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flowunit_error == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto stat = std::make_shared(n_flowunit_error->GetStatus()); + + auto *j_status = + modelbox::JNINativeObject::NewJObject(env, "com/modelbox/Status", stat); + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return j_status; +} diff --git a/src/java/jni/jni_export/flowunit_event.cc b/src/java/jni/jni_export/flowunit_event.cc new file mode 100644 index 000000000..f981e6e2d --- /dev/null +++ b/src/java/jni/jni_export/flowunit_event.cc @@ -0,0 +1,96 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "com_modelbox_FlowUnitEvent.h" +#include "jni_native_object.h" +#include "modelbox/data_context.h" +#include "scoped_jvm.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_FlowUnitEvent + * Method: FlowUnitEventNew + * Signature: ()J + */ +JNIEXPORT jlong JNICALL +Java_com_modelbox_FlowUnitEvent_FlowUnitEventNew(JNIEnv *env, jobject j_this) { + return modelbox::JNINativeObject::NewHandle( + j_this, std::make_shared()); +} + +/* + * Class: com_modelbox_FlowUnitEvent + * Method: FlowUnitEventSet + * Signature: (Ljava/lang/String;Ljava/lang/Object;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_FlowUnitEvent_FlowUnitEventSet( + JNIEnv *env, jobject j_this, jstring j_key, jobject j_object) { + if (j_key == nullptr || j_object == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return; + } + + auto n_flowunit_event = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flowunit_event == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto *j_global_object = env->NewGlobalRef(j_object); + std::shared_ptr priv_ptr( + (void *)j_global_object, [](void *j_global_object) { + modelbox::ScopedJvm scoped; + scoped.GetJNIEnv()->DeleteGlobalRef((jobject)j_global_object); + }); + n_flowunit_event->SetPrivate(modelbox::jstring2string(env, j_key), priv_ptr); +} + +/* + * Class: com_modelbox_FlowUnitEvent + * Method: FlowUnitEventGet + * Signature: (Ljava/lang/String;)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_com_modelbox_FlowUnitEvent_FlowUnitEventGet( + JNIEnv *env, jobject j_this, jstring j_key) { + if (j_key == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "input argument is null"); + return nullptr; + } + + auto n_flowunit_event = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_flowunit_event == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_object = + n_flowunit_event->GetPrivate(modelbox::jstring2string(env, j_key)); + if (n_object == nullptr) { + return nullptr; + } + + return (jobject)n_object.get(); +} \ No newline at end of file diff --git a/src/java/jni/jni_export/log.cc b/src/java/jni/jni_export/log.cc new file mode 100644 index 000000000..155df9f17 --- /dev/null +++ b/src/java/jni/jni_export/log.cc @@ -0,0 +1,146 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "log.h" + +#include + +#include + +#include "com_modelbox_Log.h" +#include "jni_native_object.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_Log + * Method: LogNew + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_modelbox_Log_LogNew(JNIEnv *env, + jobject j_this) { + return modelbox::JNINativeObject::NewHandle( + j_this, std::make_shared()); +} + +/* + * Class: com_modelbox_Log + * Method: LogSetLogLevel + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Log_LogSetLogLevel(JNIEnv *env, + jobject j_this, + jlong j_level) { + auto n_log = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_log == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_log->SetLogLevel((modelbox::LogLevel)j_level); +} + +/* + * Class: com_modelbox_Log + * Method: LogGetLogLevel + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_modelbox_Log_LogGetLogLevel(JNIEnv *env, + jobject j_this) { + auto n_log = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_log == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return (jlong)modelbox::LogLevel::LOG_OFF; + } + + auto logLevel = n_log->GetLogLevel(); + if (logLevel > modelbox::LogLevel::LOG_OFF) { + return (jlong)modelbox::LogLevel::LOG_OFF; + } + return (jlong)logLevel; +} + +/* + * Class: com_modelbox_Log + * Method: LogGetLogger + * Signature: ()Lcom/modelbox/Log; + */ +JNIEXPORT jobject JNICALL Java_com_modelbox_Log_LogGetLogger(JNIEnv *env, + jclass j_clazz) { + auto n_log = ModelBoxLogger.GetLogger(); + if (n_log == nullptr) { + return nullptr; + } + + auto logger_java = std::dynamic_pointer_cast(n_log); + if (logger_java == nullptr) { + jobject j_log = + modelbox::JNINativeObject::NewJObject(env, "com/modelbox/Log", n_log); + return j_log; + } + + auto *j_log = logger_java->GetJNICaller(); + + return j_log; +} + +/* + * Class: com_modelbox_Log + * Method: LogReg + * Signature: (Lcom/modelbox/Log;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Log_LogReg(JNIEnv *env, jclass j_clazz, + jobject j_log) { + auto n_log = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_log); + if (n_log == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_log->RegJNICaller(env, j_log); + ModelBoxLogger.SetLogger(n_log); +} + +/* + * Class: com_modelbox_Log + * Method: LogUnReg + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Log_LogUnReg(JNIEnv *env, + jclass j_clazz) { + ModelBoxLogger.SetLogger(nullptr); +} + +/* + * Class: com_modelbox_Log + * Method: LogPrint + * Signature: (JLjava/lang/String;ILjava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Log_LogPrint( + JNIEnv *env, jclass j_clazz, jlong j_level, jstring j_file, jint j_lineno, + jstring j_func, jstring j_msg) { + ModelBoxLogger.Print((modelbox::LogLevel)j_level, + modelbox::jstring2string(env, j_file).c_str(), j_lineno, + modelbox::jstring2string(env, j_func).c_str(), "%s", + modelbox::jstring2string(env, j_msg).c_str()); +} diff --git a/src/java/jni/jni_export/native_object.cc b/src/java/jni/jni_export/native_object.cc new file mode 100644 index 000000000..8471d1265 --- /dev/null +++ b/src/java/jni/jni_export/native_object.cc @@ -0,0 +1,34 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +#include "com_modelbox_NativeObject.h" +#include "jni_native_object.h" +#include "throw.h" + +/* + * Class: com_modelbox_NativeObject + * Method: delete_handle + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_NativeObject_delete_1handle( + JNIEnv *env, jobject jself, jlong handle) { + modelbox::JNINativeObject::DeleteHandle(handle); +} diff --git a/src/java/jni/jni_export/session_context.cc b/src/java/jni/jni_export/session_context.cc new file mode 100644 index 000000000..31bd002f5 --- /dev/null +++ b/src/java/jni/jni_export/session_context.cc @@ -0,0 +1,157 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modelbox/session_context.h" + +#include + +#include "com_modelbox_SessionContext.h" +#include "jni_native_object.h" +#include "throw.h" +#include "utils.h" + +/* + * Class: com_modelbox_SessionContext + * Method: SessionContext_SetSessionId + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_SessionContext_SessionContext_1SetSessionId( + JNIEnv *env, jobject j_this, jstring j_session_id) { + auto n_session_context = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_session_context == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_session_context->SetSessionId(modelbox::jstring2string(env, j_session_id)); +} + +/* + * Class: com_modelbox_SessionContext + * Method: SessionContext_GetSessionId + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_modelbox_SessionContext_SessionContext_1GetSessionId(JNIEnv *env, + jobject j_this) { + auto n_session_context = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_session_context == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return env->NewStringUTF(n_session_context->GetSessionId().c_str()); +} + +/* + * Class: com_modelbox_SessionContext + * Method: SessionContext_GetConfiguration + * Signature: ()Lcom/modelbox/Configuration; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_SessionContext_SessionContext_1GetConfiguration( + JNIEnv *env, jobject j_this) { + auto n_session_context = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_session_context == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_config = n_session_context->GetConfig(); + if (n_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "configuration is invalid"); + return nullptr; + } + + auto *j_config = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/Configuration", n_config); + if (j_config == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError, + "configuration is invalid"); + } + return j_config; +} + +/* + * Class: com_modelbox_SessionContext + * Method: SessionContext_SetError + * Signature: (Lcom/modelbox/FlowUnitError;)V + */ +JNIEXPORT void JNICALL +Java_com_modelbox_SessionContext_SessionContext_1SetError(JNIEnv *env, + jobject j_this, + jobject j_error) { + auto n_session_context = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_session_context == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto n_error = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_error); + if (n_error == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "flowunit error is invalid"); + return; + } + + n_session_context->SetError(n_error); +} + +/* + * Class: com_modelbox_SessionContext + * Method: SessionContext_GetError + * Signature: ()Lcom/modelbox/FlowUnitError; + */ +JNIEXPORT jobject JNICALL +Java_com_modelbox_SessionContext_SessionContext_1GetError(JNIEnv *env, + jobject j_this) { + auto n_session_context = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_this); + if (n_session_context == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + auto n_error = n_session_context->GetError(); + if (n_error == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "configuration is invalid"); + return nullptr; + } + + auto *j_error = modelbox::JNINativeObject::NewJObject( + env, "com/modelbox/FlowUnitError", n_error); + if (j_error == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError, + "configuration is invalid"); + } + + return j_error; +} diff --git a/src/java/jni/jni_export/status.cc b/src/java/jni/jni_export/status.cc new file mode 100644 index 000000000..69a7c460e --- /dev/null +++ b/src/java/jni/jni_export/status.cc @@ -0,0 +1,231 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modelbox/base/status.h" + +#include + +#include "com_modelbox_Status.h" +#include "jni_native_object.h" +#include "modelbox/base/utils.h" +#include "throw.h" +#include "utils.h" + +jobject GetJStatusCodeFromStatus(JNIEnv *env, modelbox::Status &status) { + jclass j_cls = env->FindClass("com/modelbox/StatusCode"); + if (j_cls == nullptr) { + modelbox::StatusError = {modelbox::STATUS_INTERNAL, + "Cannot find class StatusCode"}; + return nullptr; + } + + Defer { env->DeleteLocalRef(j_cls); }; + + jfieldID j_field = env->GetStaticFieldID( + j_cls, status.StrStatusCode().c_str(), "Lcom/modelbox/StatusCode;"); + if (j_field == nullptr) { + modelbox::StatusError = {modelbox::STATUS_FAULT, + "Cannot find enum for StatusCode"}; + return nullptr; + } + + jobject j_code = env->GetStaticObjectField(j_cls, j_field); + + return j_code; +} + +/* + * Class: com_modelbox_Status + * Method: StatusNew + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_modelbox_Status_StatusNew(JNIEnv *env, + jobject j_this) { + return modelbox::JNINativeObject::NewHandle( + j_this, std::make_shared()); +} + +/* + * Class: com_modelbox_Status + * Method: StatusSetCode + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Status_StatusSetCode(JNIEnv *env, + jobject j_this, + jlong j_code) { + auto n_status = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_status == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + if (j_code >= modelbox::STATUS_LASTFLAG) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "statuscode is invalid"); + return; + } + + *n_status = (modelbox::StatusCode)j_code; +} + +/* + * Class: com_modelbox_Status + * Method: StatusWrap + * Signature: (Lcom/modelbox/Status;JLjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Status_StatusWrap( + JNIEnv *env, jobject j_this, jobject j_status_other, jlong j_code, + jstring j_message) { + auto n_status = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_status == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + auto n_status_other = + modelbox::JNINativeObject::GetNativeSharedPtr( + env, j_status_other); + if (n_status_other == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + if (j_code >= modelbox::STATUS_LASTFLAG) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "statuscode is invalid"); + return; + } + + n_status->Wrap(*n_status_other, (modelbox::StatusCode)j_code, + modelbox::jstring2string(env, j_message)); +} + +/* + * Class: com_modelbox_Status + * Method: StatusToSting + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_modelbox_Status_StatusToSting(JNIEnv *env, jobject j_this) { + auto n_status = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_status == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return env->NewStringUTF(n_status->ToString().c_str()); +} + +/* + * Class: com_modelbox_Status + * Method: StatusCode + * Signature: ()Lcom/modelbox/StatusCode; + */ +JNIEXPORT jobject JNICALL Java_com_modelbox_Status_StatusCode(JNIEnv *env, + jobject j_this) { + auto n_status = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_status == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + auto *j_code = GetJStatusCodeFromStatus(env, *n_status); + if (j_code == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + } + + return j_code; +} + +/* + * Class: com_modelbox_Status + * Method: StatusStrCode + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_modelbox_Status_StatusStrCode(JNIEnv *env, jobject j_this) { + auto n_status = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_status == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return env->NewStringUTF(n_status->StrCode().c_str()); +} + +/* + * Class: com_modelbox_Status + * Method: StatusSetErrorMsg + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_modelbox_Status_StatusSetErrorMsg( + JNIEnv *env, jobject j_this, jstring j_message) { + auto n_status = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_status == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return; + } + + n_status->SetErrormsg(modelbox::jstring2string(env, j_message)); +} + +/* + * Class: com_modelbox_Status + * Method: StatusErrorMsg + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_modelbox_Status_StatusErrorMsg(JNIEnv *env, jobject j_this) { + auto n_status = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_status == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return env->NewStringUTF(n_status->Errormsg().c_str()); +} + +/* + * Class: com_modelbox_Status + * Method: StatusWrapErrormsgs + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_modelbox_Status_StatusWrapErrormsgs(JNIEnv *env, jobject j_this) { + auto n_status = + modelbox::JNINativeObject::GetNativeSharedPtr(env, + j_this); + if (n_status == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::StatusError); + return nullptr; + } + + return env->NewStringUTF(n_status->WrapErrormsgs().c_str()); +} \ No newline at end of file diff --git a/src/java/jni/jni_native_object.cc b/src/java/jni/jni_native_object.cc new file mode 100644 index 000000000..dd2e0b739 --- /dev/null +++ b/src/java/jni/jni_native_object.cc @@ -0,0 +1,181 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "jni_native_object.h" + +#include "modelbox/base/log.h" +#include "modelbox/base/status.h" + +namespace modelbox { + +JNINativeObject::JNINativeObject(jobject jni_object, + std::shared_ptr native_shared_ptr) + : jni_object_(jni_object), + native_shared_ptr_(std::move(native_shared_ptr)){}; + +JNINativeObject::~JNINativeObject() = default; + +jobject JNINativeObject::GetJObject() { return jni_object_; } + +void JNINativeObject::SetJObject(jobject object) { jni_object_ = object; } + +std::shared_ptr JNINativeObject::GetNativeSharedPtr() { + return native_shared_ptr_; +} + +Status JNINativeObject::SetNativeSharedPtr( + JNIEnv *env, jlong handle, const std::shared_ptr &native_shared_ptr) { + Status ret = STATUS_SUCCESS; + auto *native_object = FromHandle(handle); + if (native_object == nullptr) { + return {STATUS_INVALID, "handle is invalid"}; + } + + native_object->SetNativeSharedPtr(native_shared_ptr); + return ret; +} + +Status JNINativeObject::SetNativeSharedPtr( + JNIEnv *env, jobject object, const std::shared_ptr &native_shared_ptr, + const char *member) { + Status ret = STATUS_SUCCESS; + auto *native_object = FromJObject(env, object, member); + if (native_object == nullptr) { + return modelbox::StatusError; + } + + native_object->SetNativeSharedPtr(native_shared_ptr); + return ret; +} + +void JNINativeObject::SetNativeSharedPtr( + std::shared_ptr native_shared_ptr) { + native_shared_ptr_ = std::move(native_shared_ptr); +} + +JNINativeObject *JNINativeObject::FromHandle(jlong handle) { + return reinterpret_cast(handle); +} + +JNINativeObject *JNINativeObject::FromJObject(JNIEnv *env, jobject object, + const char *member) { + if (env == nullptr || object == nullptr) { + std::string errmsg = "get jni native from object failed, invalid argument"; + StatusError = {STATUS_INVALID, errmsg}; + return nullptr; + } + + jclass cls = env->GetObjectClass(object); + if (cls == nullptr) { + std::string errmsg = "get object class failed."; + StatusError = {STATUS_INVALID, errmsg}; + return nullptr; + } + Defer { env->DeleteLocalRef(cls); }; + + jfieldID ptrField = env->GetFieldID(cls, member, "J"); + if (ptrField == nullptr) { + std::string errmsg = "not a modelbox object, not extends from NativeObject"; + StatusError = {STATUS_INVALID, errmsg}; + return nullptr; + } + + auto handle = (jlong)env->GetLongField(object, ptrField); + if (handle == 0) { + std::string errmsg = "native handler is invalid"; + StatusError = {STATUS_INVALID, errmsg}; + return nullptr; + } + + auto *native_object = FromHandle(handle); + if (native_object == nullptr) { + return nullptr; + } + + return native_object; +} + +jlong JNINativeObject::NewHandle( + jobject object, const std::shared_ptr &native_shared_ptr) { + auto *native_object = new JNINativeObject(object, native_shared_ptr); + return (jlong)native_object; +} + +jobject JNINativeObject::NewJObject( + JNIEnv *env, const char *clazz, + const std::shared_ptr &native_shared_ptr, const char *member) { + jclass cls = env->FindClass(clazz); + if (cls == nullptr) { + StatusError = {STATUS_INVALID, "cannot find class " + std::string(clazz)}; + return nullptr; + } + Defer { env->DeleteLocalRef(cls); }; + + auto *cls_constructor = env->GetMethodID(cls, "", "()V"); + if (cls_constructor == nullptr) { + std::string errmsg = + "cannot find constructor for " + std::string(clazz) + "."; + modelbox::StatusError = {modelbox::STATUS_INVALID, errmsg}; + } + + jobject object = env->NewObject(cls, cls_constructor); + if (object == nullptr) { + std::string errmsg = "new object for " + std::string(clazz) + " failed."; + modelbox::StatusError = {modelbox::STATUS_NOMEM, errmsg}; + return nullptr; + } + + jfieldID ptrField = env->GetFieldID(cls, member, "J"); + if (ptrField == nullptr) { + std::string errmsg = + "not a modelbox class, not extends from NativeObject, "; + errmsg += "class: " + std::string(clazz); + modelbox::StatusError = {modelbox::STATUS_INVALID, errmsg}; + env->DeleteLocalRef(object); + return nullptr; + } + + jlong oldptr = env->GetLongField(object, ptrField); + if (oldptr != 0) { + DeleteHandle(oldptr); + } + + auto native_object = NewHandle(object, native_shared_ptr); + env->SetLongField(object, ptrField, native_object); + return object; +} + +void JNINativeObject::DeleteHandle(jlong handle) { + auto *native_object = FromHandle(handle); + if (native_object == nullptr) { + return; + } + + delete native_object; +} + +void JNINativeObject::DeleteJObject(JNIEnv *env, jobject object, + const char *member) { + auto *native_object = FromJObject(env, object, member); + if (native_object == nullptr) { + return; + } + + delete native_object; +} + +} // namespace modelbox \ No newline at end of file diff --git a/src/java/jni/jni_native_object.h b/src/java/jni/jni_native_object.h new file mode 100644 index 000000000..9fd2a26e6 --- /dev/null +++ b/src/java/jni/jni_native_object.h @@ -0,0 +1,106 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODELBOX_JNI_BIND_H_ +#define MODELBOX_JNI_BIND_H_ + +#include + +#include +#include + +#include "modelbox/base/status.h" + +namespace modelbox { + +constexpr const char *NATIVE_HANDLER_MEMBER_NAME = "native_handle"; + +class JNINativeObject { + public: + JNINativeObject(jobject jni_object, std::shared_ptr native_shared_ptr); + virtual ~JNINativeObject(); + + jobject GetJObject(); + + void SetJObject(jobject object); + + std::shared_ptr GetNativeSharedPtr(); + + template + inline std::shared_ptr GetNativeSharedPtr() { + return std::static_pointer_cast(GetNativeSharedPtr()); + } + + static jlong NewHandle(jobject object, + const std::shared_ptr &native_shared_ptr); + + static void DeleteHandle(jlong handle); + + static jobject NewJObject(JNIEnv *env, const char *clazz, + const std::shared_ptr &native_shared_ptr, + const char *member = NATIVE_HANDLER_MEMBER_NAME); + + static void DeleteJObject(JNIEnv *env, jobject object, + const char *member = NATIVE_HANDLER_MEMBER_NAME); + + template + inline static std::shared_ptr GetNativeSharedPtr(jlong handle) { + auto native_object = FromHandle(handle); + if (native_object == nullptr) { + return nullptr; + } + + return native_object->GetNativeSharedPtr(); + } + + template + inline static std::shared_ptr GetNativeSharedPtr( + JNIEnv *env, jobject object, + const char *member = NATIVE_HANDLER_MEMBER_NAME) { + auto native_object = FromJObject(env, object, member); + if (native_object == nullptr) { + return nullptr; + } + + return native_object->GetNativeSharedPtr(); + } + + static Status SetNativeSharedPtr( + JNIEnv *env, jlong handle, + const std::shared_ptr &native_shared_ptr); + + static Status SetNativeSharedPtr( + JNIEnv *env, jobject object, + const std::shared_ptr &native_shared_ptr, + const char *member = NATIVE_HANDLER_MEMBER_NAME); + + private: + JNINativeObject() = default; + void SetNativeSharedPtr(std::shared_ptr native_shared_ptr); + + static JNINativeObject *FromHandle(jlong handle); + + static JNINativeObject *FromJObject( + JNIEnv *env, jobject object, + const char *member = NATIVE_HANDLER_MEMBER_NAME); + + jobject jni_object_; + std::shared_ptr native_shared_ptr_; +}; + +} // namespace modelbox + +#endif // MODELBOX_JNI_BIND_H_ diff --git a/src/java/jni/log.cc b/src/java/jni/log.cc index ba5f8df89..601cf04fc 100644 --- a/src/java/jni/log.cc +++ b/src/java/jni/log.cc @@ -1,63 +1,104 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "log.h" +#include "scoped_jvm.h" +#include "throw.h" + namespace modelbox { -LoggerJava::LoggerJava() {} -LoggerJava::~LoggerJava() { UnReg(); } +LoggerJava::LoggerJava() = default; +LoggerJava::~LoggerJava() { + modelbox::ScopedJvm scope; + UnReg(scope.GetJNIEnv()); +} void LoggerJava::Print(LogLevel level, const char *file, int lineno, const char *func, const char *msg) { - auto jfile = env_->NewStringUTF(file); + modelbox::ScopedJvm scope; + auto *env = scope.GetJNIEnv(); + if (env == nullptr) { + return; + } + auto *jfile = env->NewStringUTF(file); auto jlineno = (jint)lineno; - auto jfunc = env_->NewStringUTF(func); - auto jmsg = env_->NewStringUTF(msg); - env_->CallObjectMethod(logger_, log_mid_, (jlong)level, jfile, jlineno, jfunc, - jmsg); - env_->DeleteLocalRef(jfile); - env_->DeleteLocalRef(jfunc); - env_->DeleteLocalRef(jmsg); + auto *jfunc = env->NewStringUTF(func); + auto *jmsg = env->NewStringUTF(msg); + env->CallObjectMethod(logger_, log_mid_, (jlong)level, jfile, jlineno, jfunc, + jmsg); + env->DeleteLocalRef(jfile); + env->DeleteLocalRef(jfunc); + env->DeleteLocalRef(jmsg); } +jobject LoggerJava::GetJNICaller() { return logger_; } + void LoggerJava::RegJNICaller(JNIEnv *env, jobject logger) { - env_ = env; - logger_ = env->NewGlobalRef(logger); - jclass cls = env->GetObjectClass(logger_); + UnReg(env); + jclass cls = env->GetObjectClass(logger); + if (cls == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "logger class is not found."); + return; + } + + Defer { env->DeleteLocalRef(cls); }; + jmethodID mid = env->GetMethodID( cls, "jniPrintCallback", "(JLjava/lang/String;ILjava/lang/String;Ljava/lang/String;)V"); - log_mid_ = mid; + if (mid == nullptr) { + modelbox::ModelBoxJNIThrow(env, modelbox::STATUS_INVALID, + "no print callback function found."); + return; + } - env->DeleteLocalRef(cls); + logger_ = env->NewGlobalRef(logger); + log_mid_ = mid; } -void LoggerJava::UnReg() { - if (env_ == nullptr) { +void LoggerJava::UnReg(JNIEnv *env) { + if (logger_ == nullptr) { return; } - env_->DeleteLocalRef(logger_); + env->DeleteLocalRef(logger_); logger_ = nullptr; - env_ = nullptr; + log_mid_ = nullptr; } void LoggerJava::SetLogLevel(LogLevel level) { level_ = level; } LogLevel LoggerJava::GetLogLevel() { return level_; } -LoggerJavaWapper::LoggerJavaWapper() {} +LoggerJavaWapper::LoggerJavaWapper() = default; LoggerJavaWapper::~LoggerJavaWapper() { ModelBoxLogger.SetLogger(nullptr); } -void LoggerJavaWapper::RegLogFunc(std::string pylog) { +void LoggerJavaWapper::RegLogFunc(const std::string &pylog) { ModelBoxLogger.SetLogger(logger_java_); } -const std::shared_ptr LoggerJavaWapper::GetLogger() { +std::shared_ptr LoggerJavaWapper::GetLogger() { return ModelBoxLogger.GetLogger(); } -void LoggerJavaWapper::SetLogger(std::shared_ptr logger) { +void LoggerJavaWapper::SetLogger(const std::shared_ptr &logger) { ModelBoxLogger.SetLogger(logger); } diff --git a/src/java/jni/log.h b/src/java/jni/log.h index 8d0b5d02e..a5d74bd2c 100644 --- a/src/java/jni/log.h +++ b/src/java/jni/log.h @@ -17,31 +17,32 @@ #ifndef MODELBOX_JAVA_LIB_LOG_H_ #define MODELBOX_JAVA_LIB_LOG_H_ -#include #include +#include namespace modelbox { class LoggerJava : public Logger { public: LoggerJava(); - virtual ~LoggerJava(); + ~LoggerJava() override; - virtual void Print(LogLevel level, const char *file, int lineno, - const char *func, const char *msg); + void Print(LogLevel level, const char *file, int lineno, const char *func, + const char *msg) override; void RegJNICaller(JNIEnv *env, jobject logger); - void UnReg(); + jobject GetJNICaller(); - void SetLogLevel(LogLevel level); + void UnReg(JNIEnv *env); + + void SetLogLevel(LogLevel level) override; - virtual LogLevel GetLogLevel(); + LogLevel GetLogLevel() override; private: - JNIEnv *env_; - jobject logger_; - jmethodID log_mid_; + jobject logger_{nullptr}; + jmethodID log_mid_{nullptr}; LogLevel level_{LOG_OFF}; }; @@ -50,13 +51,13 @@ class LoggerJavaWapper { LoggerJavaWapper(); virtual ~LoggerJavaWapper(); - void RegLogFunc(std::string pylog); + void RegLogFunc(const std::string &pylog); void SetLogLevel(LogLevel level); - const std::shared_ptr GetLogger(); + std::shared_ptr GetLogger(); - void SetLogger(std::shared_ptr logger); + void SetLogger(const std::shared_ptr &logger); void PrintExt(LogLevel level, const char *file, int lineno, const char *func, const char *msg); diff --git a/src/java/jni/modelbox.cc b/src/java/jni/modelbox.cc deleted file mode 100644 index 105614a48..000000000 --- a/src/java/jni/modelbox.cc +++ /dev/null @@ -1,162 +0,0 @@ - -/* - * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "modelbox.h" - -#include -#include - -#include - -#include "com_modelbox_ModelBoxJni.h" -#include "log.h" -#include "utils.h" - -/* - * Class: com_modelbox_ModelBoxJni - * Method: FlowNew - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_com_modelbox_ModelBoxJni_FlowNew(JNIEnv *env, - jclass clazz) { - std::shared_ptr *pflow = new std::shared_ptr; - *pflow = std::make_shared(); - return reinterpret_cast(pflow); -} - -/* - * Class: com_modelbox_ModelBoxJni - * Method: FlowFree - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_com_modelbox_ModelBoxJni_FlowFree(JNIEnv *env, - jclass clazz, - jlong flow) { - std::shared_ptr *pflow = - reinterpret_cast *>(flow); - delete pflow; -} - -/* - * Class: com_modelbox_ModelBoxJni - * Method: FlowInit - * Signature: (JLjava/lang/String;Ljava/lang/String;)V - */ -JNIEXPORT void JNICALL Java_com_modelbox_ModelBoxJni_FlowInit( - JNIEnv *env, jclass clazz, jlong flow, jstring jname, jstring jgraph) { - auto name = jstring2string(env, jname); - auto graph = jstring2string(env, jgraph); - - std::shared_ptr *pflow = - reinterpret_cast *>(flow); - auto ret = (*pflow)->Init(name, graph); -} - -/* - * Class: com_modelbox_ModelBoxJni - * Method: FlowBuild - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_com_modelbox_ModelBoxJni_FlowBuild(JNIEnv *env, - jclass clazz, - jlong flow) { - std::shared_ptr *pflow = - reinterpret_cast *>(flow); - auto ret = (*pflow)->Build(); -} - -/* - * Class: com_modelbox_ModelBoxJni - * Method: LogNew - * Signature: ()J - */ -JNIEXPORT jlong JNICALL Java_com_modelbox_ModelBoxJni_LogNew(JNIEnv *env, - jclass clazz) { - std::shared_ptr *plog = - new std::shared_ptr; - *plog = std::make_shared(); - return reinterpret_cast(plog); -} - -/* - * Class: com_modelbox_ModelBoxJni - * Method: LogFree - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_com_modelbox_ModelBoxJni_LogFree(JNIEnv *env, - jclass clazz, - jlong jlog) { - std::shared_ptr *plog = - reinterpret_cast *>(jlog); - delete plog; -} - -/* - * Class: com_modelbox_ModelBoxJni - * Method: SetLogLevel - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL Java_com_modelbox_ModelBoxJni_SetLogLevel(JNIEnv *env, - jclass clazz, - jlong jlog, - jlong jlevel) { - std::shared_ptr *plog = - reinterpret_cast *>(jlog); - (*plog)->SetLogLevel((modelbox::LogLevel)jlevel); -} - -/* - * Class: com_modelbox_ModelBoxJni - * Method: LogReg - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_com_modelbox_ModelBoxJni_LogReg(JNIEnv *env, - jclass clazz, - jobject jlog) { - jclass cls = env->GetObjectClass(jlog); - jmethodID mid = env->GetMethodID(cls, "getLogPtr", "()J"); - jobject result = env->CallObjectMethod(jlog, mid); - std::shared_ptr *plog = - reinterpret_cast *>(result); - - (*plog)->RegJNICaller(env, jlog); - ModelBoxLogger.SetLogger(*plog); -} - -/* - * Class: com_modelbox_ModelBoxJni - * Method: LogUnReg - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_com_modelbox_ModelBoxJni_LogUnReg(JNIEnv *env, - jclass clazz) { - ModelBoxLogger.SetLogger(nullptr); - } - -/* - * Class: com_modelbox_ModelBoxJni - * Method: LogPrint - * Signature: (JLjava/lang/String;ILjava/lang/String;Ljava/lang/String;)V - */ -JNIEXPORT void JNICALL Java_com_modelbox_ModelBoxJni_LogPrint( - JNIEnv *env, jclass clazz, jlong jlevel, jstring jfile, jint jlineno, - jstring jfunc, jstring jmsg) { - ModelBoxLogger.Print((modelbox::LogLevel)jlevel, - jstring2string(env, jfile).c_str(), jlineno, - jstring2string(env, jfunc).c_str(), "%s", - jstring2string(env, jmsg).c_str()); -} \ No newline at end of file diff --git a/src/java/jni/modelbox_jni.cc b/src/java/jni/modelbox_jni.cc new file mode 100644 index 000000000..561d83e8e --- /dev/null +++ b/src/java/jni/modelbox_jni.cc @@ -0,0 +1,35 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "modelbox_jni.h" + +#include "scoped_jvm.h" + +JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { + JNIEnv *env; + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_8) != JNI_OK) { + return JNI_ERR; + } + + modelbox::ScopedJvm::SetJavaVM(vm); + + return JNI_VERSION_1_8; +} + +JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { + modelbox::ScopedJvm::SetJavaVM(nullptr); +} diff --git a/src/java/jni/modelbox.h b/src/java/jni/modelbox_jni.h similarity index 100% rename from src/java/jni/modelbox.h rename to src/java/jni/modelbox_jni.h diff --git a/src/java/jni/scoped_jvm.cc b/src/java/jni/scoped_jvm.cc new file mode 100644 index 000000000..ff3a57dda --- /dev/null +++ b/src/java/jni/scoped_jvm.cc @@ -0,0 +1,69 @@ + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scoped_jvm.h" + +#include + +#include "modelbox/base/log.h" + +namespace modelbox { + +JavaVM *ScopedJvm::jvm_; + +JavaVM *ScopedJvm::GetJavaVM() { return jvm_; } + +void ScopedJvm::SetJavaVM(JavaVM *vm) { jvm_ = vm; } + +ScopedJvm::ScopedJvm() { + JNIEnv *env = nullptr; + if (jvm_ == nullptr) { + throw std::runtime_error("jvm pointer is not set"); + return; + } + + auto ret = jvm_->GetEnv((void **)&env, JNI_VERSION_1_6); + if (ret == JNI_OK) { + env_ = env; + return; + } + + ret = jvm_->AttachCurrentThread((void **)&env, nullptr); + if (ret != JNI_OK) { + throw std::runtime_error("Attach jvm thread failed."); + return; + } + + env_ = env; + do_attach_ = true; +} + +ScopedJvm::~ScopedJvm() { + if (jvm_ == nullptr) { + return; + } + + if (do_attach_ == true) { + jvm_->DetachCurrentThread(); + } + + env_ = nullptr; +} + +JNIEnv *ScopedJvm::GetJNIEnv() { return env_; } + +} // namespace modelbox \ No newline at end of file diff --git a/src/java/jni/scoped_jvm.h b/src/java/jni/scoped_jvm.h new file mode 100644 index 000000000..263514fd5 --- /dev/null +++ b/src/java/jni/scoped_jvm.h @@ -0,0 +1,42 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODELBOX_SCOPED_JVM_H_ +#define MODELBOX_SCOPED_JVM_H_ + +#include + +namespace modelbox { + +class ScopedJvm { + public: + ScopedJvm(); + virtual ~ScopedJvm(); + + JNIEnv *GetJNIEnv(); + + static JavaVM *GetJavaVM(); + + static void SetJavaVM(JavaVM *vm); + + private: + static JavaVM *jvm_; + bool do_attach_{false}; + JNIEnv *env_{nullptr}; +}; +} // namespace modelbox + +#endif // MODELBOX_SCOPED_JVM_H_ diff --git a/src/java/jni/throw.cc b/src/java/jni/throw.cc new file mode 100644 index 000000000..121fbd829 --- /dev/null +++ b/src/java/jni/throw.cc @@ -0,0 +1,115 @@ + + +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "throw.h" + +#include "modelbox/base/log.h" +#include "modelbox/base/status.h" +#include "modelbox_jni.h" + +namespace modelbox { + +const char *kModelBoxExceptionCodeMap[] = { + "com/modelbox/ModelBoxException$Success", + "com/modelbox/ModelBoxException$Fault", + "com/modelbox/ModelBoxException$Notfound", + "com/modelbox/ModelBoxException$Invalid", + "com/modelbox/ModelBoxException$Again", + "com/modelbox/ModelBoxException$Badconf", + "com/modelbox/ModelBoxException$Nomem", + "com/modelbox/ModelBoxException$Range", + "com/modelbox/ModelBoxException$Exist", + "com/modelbox/ModelBoxException$Internal", + "com/modelbox/ModelBoxException$Busy", + "com/modelbox/ModelBoxException$Permit", + "com/modelbox/ModelBoxException$Notsupport", + "com/modelbox/ModelBoxException$Nodata", + "com/modelbox/ModelBoxException$Nospace", + "com/modelbox/ModelBoxException$Nobufs", + "com/modelbox/ModelBoxException$Overflow", + "com/modelbox/ModelBoxException$Inprogress", + "com/modelbox/ModelBoxException$Already", + "com/modelbox/ModelBoxException$Timedout", + "com/modelbox/ModelBoxException$Nostream", + "com/modelbox/ModelBoxException$Reset", + "com/modelbox/ModelBoxException$Continue", + "com/modelbox/ModelBoxException$Edquot", + "com/modelbox/ModelBoxException$Stop", + "com/modelbox/ModelBoxException$Shutdown", + "com/modelbox/ModelBoxException$Eof", + "com/modelbox/ModelBoxException$Noent", + "com/modelbox/ModelBoxException$Deadlock", + "com/modelbox/ModelBoxException$Noresponse", + "com/modelbox/ModelBoxException$Io", +}; + +static void do_jni_throw(JNIEnv *env, const char *except_name, + const char *message) { + jclass ecls = env->FindClass(except_name); + + if (ecls == nullptr) { + ecls = env->FindClass("java/lang/RuntimeException"); + message = "Modelbox: cannot find exception"; + if (ecls == nullptr) { + MBLOG_ERROR << "Modelbox-JNI: Failed to throw exception"; + return; + } + } + + Defer { env->DeleteLocalRef(ecls); }; + int ret = env->ThrowNew(ecls, message); + if (ret < 0) { + MBLOG_ERROR << "Modelbox-JNI: Fatal Error"; + } +} + +void ModelBoxJNIThrow(JNIEnv *env, Status &status) { + ModelBoxJNIThrow(env, status.Code(), status.WrapErrormsgs()); +} + +void ModelBoxJNIThrow(JNIEnv *env, StatusCode code, + const std::string &errormsg) { + if (code == STATUS_OK) { + return; + } + + if (code >= sizeof(kModelBoxExceptionCodeMap) / sizeof(char *)) { + do_jni_throw(env, "java/lang/RuntimeException", + "Modelbox: Status is invalid."); + return; + } + + do_jni_throw(env, kModelBoxExceptionCodeMap[code], errormsg.c_str()); +} + +void ModelBoxJNIThrow(JNIEnv *env, const char *runtime_exception, + const char *errmsg) { + do_jni_throw(env, runtime_exception, errmsg); +} + +std::string ModelboxExceptionMsg(JNIEnv *env) { + auto *j_throw = env->ExceptionOccurred(); + if (j_throw == nullptr) { + return ""; + } + + // TODO + return ""; +} + +} // namespace modelbox \ No newline at end of file diff --git a/src/java/jni/throw.h b/src/java/jni/throw.h new file mode 100644 index 000000000..9f8934984 --- /dev/null +++ b/src/java/jni/throw.h @@ -0,0 +1,44 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODELBOX_JNI_THROW_H_ +#define MODELBOX_JNI_THROW_H_ + +#include + +#include "modelbox/base/status.h" + +namespace modelbox { + +constexpr const char *JNIEXCEPT_NullPointer = "java/lang/NullPointerException"; +constexpr const char *JNIEXCEPT_OutOfMemoryError = "java/lang/OutOfMemoryError"; +constexpr const char *JNIEXCEPT_RuntimeException = "java/lang/RuntimeException"; +constexpr const char *JNIEXCEPT_IllegalArgumentException = + "java/lang/IllegalArgumentException"; + +void ModelBoxJNIThrow(JNIEnv *env, StatusCode code, + const std::string &errormsg); + +void ModelBoxJNIThrow(JNIEnv *env, Status &status); + +void ModelBoxJNIThrow(JNIEnv *env, const char *runtime_exception, + const char *errmsg); + +std::string ModelboxExceptionMsg(JNIEnv *env); + +} // namespace modelbox + +#endif // MODELBOX_JNI_THROW_H_ diff --git a/src/java/jni/utils.cc b/src/java/jni/utils.cc index c2e657641..e13ae5f77 100644 --- a/src/java/jni/utils.cc +++ b/src/java/jni/utils.cc @@ -16,19 +16,23 @@ #include "utils.h" +#include "modelbox/base/log.h" + +namespace modelbox { + std::string jstring2string(JNIEnv *env, jstring jStr) { if (!jStr) { return ""; } - const jclass stringClass = env->GetObjectClass(jStr); - const jmethodID getBytes = + jclass stringClass = env->GetObjectClass(jStr); + jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B"); - const jbyteArray stringJbytes = (jbyteArray)env->CallObjectMethod( + auto *const stringJbytes = (jbyteArray)env->CallObjectMethod( jStr, getBytes, env->NewStringUTF("UTF-8")); - size_t length = (size_t)env->GetArrayLength(stringJbytes); - jbyte *pBytes = env->GetByteArrayElements(stringJbytes, NULL); + auto length = (size_t)env->GetArrayLength(stringJbytes); + jbyte *pBytes = env->GetByteArrayElements(stringJbytes, nullptr); std::string ret = std::string((char *)pBytes, length); env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT); @@ -37,3 +41,5 @@ std::string jstring2string(JNIEnv *env, jstring jStr) { env->DeleteLocalRef(stringClass); return ret; } + +} // namespace modelbox diff --git a/src/java/jni/utils.h b/src/java/jni/utils.h index 0aea87b2e..139096a4c 100644 --- a/src/java/jni/utils.h +++ b/src/java/jni/utils.h @@ -18,8 +18,16 @@ #define MODELBOX_JNI_UTILS_H_ #include + +#include #include +#include "modelbox/base/status.h" + +namespace modelbox { + std::string jstring2string(JNIEnv *env, jstring jStr); +} // namespace modelbox + #endif // MODELBOX_JNI_UTILS_H_ diff --git a/src/java/pom.xml b/src/java/pom.xml index f2078a3c7..9f352d21e 100644 --- a/src/java/pom.xml +++ b/src/java/pom.xml @@ -6,8 +6,8 @@ 1.0.0 - 1.7 - 1.7 + 1.8 + 1.8 ${project.basedir}/target @@ -31,9 +31,10 @@ junit junit - 4.12 + 4.13.2 test + org.json json @@ -41,4 +42,4 @@ test - \ No newline at end of file + diff --git a/src/java/src/main/java/com/modelbox/Buffer.java b/src/java/src/main/java/com/modelbox/Buffer.java new file mode 100644 index 000000000..8f0fc206b --- /dev/null +++ b/src/java/src/main/java/com/modelbox/Buffer.java @@ -0,0 +1,136 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + +/** + * Modelbox Buffer + */ +public class Buffer extends NativeObject { + private Buffer() { + + } + + /** + * Build buffer by size + * @param size + */ + public void build(long size) throws ModelBoxException { + BufferBuild(size); + } + + /** + * build buffer from bytes[] + * @param data + */ + public void build(byte[] data) throws ModelBoxException { + BufferBuild(data); + } + + /** + * get bytes[] from buffer + * @return + */ + public byte[] getData() throws ModelBoxException { + return BufferGetData(); + } + + /* + * Any error on buffer + */ + public boolean hasError() { + return BufferHasError(); + } + + /** + * Set error to buffer + * @param code error code + * @param message error message + */ + public void setError(String code, String message) throws ModelBoxException { + BufferSetError(code, message); + } + + /** + * Get error code + * @return error code + */ + public String getErrorCode() { + return BufferGetErrorCode(); + } + + /** + * Get error message + * @return error message + */ + public String getErrorMsg() { + return BufferGetErrorMsg(); + } + + /** + * Get buffer length in byte + * @return + */ + public long getBytes() { + return BufferGetBytes(); + } + + /** + * Copy meta from another buffer + * @param buffer another buffer + * @param isOverWrite overwrite exist meta + * @throws ModelBoxException + */ + public void copyMeta(Buffer buffer, boolean isOverWrite) throws ModelBoxException { + BufferCopyMeta(buffer, isOverWrite); + } + + /** + * Copy meta from anoter buffer + * @param buffer another meta + */ + public void copyMeta(Buffer buffer) { + BufferCopyMeta(buffer, false); + } + + /** + * Get buffer device + * @return + */ + public Device getDevice() { + return BufferGetDevice(); + } + + private native void BufferBuild(long size); + + private native void BufferBuild(byte[] data); + + private native byte[] BufferGetData(); + + private native boolean BufferHasError(); + + private native void BufferSetError(String code, String message); + + private native String BufferGetErrorCode(); + + private native String BufferGetErrorMsg(); + + private native long BufferGetBytes(); + + private native void BufferCopyMeta(Buffer buffer, boolean isOverWrite); + + private native Device BufferGetDevice(); +} diff --git a/src/java/src/main/java/com/modelbox/BufferList.java b/src/java/src/main/java/com/modelbox/BufferList.java new file mode 100644 index 000000000..34d6b5995 --- /dev/null +++ b/src/java/src/main/java/com/modelbox/BufferList.java @@ -0,0 +1,157 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + + +import java.util.Iterator; + +/** + * Modelbox Bufferlist + */ + +public class BufferList extends NativeObject implements Iterable { + + class BufferListIterator implements Iterator { + + @Override + public boolean hasNext() { + if (index < bufferList.size()) { + return true; + } + return false; + } + + @Override + public Buffer next() { + Buffer buff = bufferList.at(index); + index++; + return buff; + } + + protected void SetBufferList(BufferList list) { + this.bufferList = list; + } + + private BufferList bufferList; + int index = 0; + } + + public Iterator iterator() { + BufferListIterator itr = new BufferListIterator(); + itr.SetBufferList(this); + return itr; + } + + /** + * modelbox buffer list. + * Create Bufferlist from external data map + */ + private BufferList() { + + } + + /** + * @brief Builder buffer, create memory + * @param sizeList buffer size list + */ + public void build(int[] sizeList) { + BufferListBuild(sizeList); + } + + /** + * @brief Get buffer at index + * @param index position of buffer + * @return buffer + */ + public Buffer at(long index) { + return BufferListAt(index); + } + + /** + * @brief Get number of buffer in bufferlist + * @return number of buffer + */ + public long size() { + return BufferListSize(); + } + + /** + * @brief Push new buffer to buffer list + * @param buffer pointer to buffer + */ + public void pushBack(Buffer buffer) { + BufferListPushBack(buffer); + } + + /** + * @brief Push new data to buffer list + * @param data pointer to data + */ + public void pushBack(byte[] data) { + BufferListPushBack(data); + } + + /** + * @brief Assign buffer list + * @param buffers buffer list to assign + */ + public void assign(Buffer[] buffers) { + BufferListAssign(buffers); + } + + /** + * @brief Get buffer data pointer from begining + * @return buffer data pointer from begining + */ + public byte[] getData() { + return BufferListGetData(); + } + + /** + * @brief Get device of buffer list + * @return pointer to device + */ + public Device getDevice() { + return BufferListGetDevice(); + } + + /** + * @brief Reset buffer list + * @return reset result + */ + public void reset() { + BufferListReset(); + } + + private native void BufferListBuild(int[] sizeList); + + private native Buffer BufferListAt(long index); + + private native long BufferListSize(); + + private native void BufferListPushBack(Buffer buffer); + + private native void BufferListPushBack(byte[] data); + + private native void BufferListAssign(Buffer[] buffers); + + private native byte[] BufferListGetData(); + + private native Device BufferListGetDevice(); + + private native void BufferListReset(); +} diff --git a/src/java/src/main/java/com/modelbox/Configuration.java b/src/java/src/main/java/com/modelbox/Configuration.java new file mode 100644 index 000000000..e0f91f95b --- /dev/null +++ b/src/java/src/main/java/com/modelbox/Configuration.java @@ -0,0 +1,193 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + +import java.util.ArrayList; + +/** + * modelbox Configuration + */ +public class Configuration extends NativeObject { + public Configuration() { + setNativeHandle(ConfigurationNew()); + } + + /** + * Parser configuration from file + * @param file toml or json file + * @throws ModelBoxException + */ + public void Parser(String file) throws ModelBoxException { + ConfigurationParser(file); + } + + /** + * Get boolean key + * @param key + * @return + */ + public boolean getBoolean(String key, boolean defaultValue) { + return ConfigurationGetBoolean(key, defaultValue); + } + + /** + * Get int key + * @param key + * @return + */ + public int getInt(String key, int defaultValue) { + return ConfigurationGetInt(key, defaultValue); + } + + /** + * Get long key + * @param key + * @return + */ + public long getLong(String key, long defaultValue) { + return ConfigurationGetLong(key, defaultValue); + } + + /** + * Get String key + * @param key + * @return + */ + public String getString(String key, String defaultValue) { + return ConfigurationGetString(key, defaultValue); + } + + /** + * Get float key + * @param key + * @return + */ + public float getFloat(String key, float defaultValue) { + return ConfigurationGetFloat(key, defaultValue); + } + + /** + * Get double key + * @param key + * @return + */ + public double getDouble(String key, double defaultValue) { + return ConfigurationGetDouble(key, defaultValue); + } + + /** + * Set boolean key + * @param key + * @param value + */ + public void set(String key, boolean value) { + ConfigurationSet(key, value); + } + + /** + * Set int key + */ + public void set(String key, int value) { + ConfigurationSet(key, value); + } + + /** + * Set long key + */ + public void set(String key, long value) { + ConfigurationSet(key, value); + } + + + /** + * Set float key + * @param key + * @param value + */ + public void set(String key, float value) { + ConfigurationSet(key, value); + } + + /** + * Set double key + * @param key + * @param value + */ + public void set(String key, double value) { + ConfigurationSet(key, value); + } + + /** + * Set string key + * @param key + * @param value + */ + public void set(String key, String value) { + ConfigurationSet(key, value); + } + + /** + * Get string array by key + * @param key + * @return + */ + public ArrayList getStrings(String key, ArrayList defaultValues) { + return ConfigurationGetStrings(key, defaultValues); + } + + /** + * set string array + * @param key + * @param values + */ + public void set(String key, ArrayList values) { + ConfigurationSet(key, values); + } + + private native boolean ConfigurationGetBoolean(String key, boolean defaultValue); + + private native int ConfigurationGetInt(String key, int defaultValue); + + private native long ConfigurationGetLong(String key, long defaultValue); + + private native String ConfigurationGetString(String key, String defaultValue); + + private native float ConfigurationGetFloat(String key, float defaultValue); + + private native double ConfigurationGetDouble(String key, double defaultValue); + + private native void ConfigurationSet(String key, boolean value); + + private native void ConfigurationSet(String key, int value); + + private native void ConfigurationSet(String key, long value); + + private native void ConfigurationSet(String key, float value); + + private native void ConfigurationSet(String key, double value); + + private native void ConfigurationSet(String key, String value); + + private native ArrayList ConfigurationGetStrings(String key, + ArrayList defaultValue); + + private native void ConfigurationSet(String key, ArrayList values); + + private native void ConfigurationParser(String file); + + private native long ConfigurationNew(); +} diff --git a/src/java/src/main/java/com/modelbox/DataContext.java b/src/java/src/main/java/com/modelbox/DataContext.java new file mode 100644 index 000000000..ed3327419 --- /dev/null +++ b/src/java/src/main/java/com/modelbox/DataContext.java @@ -0,0 +1,149 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + +public class DataContext extends NativeObject { + private DataContext() { + + } + + /** + * Get input port bufferlist + * @param portName port name + * @return BufferList + */ + public BufferList input(String portName) { + return DataContext_Input(portName); + } + + /** + * Get output port bufferlist + * @param portName port name + * @return BufferList + */ + public BufferList output(String portName) { + return DataContext_Output(portName); + } + + /** + * Get external port bufferlist + * @return BufferList + */ + public BufferList external() { + return DataContext_External(); + } + + /** + * Has error + * @return boolean + */ + public boolean hasError() { + return DataContext_HasError(); + } + + /** + * Send event to flowunit + * @param event + */ + public void sendEvent(FlowUnitEvent event) { + DataContext_SendEvent(event); + } + + /** + * Set private + * @param key private key + * @param priv private object + */ + public void setPrivate(String key, Object priv) { + DataContext_SetPrivate(key, priv); + } + + /** + * Get private + * @param key private key + * @return object + */ + public Object getPrivate(String key) { + return DataContext_GetPrivate(key); + } + + /** + * Get input meta + * @param portName portname + * @return data meta + */ + public DataMeta getInputMeta(String portName) { + return DataContext_GetInputMeta(portName); + } + + /** + * Set output meta + * @param portName portname + * @param dataMeta data meta + */ + public void setOutputMeta(String portName, DataMeta dataMeta) { + DataContext_SetOututMeta(portName, dataMeta); + } + + /** + * Get session context + * @return session context + */ + public SessionContext getSessionContext() { + return DataContext_GetSessionContext(); + } + + /** + * Get session configuration + * @return session configuration + */ + public Configuration getSessionConfig() { + return DataContext_GetSessionConfig(); + } + + /** + * get Statistics + * @return Statistics + */ + public StatisticsItem getStatistics() { + return DataContext_GetStatistics(); + } + + private native BufferList DataContext_Input(String portName); + + private native BufferList DataContext_Output(String portName); + + private native BufferList DataContext_External(); + + private native boolean DataContext_HasError(); + + private native void DataContext_SendEvent(FlowUnitEvent event); + + private native void DataContext_SetPrivate(String key, Object priv); + + private native Object DataContext_GetPrivate(String key); + + private native DataMeta DataContext_GetInputMeta(String portName); + + private native void DataContext_SetOututMeta(String portName, DataMeta dataMeta); + + private native SessionContext DataContext_GetSessionContext(); + + private native Configuration DataContext_GetSessionConfig(); + + private native StatisticsItem DataContext_GetStatistics(); +} diff --git a/src/java/src/main/java/com/modelbox/DataMeta.java b/src/java/src/main/java/com/modelbox/DataMeta.java new file mode 100644 index 000000000..5affb2d61 --- /dev/null +++ b/src/java/src/main/java/com/modelbox/DataMeta.java @@ -0,0 +1,46 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + +/** + * modelbox DataMeta + */ +public class DataMeta extends NativeObject { + public DataMeta() { + setNativeHandle(DataMetaNew()); + } + + /** + * set meta data + * @param key meta key + * @param value meta value + */ + public void set(String key, String value) { + DataMetaSet(key, value); + } + + public String getString(String key) { + return DataMetaGetString(key); + } + + private native long DataMetaNew(); + + private native void DataMetaSet(String key, String meta); + + private native String DataMetaGetString(String key); + +} diff --git a/src/java/src/main/java/com/modelbox/Device.java b/src/java/src/main/java/com/modelbox/Device.java new file mode 100644 index 000000000..61e4512fc --- /dev/null +++ b/src/java/src/main/java/com/modelbox/Device.java @@ -0,0 +1,46 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + +/** + * modelbox device + */ +public class Device extends NativeObject { + private Device() { + + } + + /** + * Get device type + * @return device type in string + */ + public String getType() { + return DeviceGetType(); + } + + /** + * Get device ID + * @return device id in string + */ + public String getDeviceID() { + return DeviceGetDeviceID(); + } + + private native String DeviceGetType(); + + private native String DeviceGetDeviceID(); +} diff --git a/src/java/src/main/java/com/modelbox/ExternalDataMap.java b/src/java/src/main/java/com/modelbox/ExternalDataMap.java new file mode 100644 index 000000000..1bd9c6d09 --- /dev/null +++ b/src/java/src/main/java/com/modelbox/ExternalDataMap.java @@ -0,0 +1,158 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.modelbox; + +import java.util.HashMap; + +/** + * modelbox ExternalDataMap + */ +public class ExternalDataMap extends NativeObject { + private Object priv_data = null; + + private ExternalDataMap() { + // Create this object from Flow. + } + + /** + * Create buffer list + * @return bufferlist + */ + public BufferList CreateBufferList() { + return ExternalDataMap_CreateBufferList(); + } + + /** + * Set output data meta + * @param name meta name + * @param meta datameta object + */ + public void setOutputMeta(String name, DataMeta meta) { + ExternalDataMap_SetOutputMeta(name, meta); + } + + /** + * Send bufferlist to port + * @param portName portname + * @param bufferlist bufferlist + * @throws ModelBoxException + */ + public void send(String portName, BufferList bufferlist) throws ModelBoxException { + ExternalDataMap_Send(portName, bufferlist); + } + + /** + * Recv bufferlist map + * @param timeout recv timeout in milliseconds, + * timeout > 0 if no data blocking for timeout(ms) and return null. + * timeout = 0 if no data blocking until data is ready. + * timeout < 0 if no data return immediately. and return null. + * @return output portname and bufferlist map + * @throws ModelBoxException + */ + public HashMap recv(long timeout) throws ModelBoxException { + return ExternalDataMap_Recv(timeout); + } + + /** + * Recv bufferlist map, blocking until data is ready. + * @return output portname and bufferlist map + * @throws ModelBoxException + */ + public HashMap recv() throws ModelBoxException { + return recv(0); + } + + /** + * Close datamap, no input data anymore + */ + public void close() { + ExternalDataMap_Close(); + } + + /** + * shutdown datamap, and exit. + */ + public void shutdown() { + ExternalDataMap_Shutdown(); + } + + /** + * Set user private object + * @param o + */ + public void setPrivate(Object o) { + priv_data = o; + } + + /** + * Get user private object + * @param user object type + * @return user object + */ + @SuppressWarnings("unchecked") + public T getPrivate() { + try { + return (T) priv_data; + } catch (ClassCastException e) { + return null; + } + } + + /** + * Get session context + * @return session context + */ + public SessionContext getSessionContext() { + return ExternalDataMap_GetSessionContext(); + } + + /** + * Get sessioncontext configuration + * @return sessioncontext configuration + */ + public Configuration getSessionConfig() { + return ExternalDataMap_GetSessionConfig(); + } + + /** + * Get last error on datamap + * @return flowunit error + */ + public FlowUnitError getLastError() { + return ExternalDataMap_GetLastError(); + } + + private native BufferList ExternalDataMap_CreateBufferList(); + + private native void ExternalDataMap_SetOutputMeta(String name, DataMeta meta); + + private native void ExternalDataMap_Send(String portName, BufferList bufferList); + + private native HashMap ExternalDataMap_Recv(long timeout); + + private native void ExternalDataMap_Close(); + + private native void ExternalDataMap_Shutdown(); + + private native SessionContext ExternalDataMap_GetSessionContext(); + + private native Configuration ExternalDataMap_GetSessionConfig(); + + private native FlowUnitError ExternalDataMap_GetLastError(); +} diff --git a/src/java/src/main/java/com/modelbox/ExternalDataSelect.java b/src/java/src/main/java/com/modelbox/ExternalDataSelect.java new file mode 100644 index 000000000..54fd0060a --- /dev/null +++ b/src/java/src/main/java/com/modelbox/ExternalDataSelect.java @@ -0,0 +1,72 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + +import java.util.ArrayList; + +/** + * modelbox ExternalDataSelect + */ +public class ExternalDataSelect extends NativeObject { + public ExternalDataSelect() { + setNativeHandle(ExternalDataSelect_New()); + } + + /** + * Register ExternalDataMap to ExternalDataSelect + * @param dataMap datamap object + */ + public void register(ExternalDataMap dataMap) { + ExternalDataSelect_RegisterExternalData(dataMap); + } + + /** + * From ExternalDataMap from ExternalDataSelect + * @param dataMap datamap object + */ + public void remove(ExternalDataMap dataMap) { + ExternalDataSelect_RemoveExternalData(dataMap); + } + + /** + * Wait from datamap ready + * @param timeout wait timeout. if timeout < 0, wait until data ready. + * @return datamap ready to recv + * @throws ModelBoxException + */ + public ArrayList select(long timeout) throws ModelBoxException { + return ExternalDataSelect_SelectExternalData(timeout); + } + + /** + * Wait from datamap ready + * @param timeout wait timeout. wait until data ready. + * @return datamap ready to recv + * @throws ModelBoxException + */ + public ArrayList select() throws ModelBoxException { + return select(-1); + } + + private native long ExternalDataSelect_New(); + + private native void ExternalDataSelect_RegisterExternalData(ExternalDataMap dataMap); + + private native void ExternalDataSelect_RemoveExternalData(ExternalDataMap dataMap); + + private native ArrayList ExternalDataSelect_SelectExternalData(long timeout); +} diff --git a/src/java/src/main/java/com/modelbox/Flow.java b/src/java/src/main/java/com/modelbox/Flow.java index cd15291ef..7f47f01b6 100644 --- a/src/java/src/main/java/com/modelbox/Flow.java +++ b/src/java/src/main/java/com/modelbox/Flow.java @@ -16,36 +16,145 @@ package com.modelbox; -public class Flow { +/** + * modelbox Flow + */ +public class Flow extends NativeObject { + public Flow() { + setNativeHandle(FlowNew()); + } - private long flowPtr = 0; + /** + * init flow from inline graph + * @param name graph name + * @param graph inline graph + * @throws ModelBoxException + */ + public void init(String name, String graph) throws ModelBoxException { + FlowInit(name, graph); + } - public Flow() { - flowPtr = ModelBoxJni.FlowNew(); + /** + * init flow from graph file + * @param file path to graph file + * @throws ModelBoxException + */ + public void init(String file) throws ModelBoxException { + FlowInit(file); + } + + /** + * init flow by name, args and flow directory + * @param name flow name + * @param args flow args + * @param flowDir scan flow directory + * @throws ModelBoxException + */ + public void initByName(String name, Configuration args, String flowDir) throws ModelBoxException { + FlowInitByName(name, args, flowDir); } - public void init(String name, String graph) throws FlowException { - ModelBoxJni.FlowInit(flowPtr, name, graph); - return; + /** + * init flow by name, args and flow directory + * @param name flow name + * @param args flow args + * @throws ModelBoxException + */ + public void initByName(String name, Configuration args) throws ModelBoxException { + FlowInitByName(name, args); } - public void build() throws FlowException { - ModelBoxJni.FlowBuild(flowPtr); - return; + /** + * init flow by name, args and flow directory + * @param name flow name + * @param args flow args + * @throws ModelBoxException + */ + public void initByName(String name) throws ModelBoxException { + FlowInitByName(name, null); } - public void close() throws FlowException { - if (flowPtr == 0) { - return; - } - ModelBoxJni.FlowFree(flowPtr); + /** + * Start run flow + * @throws ModelBoxException + */ + public void startRun() throws ModelBoxException { + FlowStartRun(); } - protected void finalize() { - try { - close(); - } catch (Exception e) { - //pass - } + /** + * Wait flow finish + * @throws ModelBoxException + */ + public void waitFor() throws ModelBoxException { + waitFor(0); } -} \ No newline at end of file + + /** + * Wait flow finish + * @param timeout wait timeout, in millisecond + * @return whether timeout + * @throws ModelBoxException + */ + public boolean waitFor(long timeout) throws ModelBoxException { + Status retval = new Status(); + return waitFor(timeout, retval); + } + + /** + * Wait flor finish, and get flow result + * @param timeout wait timeout, in millisecond + * @param retval flow result. + * @return whether timeout + * @throws ModelBoxException + */ + public boolean waitFor(long timeout, Status retval) throws ModelBoxException { + return FlowWait(timeout, retval); + } + + /** + * Stop flow + * @throws ModelBoxException + */ + public void stop() throws ModelBoxException { + FlowStop(); + } + + /** + * Create external data for sending data to flow + * @return ExternalDataMap object + * @throws ModelBoxException + */ + public ExternalDataMap createExternalDataMap() throws ModelBoxException { + return FlowCreateExternalDataMap(); + } + + /** + * Create stream io to send and recv stream data + * @return ExternalDataMap object + * @throws ModelBoxException + */ + public FlowStreamIO CreateStreamIO() throws ModelBoxException { + return FlowCreateStreamIO(); + } + + private native long FlowNew(); + + private native boolean FlowWait(long timeout, Status status); + + private native void FlowStartRun(); + + private native void FlowInit(String name, String graph); + + private native void FlowInit(String file); + + private native void FlowInitByName(String name, Configuration args, String flowDir); + + private native void FlowInitByName(String name, Configuration args); + + private native void FlowStop(); + + private native ExternalDataMap FlowCreateExternalDataMap(); + + private native FlowStreamIO FlowCreateStreamIO(); +} diff --git a/src/java/src/main/java/com/modelbox/FlowStreamIO.java b/src/java/src/main/java/com/modelbox/FlowStreamIO.java new file mode 100644 index 000000000..a7f7ef849 --- /dev/null +++ b/src/java/src/main/java/com/modelbox/FlowStreamIO.java @@ -0,0 +1,93 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + +/** + * modelbox FlowStreamIO + */ +public class FlowStreamIO extends NativeObject { + private FlowStreamIO() { + + } + + /** + * create a empty buffer on cpu device + * @returncpu buffer + * @throws ModelBoxException + */ + public Buffer createBuffer() throws ModelBoxException { + return FlowStreamIO_CreateBuffer(); + } + + /** + * Send buffer of this stream to flow + * @param inputName input node name of flow + * @param buffer buffer of this stream + * @throws ModelBoxException + */ + public void send(String inputName, Buffer buffer) throws ModelBoxException { + FlowStreamIO_Send(inputName, buffer); + } + + /** + * Send buffer of this stream to flow + * @param inputName input node name of flow + * @param data data of this stream + * @throws ModelBoxException + */ + public void send(String inputName, byte[] data) throws ModelBoxException { + FlowStreamIO_Send(inputName, data); + } + + /** + * @brief recv buffer of this stream result from flow + * @param output_name output node name of flow + * @param buffer result buffer of this stream + * @param timeout wait result timeout + * @return Status + **/ + /** + * Recv buffer of this stream result from flow + * @param outputName output node name of flow + * @param timeout wait result timeout + * timeout > 0 if no data blocking for timeout(ms) and return null. + * timeout = 0 if no data blocking until data is ready. + * timeout < 0 if no data return immediately. and return null. + * @return result buffer of this stream + * @throws ModelBoxException + */ + public Buffer recv(String outputName, long timeout) throws ModelBoxException { + return FlowStreamIO_Recv(outputName, timeout); + } + + /** + * Close input stream, mark stream end + */ + public void closeInput() { + FlowStreamIO_CloseInput(); + } + + private native Buffer FlowStreamIO_CreateBuffer(); + + private native void FlowStreamIO_Send(String inputName, Buffer buffer); + + private native void FlowStreamIO_Send(String inputName, byte[] data); + + private native Buffer FlowStreamIO_Recv(String outputName, long timeout); + + private native void FlowStreamIO_CloseInput(); +} diff --git a/src/java/src/main/java/com/modelbox/FlowUnit.java b/src/java/src/main/java/com/modelbox/FlowUnit.java new file mode 100644 index 000000000..5652d76fc --- /dev/null +++ b/src/java/src/main/java/com/modelbox/FlowUnit.java @@ -0,0 +1,53 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + +abstract public class FlowUnit extends NativeObject { + /** + * Flowunit Open + * @param opts + * @return + */ + abstract public Status open(Configuration opts); + + /** + * Flowunit Close + * @return + */ + abstract public Status close(); + + /** + * FlowUnit data process + * @param data_ctx + * @return + */ + abstract public Status process(DataContext data_ctx); + + /** + * Flowunit data pre + * @param data_ctx + * @return + */ + abstract public Status dataPre(DataContext data_ctx); + + /** + * FlowUnit data Post; + * @param data_ctx + * @return + */ + abstract public Status dataPost(DataContext data_ctx); +} diff --git a/src/java/src/main/java/com/modelbox/FlowUnitError.java b/src/java/src/main/java/com/modelbox/FlowUnitError.java new file mode 100644 index 000000000..7109855ff --- /dev/null +++ b/src/java/src/main/java/com/modelbox/FlowUnitError.java @@ -0,0 +1,52 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.modelbox; + +public class FlowUnitError extends NativeObject { + public FlowUnitError(String desc) { + setNativeHandle(FlowUnitError_New(desc)); + } + + public FlowUnitError(String node, String error_pos, Status error_status) { + setNativeHandle(FlowUnitError_New(node, error_pos, error_status)); + } + + /** + * Get flowunit error description + * @return error description + */ + public String getDesc() { + return FlowUnitError_GetDesc(); + } + + /** + * Get flowunit error status + * @return + */ + public Status GetStatus() { + return FlowUnitError_GetStatus(); + } + + private native long FlowUnitError_New(String desc); + + private native long FlowUnitError_New(String node, String error_pos, Status error_status); + + private native String FlowUnitError_GetDesc(); + + private native Status FlowUnitError_GetStatus(); +} diff --git a/src/java/src/main/java/com/modelbox/FlowUnitEvent.java b/src/java/src/main/java/com/modelbox/FlowUnitEvent.java new file mode 100644 index 000000000..5253e0925 --- /dev/null +++ b/src/java/src/main/java/com/modelbox/FlowUnitEvent.java @@ -0,0 +1,53 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + +public class FlowUnitEvent extends NativeObject { + + FlowUnitEvent() { + setNativeHandle(FlowUnitEventNew()); + } + + /** + * set data + * @param key data key + * @param value data value + */ + public void set(String key, String value) { + FlowUnitEventSet(key, value); + } + + /** + * set data + * @param key data key + * @param value data value + */ + public void set(String key, Object object) { + FlowUnitEventSet(key, object); + } + + + public Object get(String key) { + return FlowUnitEventGet(key); + } + + private native long FlowUnitEventNew(); + + private native void FlowUnitEventSet(String key, Object object); + + private native Object FlowUnitEventGet(String key); +} diff --git a/src/java/src/main/java/com/modelbox/Log.java b/src/java/src/main/java/com/modelbox/Log.java index a80be42d0..67d6cf414 100644 --- a/src/java/src/main/java/com/modelbox/Log.java +++ b/src/java/src/main/java/com/modelbox/Log.java @@ -14,27 +14,29 @@ * limitations under the License. */ + package com.modelbox; import java.text.SimpleDateFormat; import java.util.Date; - -public class Log { +public class Log extends NativeObject { enum LogLevel { - LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL + LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARN, LOG_ERROR, LOG_FATAL, LOG_OFF } - - private long logPtr = 0; public Log() { - logPtr = ModelBoxJni.LogNew(); - } - - protected void finalize() { - ModelBoxJni.LogFree(logPtr); + setNativeHandle(LogNew()); } + /** + * modelbox default log append function, output log to console + * @param level log level + * @param file log file + * @param lineno log file lineno + * @param func log function + * @param msg log message + */ public void print(LogLevel level, String file, int lineno, String func, String msg) { String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH.mm.ss.SSS").format(new Date()); System.out.printf("[%s][%s][%17s:%-4d] %s\n", timeStamp, level, file, lineno, msg); @@ -44,48 +46,160 @@ public final void jniPrintCallback(long level, String file, int lineno, String f print(LogLevel.LOG_INFO, file, lineno, func, msg); } - long getLogPtr() { - return logPtr; + /** + * Set log level + * @param level log level + */ + public void setLogLevel(LogLevel level) { + LogSetLogLevel(level.ordinal()); } - void setLogLevel(LogLevel level) { - ModelBoxJni.SetLogLevel(logPtr, level.ordinal()); + /** + * Get log level + * @return level log level + */ + public LogLevel getLogLevel() { + return LogLevel.values()[(int)LogGetLogLevel()]; } + /** + * Get current log appender + * @return + */ + public static Log getLogger() { + return LogGetLogger(); + } + + /** + * Register log appender to modelbox + * @param log + */ public static void regLog(Log log) { - ModelBoxJni.LogReg(log); + LogReg(log); } + /** + * Unregister log appender, reset to default + */ public static void unRegLog() { - ModelBoxJni.LogUnReg(); + LogUnReg(); + } + + /** + * log debug + * @param msg message + */ + public static void debug(String format, Object... params) { + printLog(LogLevel.LOG_DEBUG, format, params); + } + + /** + * log debug + * @param msg message + */ + public static void debug(String message) { + printLog(LogLevel.LOG_DEBUG, message); + } + + /** + * log info + * @param msg message + */ + public static void info(String format, Object... params) { + printLog(LogLevel.LOG_INFO, format, params); + } + + /** + * log info + * @param msg message + */ + public static void info(String message) { + printLog(LogLevel.LOG_INFO, message); + } + + /** + * log notice + * @param msg message + */ + public static void notice(String format, Object... params) { + printLog(LogLevel.LOG_NOTICE, format, params); } - public static void debug(String msg) { - printLog(LogLevel.LOG_DEBUG, msg); + /** + * log notice + * @param msg message + */ + public static void notice(String message) { + printLog(LogLevel.LOG_NOTICE, message); } - public static void info(String msg) { + /** + * log warn + * @param msg message + */ + public static void warn(String format, Object... params) { + printLog(LogLevel.LOG_WARN, format, params); + } - printLog(LogLevel.LOG_INFO, msg); + /** + * log notice + * @param msg message + */ + public static void warn(String message) { + printLog(LogLevel.LOG_WARN, message); } - public static void warn(String msg) { - printLog(LogLevel.LOG_WARN, msg); + /** + * log error + * @param msg message + */ + public static void error(String format, Object... params) { + printLog(LogLevel.LOG_ERROR, format, params); } - public static void error(String msg) { - printLog(LogLevel.LOG_ERROR, msg); + /** + * log error + * @param msg message + */ + public static void error(String message) { + printLog(LogLevel.LOG_ERROR, message); } - public static void fatal(String msg) { - printLog(LogLevel.LOG_FATAL, msg); + /** + * log fatal + * @param msg message + */ + public static void fatal(String format, Object... params) { + printLog(LogLevel.LOG_FATAL, format, params); } - private static void printLog(LogLevel level, String msg) { + /** + * log fatal + * @param msg message + */ + public static void fatal(String message) { + printLog(LogLevel.LOG_FATAL, message); + } + + private static void printLog(LogLevel level, String format, Object... params) { StackTraceElement stack = Thread.currentThread().getStackTrace()[3]; String file = stack.getFileName(); int lineno = stack.getLineNumber(); String func = stack.getMethodName(); - ModelBoxJni.LogPrint(level.ordinal(), file, lineno, func, msg); + LogPrint(level.ordinal(), file, lineno, func, String.format(format, params)); } + + public native long LogNew(); + + public native void LogSetLogLevel(long level); + + public native long LogGetLogLevel(); + + public static native Log LogGetLogger(); + + public static native void LogReg(Log log); + + public static native void LogUnReg(); + + public static native void LogPrint(long level, String file, int lineno, String func, String msg); } diff --git a/src/java/src/main/java/com/modelbox/ModelBoxException.java b/src/java/src/main/java/com/modelbox/ModelBoxException.java new file mode 100644 index 000000000..9da583282 --- /dev/null +++ b/src/java/src/main/java/com/modelbox/ModelBoxException.java @@ -0,0 +1,311 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.modelbox; + +import java.io.IOException; + +/** + * modelbox exception type + */ +public class ModelBoxException extends IOException { + public ModelBoxException() {} + + public ModelBoxException(String message) { + super(message); + } + + static public class Success extends ModelBoxException { + public Success() { + super(); + } + + public Success(String message) { + super(message); + } + } + static public class Fault extends ModelBoxException { + public Fault() { + super(); + } + + public Fault(String message) { + super(message); + } + } + static public class Notfound extends ModelBoxException { + public Notfound() { + super(); + } + + public Notfound(String message) { + super(message); + } + } + static public class Invalid extends ModelBoxException { + public Invalid() { + super(); + } + + public Invalid(String message) { + super(message); + } + } + static public class Again extends ModelBoxException { + public Again() { + super(); + } + + public Again(String message) { + super(message); + } + } + static public class Badconf extends ModelBoxException { + public Badconf() { + super(); + } + + public Badconf(String message) { + super(message); + } + } + static public class Nomem extends ModelBoxException { + public Nomem() { + super(); + } + + public Nomem(String message) { + super(message); + } + } + static public class Range extends ModelBoxException { + public Range() { + super(); + } + + public Range(String message) { + super(message); + } + } + static public class Exist extends ModelBoxException { + public Exist() { + super(); + } + + public Exist(String message) { + super(message); + } + } + static public class Internal extends ModelBoxException { + public Internal() { + super(); + } + + public Internal(String message) { + super(message); + } + } + static public class Busy extends ModelBoxException { + public Busy() { + super(); + } + + public Busy(String message) { + super(message); + } + } + static public class Permit extends ModelBoxException { + public Permit() { + super(); + } + + public Permit(String message) { + super(message); + } + } + static public class Notsupport extends ModelBoxException { + public Notsupport() { + super(); + } + + public Notsupport(String message) { + super(message); + } + } + static public class Nodata extends ModelBoxException { + public Nodata() { + super(); + } + + public Nodata(String message) { + super(message); + } + } + static public class Nospace extends ModelBoxException { + public Nospace() { + super(); + } + + public Nospace(String message) { + super(message); + } + } + static public class Nobufs extends ModelBoxException { + public Nobufs() { + super(); + } + + public Nobufs(String message) { + super(message); + } + } + static public class Overflow extends ModelBoxException { + public Overflow() { + super(); + } + + public Overflow(String message) { + super(message); + } + } + static public class Inprogress extends ModelBoxException { + public Inprogress() { + super(); + } + + public Inprogress(String message) { + super(message); + } + } + static public class Already extends ModelBoxException { + public Already() { + super(); + } + + public Already(String message) { + super(message); + } + } + static public class Timedout extends ModelBoxException { + public Timedout() { + super(); + } + + public Timedout(String message) { + super(message); + } + } + static public class Nostream extends ModelBoxException { + public Nostream() { + super(); + } + + public Nostream(String message) { + super(message); + } + } + static public class Reset extends ModelBoxException { + public Reset() { + super(); + } + + public Reset(String message) { + super(message); + } + } + static public class Continue extends ModelBoxException { + public Continue() { + super(); + } + + public Continue(String message) { + super(message); + } + } + static public class Edquot extends ModelBoxException { + public Edquot() { + super(); + } + + public Edquot(String message) { + super(message); + } + } + static public class Stop extends ModelBoxException { + public Stop() { + super(); + } + + public Stop(String message) { + super(message); + } + } + static public class Shutdown extends ModelBoxException { + public Shutdown() { + super(); + } + + public Shutdown(String message) { + super(message); + } + } + static public class Eof extends ModelBoxException { + public Eof() { + super(); + } + + public Eof(String message) { + super(message); + } + } + static public class Noent extends ModelBoxException { + public Noent() { + super(); + } + + public Noent(String message) { + super(message); + } + } + static public class Deadlock extends ModelBoxException { + public Deadlock() { + super(); + } + + public Deadlock(String message) { + super(message); + } + } + static public class Noresponse extends ModelBoxException { + public Noresponse() { + super(); + } + + public Noresponse(String message) { + super(message); + } + } + static public class Io extends ModelBoxException { + public Io() { + super(); + } + + public Io(String message) { + super(message); + } + } +} diff --git a/src/java/src/main/java/com/modelbox/ModelBoxJni.java b/src/java/src/main/java/com/modelbox/ModelBoxJni.java index bbaf415c4..044c99f07 100644 --- a/src/java/src/main/java/com/modelbox/ModelBoxJni.java +++ b/src/java/src/main/java/com/modelbox/ModelBoxJni.java @@ -14,32 +14,19 @@ * limitations under the License. */ + + package com.modelbox; +/** + * modelbox defulat JNI + */ public class ModelBoxJni { static { System.loadLibrary("modelbox-jni"); } // CHECKSTYLE:OFF - public static native long FlowNew(); - - public static native void FlowFree(long flow); - - public static native void FlowInit(long flow, String name, String graph); - - public static native void FlowBuild(long flow); - - public static native long LogNew(); - - public static native void LogFree(long log); - - public static native void SetLogLevel(long log, long level); - - public static native void LogReg(Log log); - - public static native void LogUnReg(); - public static native void LogPrint(long level, String file, int lineno, String func, String msg); // CHECKSTYLE:ON -} \ No newline at end of file +} diff --git a/src/java/src/main/java/com/modelbox/NativeObject.java b/src/java/src/main/java/com/modelbox/NativeObject.java new file mode 100644 index 000000000..fa365fbc5 --- /dev/null +++ b/src/java/src/main/java/com/modelbox/NativeObject.java @@ -0,0 +1,51 @@ +package com.modelbox; + +/** + * modelbox JNI backend + */ +public class NativeObject { + private long native_handle = 0; + + static { + System.loadLibrary("modelbox-jni"); + } + + protected NativeObject() { + native_handle = 0; + } + + /** + * Get native jni handle + * @return native jni handle + */ + public long getNativeHandle() { + return native_handle; + } + + /** + * Set native jni handle + * @param handle native jni handle + */ + protected void setNativeHandle(long handle) { + if (native_handle != 0) { + delete_handle(native_handle); + native_handle = 0; + } + native_handle = handle; + } + + /** + * Free native jni handle + */ + @Override + protected void finalize() { + try { + delete_handle(native_handle); + native_handle = 0; + } catch (Exception e) { + //pass + } + } + + private native void delete_handle(long handle); +} diff --git a/src/java/src/main/java/com/modelbox/SessionContext.java b/src/java/src/main/java/com/modelbox/SessionContext.java new file mode 100644 index 000000000..587c72f3e --- /dev/null +++ b/src/java/src/main/java/com/modelbox/SessionContext.java @@ -0,0 +1,100 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.modelbox; + +/** + * modelbox SessionContext + */ +public class SessionContext extends NativeObject { + + private SessionContext() { + + } + + /** + * Set private object + * @param key private key + * @param object private object + */ + public void setPrivate(String key, Object object) { + SessionContext_SetPrivate(key, object); + } + + /** + * Get private object + * @param key private key + * @return object private object + */ + public Object getPrivate(String key) { + return SessionContext_GetPrivate(key); + } + + /** + * Set session ID + * @param sessionId session id + */ + public void setSessionId(String sessionId) { + SessionContext_SetSessionId(sessionId); + } + + /** + * Get session ID + * @return session id + */ + public String getSessionId() { + return SessionContext_GetSessionId(); + } + + /** + * Get session configuration object + * @return session configuration object + */ + public Configuration getConfig() { + return SessionContext_GetConfiguration(); + } + + /** + * Set error to session + * @param error flowunit error + */ + public void setError(FlowUnitError error) { + SessionContext_SetError(error); + } + + /** + * Get error from session + * @return error flowunit error + */ + public FlowUnitError getError() { + return SessionContext_GetError(); + } + + private native void SessionContext_SetPrivate(String key, Object object); + + private native Object SessionContext_GetPrivate(String key); + + private native void SessionContext_SetSessionId(String sessionId); + + private native String SessionContext_GetSessionId(); + + private native Configuration SessionContext_GetConfiguration(); + + private native void SessionContext_SetError(FlowUnitError error); + + private native FlowUnitError SessionContext_GetError(); +} diff --git a/src/java/src/main/java/com/modelbox/FlowException.java b/src/java/src/main/java/com/modelbox/StatisticsItem.java similarity index 93% rename from src/java/src/main/java/com/modelbox/FlowException.java rename to src/java/src/main/java/com/modelbox/StatisticsItem.java index afaf4a188..a5c59b0c3 100644 --- a/src/java/src/main/java/com/modelbox/FlowException.java +++ b/src/java/src/main/java/com/modelbox/StatisticsItem.java @@ -16,6 +16,6 @@ package com.modelbox; -public class FlowException extends Exception { +public class StatisticsItem { } diff --git a/src/java/src/main/java/com/modelbox/Status.java b/src/java/src/main/java/com/modelbox/Status.java new file mode 100644 index 000000000..855feffb4 --- /dev/null +++ b/src/java/src/main/java/com/modelbox/Status.java @@ -0,0 +1,131 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.modelbox; + +/** + * modelbox Status + */ +public class Status extends NativeObject { + public Status() { + setNativeHandle(StatusNew()); + } + + /** + * constructor of status + * @param code status code + * @param msg status message + */ + public Status(StatusCode code, String msg) { + setNativeHandle(StatusNew()); + StatusSetCode(code.ordinal()); + StatusSetErrorMsg(msg); + } + + /** + * constructor of status + * @param other another status + * @param msg status message + */ + public Status(Status other, String msg) { + setNativeHandle(StatusNew()); + StatusWrap(other, other.Code().ordinal(), msg); + } + + /** + * make status to string + * @return status in string + */ + public String ToSting() { + return StatusToSting(); + } + + /** + * Get status code + * @return status code + */ + public StatusCode Code() { + return StatusCode(); + } + + /** + * Get status code in string + * @return status code in string + */ + public String StrCode() { + return StatusStrCode(); + } + + /** + * Set error message to status + * @param errorMsg error message + */ + public void SetErrorMsg(String errorMsg) { + StatusSetErrorMsg(errorMsg); + } + + /** + * Get error message + * @return error messsage + */ + public String ErrorMsg() { + return StatusErrorMsg(); + } + + /** + * Get wrap error message + * @return wrap error message + */ + public String WrapErrormsgs() { + return StatusWrapErrormsgs(); + } + + private native long StatusNew(); + + private native void StatusSetCode(long code); + + private native void StatusWrap(Status status, long code, String msg); + + private native String StatusToSting(); + + private native StatusCode StatusCode(); + + private native String StatusStrCode(); + + private native void StatusSetErrorMsg(String errorMsg); + + private native String StatusErrorMsg(); + + private native String StatusWrapErrormsgs(); + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + + if (o instanceof Status == false) { + return false; + } + + if (Code() == ((Status) o).Code()) { + return true; + } + + return false; + } +} diff --git a/src/java/src/main/java/com/modelbox/StatusCode.java b/src/java/src/main/java/com/modelbox/StatusCode.java new file mode 100644 index 000000000..53a432bb4 --- /dev/null +++ b/src/java/src/main/java/com/modelbox/StatusCode.java @@ -0,0 +1,52 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.modelbox; + +public enum StatusCode { + STATUS_SUCCESS, /* Success, Avoid using this, use STATUS_OK instead.*/ + STATUS_FAULT, /* Fault */ + STATUS_NOTFOUND, /* Not Found */ + STATUS_INVALID, /* Invalid argument */ + STATUS_AGAIN, /* Try again */ + STATUS_BADCONF, /* Bad Config */ + STATUS_NOMEM, /* Out of memory */ + STATUS_RANGE, /* Out of range */ + STATUS_EXIST, /* Already exists */ + STATUS_INTERNAL, /* Internal error */ + STATUS_BUSY, /* Device or resource busy */ + STATUS_PERMIT, /* Operation not permitted */ + STATUS_NOTSUPPORT, /* Not supported */ + STATUS_NODATA, /* No data available */ + STATUS_NOSPACE, /* No space left */ + STATUS_NOBUFS, /* No buffer space available */ + STATUS_OVERFLOW, /* Value too large for defined data type */ + STATUS_INPROGRESS, /* Operation now in progress */ + STATUS_ALREADY, /* Operation already in progress */ + STATUS_TIMEDOUT, /* Operation timed out */ + STATUS_NOSTREAM, /* Out of streams resources */ + STATUS_RESET, /* Request Reset by peer */ + STATUS_CONTINUE, /* Continue operation */ + STATUS_EDQUOT, /* Quota exceeded */ + STATUS_STOP, /* Stop operation */ + STATUS_SHUTDOWN, /* Shutdown operation */ + STATUS_EOF, /* End of file */ + STATUS_NOENT, /* No such file or directory */ + STATUS_DEADLOCK, /* Resource deadlock */ + STATUS_NORESPONSE, /* No response*/ + STATUS_IO /* Input/output error */ +} diff --git a/src/java/src/test/java/com/modelbox/ModelBoxConfigurationTest.java b/src/java/src/test/java/com/modelbox/ModelBoxConfigurationTest.java new file mode 100644 index 000000000..c885d2e16 --- /dev/null +++ b/src/java/src/test/java/com/modelbox/ModelBoxConfigurationTest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + +import static org.junit.Assert.assertEquals; +import java.util.ArrayList; +import org.junit.Test; + +public class ModelBoxConfigurationTest { + + @Test + public void testKeys() throws Exception { + Configuration conf = new Configuration(); + conf.set("bool", true); + conf.set("int", 1); + conf.set("long", 1); + conf.set("float", 1.1F); + conf.set("double", 1.2); + conf.set("string", "string"); + ArrayList lists = new ArrayList(); + lists.add("a"); + lists.add("b"); + lists.add("c"); + conf.set("strings", lists); + + assertEquals(conf.getBoolean("bool", false), true); + assertEquals(conf.getInt("int", 0), 1); + assertEquals(conf.getLong("long", 0), 1); + assertEquals(conf.getFloat("float", 0.0F), 1.1F, 0.1); + assertEquals(conf.getDouble("double", 0.0F), 1.2, 0.1); + assertEquals(conf.getString("string", ""), "string"); + + ArrayList get_lists = conf.getStrings("strings", null); + assertEquals(lists.size(), get_lists.size()); + + for (int i = 0; i < lists.size(); i++) { + assertEquals(lists.get(i), get_lists.get(i)); + } + } + + @Test + public void testKeysDefault() throws Exception { + Configuration conf = new Configuration(); + + ArrayList lists = new ArrayList(); + lists.add("a"); + lists.add("b"); + lists.add("c"); + conf.set("strings", lists); + + assertEquals(conf.getBoolean("bool", true), true); + assertEquals(conf.getInt("int", 1), 1); + assertEquals(conf.getLong("long", 1), 1); + assertEquals(conf.getFloat("float", 1.1F), 1.1F, 0.1); + assertEquals(conf.getDouble("double", 1.1F), 1.2, 0.1); + assertEquals(conf.getString("string", "string"), "string"); + + ArrayList get_lists = conf.getStrings("strings", lists); + assertEquals(lists, get_lists); + } +} \ No newline at end of file diff --git a/src/java/src/test/java/com/modelbox/ModelBoxFlowTest.java b/src/java/src/test/java/com/modelbox/ModelBoxFlowTest.java index 5d506d8a5..8d1dff533 100644 --- a/src/java/src/test/java/com/modelbox/ModelBoxFlowTest.java +++ b/src/java/src/test/java/com/modelbox/ModelBoxFlowTest.java @@ -14,20 +14,34 @@ * limitations under the License. */ + package com.modelbox; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.junit.BeforeClass; import org.junit.Test; public class ModelBoxFlowTest { - @Test + @BeforeClass + public static void setUpTest() { + Log.unRegLog(); + } + + @Test(expected = ModelBoxException.Badconf.class) public void testFlowNotExist() throws Exception { String driverDir = TestConfig.TEST_DRIVER_DIR; - String txt = "[driver]\n"; txt += "dir=[\"" + driverDir + "\"]\n"; txt += "skip-default=true\n"; txt += "[log]\n"; - txt += "level=\"ERROR\"\n"; + txt += "level=\"INFO\"\n"; txt += "[graph]\n"; txt += "graphconf = '''digraph demo {{ \n"; txt += " notexist[type=flowunit, flowunit=notexist, device=cpu]\n"; @@ -37,6 +51,143 @@ public void testFlowNotExist() throws Exception { System.out.println(txt); Flow flow = new Flow(); flow.init("NOT-EXIST", txt); - flow.build(); + flow.startRun(); + } + + @Test + public void testFlowProcessData() throws Exception { + String driverDir = TestConfig.TEST_DRIVER_DIR; + boolean get_result = false; + String txt = "[driver]\n"; + txt += "dir=[\"" + driverDir + "\"]\n"; + txt += "skip-default=true\n"; + txt += "[log]\n"; + txt += "level=\"INFO\"\n"; + txt += "[graph]\n"; + txt += "graphconf = '''digraph demo {{ \n"; + txt += " input[type=input] \n"; + txt += " process[flowunit=passthrouth, device=cpu]\n"; + txt += " output[type=output]\n"; + txt += "\n"; + txt += " input->process:in"; + txt += " process:out -> output\n"; + txt += "}}'''\n"; + txt += "format = \"graphviz\"\n"; + + System.out.println(txt); + Flow flow = new Flow(); + flow.init("Process", txt); + flow.startRun(); + ExternalDataMap datamap = flow.createExternalDataMap(); + BufferList data = datamap.CreateBufferList(); + assertEquals(data.getDevice().getType(), "cpu"); + + data.build(new int[] {0}); + String msg = "Hello world"; + data.at(0).build(msg.getBytes()); + data.pushBack(msg.getBytes()); + datamap.send("input", data); + datamap.close(); + datamap.setPrivate("this is a test"); + Log.info("session id is " + datamap.getSessionContext().getSessionId()); + + ExternalDataSelect data_select = new ExternalDataSelect(); + data_select.register(datamap); + + while (true) { + try { + ArrayList datamaplist = data_select.select(1000 * 10); + if (datamaplist == null) { + assertFalse(true); + break; + } + + for (ExternalDataMap outdatamap : datamaplist) { + System.out.println("Get: " + outdatamap.getPrivate()); + HashMap outdata = outdatamap.recv(); + if (outdata == null) { + data_select.remove(outdatamap); + throw new ModelBoxException.Eof("exit"); + } + + assertEquals(outdata.size(), 1); + assertEquals(datamap, outdatamap); + for (Map.Entry entry : outdata.entrySet()) { + String key = entry.getKey(); + BufferList value = entry.getValue(); + assertEquals(key, "output"); + assertEquals(value.size(), 2); + String str = new String(value.at(0).getData()); + assertEquals(msg, str); + Log.info("Message is: " + str); + get_result = true; + } + } + } catch (ModelBoxException.Eof e) { + break; + } catch (ModelBoxException e) { + System.out.println("select failed, " + e.getMessage()); + assertFalse(true); + break; + } + } + + assertTrue(get_result); + flow = null; + System.gc(); + } + + @Test + public void testFlowStreamIO() throws Exception { + String driverDir = TestConfig.TEST_DRIVER_DIR; + boolean get_result = false; + String txt = "[driver]\n"; + txt += "dir=[\"" + driverDir + "\"]\n"; + txt += "skip-default=true\n"; + txt += "[log]\n"; + txt += "level=\"INFO\"\n"; + txt += "[graph]\n"; + txt += "graphconf = '''digraph demo {{ \n"; + txt += " input[type=input] \n"; + txt += " process[flowunit=passthrouth, device=cpu]\n"; + txt += " output[type=output]\n"; + txt += "\n"; + txt += " input->process:in"; + txt += " process:out -> output\n"; + txt += "}}'''\n"; + txt += "format = \"graphviz\"\n"; + + + System.out.println(txt); + Flow flow = new Flow(); + flow.init("Process", txt); + flow.startRun(); + FlowStreamIO streamio = flow.CreateStreamIO(); + Buffer data = streamio.createBuffer(); + assertEquals(data.getDevice().getType(), "cpu"); + String msg = "Hello world"; + data.build(msg.getBytes()); + streamio.send("input", data); + streamio.send("input", msg.getBytes()); + streamio.closeInput(); + int count = 0; + + while (true) { + Buffer outdata = streamio.recv("output", 1000 * 10); + if (outdata == null) { + break; + } + + String str = new String(outdata.getData()); + assertEquals(msg, str); + Log.info("Message is: " + str); + get_result = true; + count++; + } + + assertEquals(count, 2); + assertTrue(get_result); + flow = null; + System.gc(); } -} \ No newline at end of file +} diff --git a/src/java/src/test/java/com/modelbox/ModelBoxLogTest.java b/src/java/src/test/java/com/modelbox/ModelBoxLogTest.java index a654f455f..d869d6710 100644 --- a/src/java/src/test/java/com/modelbox/ModelBoxLogTest.java +++ b/src/java/src/test/java/com/modelbox/ModelBoxLogTest.java @@ -17,10 +17,8 @@ package com.modelbox; import static org.junit.Assert.assertEquals; - import java.text.SimpleDateFormat; import java.util.Date; - import org.junit.Test; public class ModelBoxLogTest { @@ -38,11 +36,48 @@ public void print(LogLevel level, String file, int lineno, String func, String m @Test public void testLogReg() throws Exception { String mesg = "This is hello msg"; + Log.getLogger().setLogLevel(Log.LogLevel.LOG_DEBUG); + Log.debug(mesg); TestLog log = new TestLog(); Log.regLog(log); log.setLogLevel(Log.LogLevel.LOG_DEBUG); Log.info(mesg); assertEquals(log.lastMsg, mesg); + assertEquals(log, Log.LogGetLogger()); + Log.unRegLog(); + } + + @Test + public void testLogFormat() throws Exception { + String mesg = "This is hello msg"; + String mesg1 = "This is message 2"; + String expect_msg = "Msg: " + mesg + " " + mesg1; + Log.getLogger().setLogLevel(Log.LogLevel.LOG_DEBUG); + Log.debug(mesg); + TestLog log = new TestLog(); + Log.regLog(log); + log.setLogLevel(Log.LogLevel.LOG_DEBUG); + Log.info("Msg: %s %s", mesg, mesg1); + assertEquals(log.lastMsg, expect_msg); + assertEquals(log, Log.LogGetLogger()); Log.unRegLog(); } + + @Test + public void testLogLevel() throws Exception { + Log.LogLevel oldLevel = Log.getLogger().getLogLevel(); + + Log.getLogger().setLogLevel(Log.LogLevel.LOG_DEBUG); + assertEquals(Log.getLogger().getLogLevel(), Log.LogLevel.LOG_DEBUG); + Log.getLogger().setLogLevel(Log.LogLevel.LOG_INFO); + assertEquals(Log.getLogger().getLogLevel(), Log.LogLevel.LOG_INFO); + Log.getLogger().setLogLevel(Log.LogLevel.LOG_NOTICE); + assertEquals(Log.getLogger().getLogLevel(), Log.LogLevel.LOG_NOTICE); + Log.getLogger().setLogLevel(Log.LogLevel.LOG_WARN); + assertEquals(Log.getLogger().getLogLevel(), Log.LogLevel.LOG_WARN); + Log.getLogger().setLogLevel(Log.LogLevel.LOG_ERROR); + assertEquals(Log.getLogger().getLogLevel(), Log.LogLevel.LOG_ERROR); + + Log.getLogger().setLogLevel(oldLevel); + } } \ No newline at end of file diff --git a/src/java/src/test/java/com/modelbox/ModelBoxMiscTest.java b/src/java/src/test/java/com/modelbox/ModelBoxMiscTest.java new file mode 100644 index 000000000..b7f44f062 --- /dev/null +++ b/src/java/src/test/java/com/modelbox/ModelBoxMiscTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class ModelBoxMiscTest { + @Test + public void testFlowUnitError() throws Exception { + FlowUnitError err = new FlowUnitError("desc"); + assertEquals(err.getDesc(), "desc"); + + Status status = new Status(StatusCode.STATUS_ALREADY, "status"); + err = new FlowUnitError("a", "b", status); + assertEquals(err.getDesc(), "node:a error pos:b status:Operation already in progress error:status"); + } + + @Test + public void testFlowUnitDataMeta() throws Exception { + DataMeta data = new DataMeta(); + data.set("a", "a"); + data.set("b", "b"); + + assertEquals(data.getString("a"), "a"); + assertEquals(data.getString("b"), "b"); + assertEquals(data.getString("c"), null); + } + + @Test + public void testFlowUnitEvent() throws Exception { + FlowUnitEvent event = new FlowUnitEvent(); + event.set("a", "a"); + event.set("b", "b"); + + + assertEquals(event.get("a"), "a"); + assertEquals(event.get("b"), "b"); + assertEquals(event.get("c"), null); + } +} \ No newline at end of file diff --git a/src/java/src/test/java/com/modelbox/ModelBoxStatusTest.java b/src/java/src/test/java/com/modelbox/ModelBoxStatusTest.java new file mode 100644 index 000000000..57a8c9552 --- /dev/null +++ b/src/java/src/test/java/com/modelbox/ModelBoxStatusTest.java @@ -0,0 +1,31 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.modelbox; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class ModelBoxStatusTest { + @Test + public void testStatusMessage() throws Exception { + String msg = "this is a message"; + Status s = new Status(StatusCode.STATUS_FAULT, msg); + String expect_msg = "code: " + s.StrCode() + ", errmsg: " + msg; + assertEquals(expect_msg, s.ToSting()); + System.out.println(s.ToSting()); + } +} \ No newline at end of file diff --git a/src/java/src/test/java/com/modelbox/TestConfig.java b/src/java/src/test/java/com/modelbox/TestConfig.java index 692f40e1e..ef4fd9787 100644 --- a/src/java/src/test/java/com/modelbox/TestConfig.java +++ b/src/java/src/test/java/com/modelbox/TestConfig.java @@ -14,17 +14,30 @@ * limitations under the License. */ + package com.modelbox; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; - import org.json.JSONObject; public class TestConfig { static { + /** + for vscode junit: + add the following settings in settings.json + + "java.test.config": { + "vmArgs": [ + "-Djava.library.path=${workspaceFolder}/build/src/java/jni" + ], + "env" : { + "TEST_CONFIG_JSON_FILE" : "${workspaceFolder}/build/src/java/src/test/java/com/modelbox/TestConfig.json" + } + }, + */ String jsonfile = System.getenv("TEST_CONFIG_JSON_FILE"); if (jsonfile != null) { try { diff --git a/src/libmodelbox/base/drivers/driver.cc b/src/libmodelbox/base/drivers/driver.cc index 38f1c00bc..ec67b2aac 100644 --- a/src/libmodelbox/base/drivers/driver.cc +++ b/src/libmodelbox/base/drivers/driver.cc @@ -213,7 +213,13 @@ bool Driver::IsVirtual() { return is_virtual_; } void Driver::SetVirtual(bool is_virtual) { is_virtual_ = is_virtual; } void Driver::CloseFactory() { - if (--factory_count_ > 0) { + std::lock_guard guard(mutex_); + CloseFactoryLocked(); +} + +void Driver::CloseFactoryLocked() { + factory_count_--; + if (factory_count_ > 0) { return; } @@ -309,7 +315,8 @@ int Driver::GetMode(bool no_delete, bool global, bool deep_bind) { std::shared_ptr Driver::CreateFactory() { std::lock_guard guard(mutex_); - if (++factory_count_ == 1) { + factory_count_++; + if (factory_count_ == 1) { auto no_delete = GetDriverDesc()->GetNoDelete(); auto global = GetDriverDesc()->GetGlobal(); auto deep_bind = GetDriverDesc()->GetDeepBind(); @@ -330,7 +337,7 @@ std::shared_ptr Driver::CreateFactory() { StatusError = {STATUS_INVALID, "dlopen " + GetDriverFile() + " failed, error: " + dl_errmsg}; MBLOG_ERROR << StatusError.Errormsg(); - CloseFactory(); + CloseFactoryLocked(); return nullptr; } @@ -351,7 +358,7 @@ std::shared_ptr Driver::CreateFactory() { StatusError = {STATUS_INVALID, "failed to dlsym function DriverInit in file: " + GetDriverFile() + ", error: " + dl_errmsg}; - CloseFactory(); + CloseFactoryLocked(); return nullptr; } @@ -362,7 +369,7 @@ std::shared_ptr Driver::CreateFactory() { StatusError = {init, "driver init failed, driver:" + GetDriverFile()}; MBLOG_ERROR << "driverInit failed in " << GetDriverFile() << ", " << init; - CloseFactory(); + CloseFactoryLocked(); return nullptr; } } @@ -384,7 +391,7 @@ std::shared_ptr Driver::CreateFactory() { } MBLOG_ERROR << StatusError.Errormsg(); - CloseFactory(); + CloseFactoryLocked(); return nullptr; } @@ -393,16 +400,14 @@ std::shared_ptr Driver::CreateFactory() { StatusError = {STATUS_FAULT, "create driver failed, driver:" + GetDriverFile()}; MBLOG_ERROR << StatusError.Errormsg(); - CloseFactory(); + CloseFactoryLocked(); return nullptr; } } + auto holder = shared_from_this(); std::shared_ptr child_factory( - factory_.get(), [&](DriverFactory *child_factory) { - std::lock_guard guard(mutex_); - CloseFactory(); - }); + factory_.get(), [&, holder](DriverFactory *child_factory) { holder->CloseFactory(); }); return child_factory; } diff --git a/src/libmodelbox/base/include/modelbox/base/driver.h b/src/libmodelbox/base/include/modelbox/base/driver.h index 0e63f0c5d..154ccaf64 100644 --- a/src/libmodelbox/base/include/modelbox/base/driver.h +++ b/src/libmodelbox/base/include/modelbox/base/driver.h @@ -114,7 +114,7 @@ class DriverHandler { std::map> handler_map; }; -class Driver { +class Driver : public std::enable_shared_from_this { public: Driver(); virtual ~Driver(); @@ -135,6 +135,7 @@ class Driver { private: int GetMode(bool no_delete, bool global, bool deep_bind); void CloseFactory(); + void CloseFactoryLocked(); bool is_virtual_ = false; void *driver_handler_{nullptr}; int factory_count_ = 0; diff --git a/src/libmodelbox/base/include/modelbox/base/log.h b/src/libmodelbox/base/include/modelbox/base/log.h index b1d52c70f..05f42a0ba 100644 --- a/src/libmodelbox/base/include/modelbox/base/log.h +++ b/src/libmodelbox/base/include/modelbox/base/log.h @@ -201,6 +201,7 @@ class LoggerConsole : public Logger { private: void SetLogLevelFromEnv(); LogLevel level_ = LOG_OFF; + bool neeed_flush_; }; class Log { diff --git a/src/libmodelbox/base/include/modelbox/base/status.h b/src/libmodelbox/base/include/modelbox/base/status.h index 020c8a88b..ce7523d23 100644 --- a/src/libmodelbox/base/include/modelbox/base/status.h +++ b/src/libmodelbox/base/include/modelbox/base/status.h @@ -116,6 +116,12 @@ class Status { */ std::string StrCode() const; + /** + * @brief Get status raw code in string + * + */ + std::string StrStatusCode() const; + /** * @brief Set error message to status * @param errmsg error mesage. diff --git a/src/libmodelbox/base/log/log.cc b/src/libmodelbox/base/log/log.cc index b88856254..038d39c74 100644 --- a/src/libmodelbox/base/log/log.cc +++ b/src/libmodelbox/base/log/log.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -167,7 +168,10 @@ void LoggerCallback::Print(LogLevel level, const char *file, int lineno, Logger::Print(level, file, lineno, func, msg); } -LoggerConsole::LoggerConsole() { SetLogLevelFromEnv(); } +LoggerConsole::LoggerConsole() { + neeed_flush_ = !isatty(STDOUT_FILENO); + SetLogLevelFromEnv(); +} void LoggerConsole::SetLogLevelFromEnv() { const char *log_level = getenv("MODELBOX_CONSOLE_LOGLEVEL"); @@ -222,6 +226,9 @@ void LoggerConsole::Print(LogLevel level, const char *file, int lineno, } printf("%s%s\n", prefix_msg, msg); + if (neeed_flush_) { + fflush(stdout); + } } void LoggerConsole::SetLogLevel(LogLevel level) { level_ = level; } diff --git a/src/libmodelbox/base/status/status.cc b/src/libmodelbox/base/status/status.cc index 6b52f6c37..b1edf98ed 100644 --- a/src/libmodelbox/base/status/status.cc +++ b/src/libmodelbox/base/status/status.cc @@ -60,6 +60,20 @@ const char* kStatusCodeString[] = { "End flag", }; +const char* kStatusCodeRawString[] = { + "STATUS_SUCCESS", "STATUS_FAULT", "STATUS_NOTFOUND", + "STATUS_INVALID", "STATUS_AGAIN", "STATUS_BADCONF", + "STATUS_NOMEM", "STATUS_RANGE", "STATUS_EXIST", + "STATUS_INTERNAL", "STATUS_BUSY", "STATUS_PERMIT", + "STATUS_NOTSUPPORT", "STATUS_NODATA", "STATUS_NOSPACE", + "STATUS_NOBUFS", "STATUS_OVERFLOW", "STATUS_INPROGRESS", + "STATUS_ALREADY", "STATUS_TIMEDOUT", "STATUS_NOSTREAM", + "STATUS_RESET", "STATUS_CONTINUE", "STATUS_EDQUOT", + "STATUS_STOP", "STATUS_SHUTDOWN", "STATUS_EOF", + "STATUS_NOENT", "STATUS_DEADLOCK", "STATUS_NORESPONSE", + "STATUS_IO", +}; + Status::Status() = default; Status::~Status() = default; @@ -90,6 +104,10 @@ Status::Status(const Status& status, const std::string& errmsg) { void Status::Wrap(const Status& status, const StatusCode& code, const std::string& errmsg) { + if (code >= STATUS_LASTFLAG) { + return; + } + code_ = code; errmsg_ = errmsg; wrap_status_ = std::make_shared(status); @@ -131,13 +149,21 @@ std::string Status::ToString() const { } std::string Status::StrCode() const { - if (code_ >= sizeof(kStatusCodeString) / sizeof(char*)) { + if ((size_t)code_ >= sizeof(kStatusCodeString) / sizeof(char*)) { return ""; } return kStatusCodeString[code_]; } +std::string Status::StrStatusCode() const { + if ((size_t)code_ >= sizeof(kStatusCodeString) / sizeof(char*)) { + return ""; + } + + return kStatusCodeRawString[code_]; +} + void Status::SetErrormsg(const std::string& errmsg) { errmsg_ = errmsg; } const std::string& Status::Errormsg() const { return errmsg_; } diff --git a/src/libmodelbox/engine/error.cc b/src/libmodelbox/engine/error.cc index 3a0a8e03b..95f8f9870 100644 --- a/src/libmodelbox/engine/error.cc +++ b/src/libmodelbox/engine/error.cc @@ -14,10 +14,10 @@ * limitations under the License. */ -#include - #include "modelbox/error.h" +#include + namespace modelbox { FlowUnitError::FlowUnitError(std::string desc) { desc_ = std::move(desc); } @@ -34,9 +34,10 @@ FlowUnitError::FlowUnitError(const std::string& node, FlowUnitError::~FlowUnitError() = default; std::string FlowUnitError::GetDesc() { return desc_; }; +Status FlowUnitError::GetStatus() { return error_status_; }; -DataError::DataError(const std::string &error_code, - const std::string &error_msg) { +DataError::DataError(const std::string& error_code, + const std::string& error_msg) { error_code_ = error_code; error_msg_ = error_msg; new_error_ = true; diff --git a/src/libmodelbox/engine/external_data_map.cc b/src/libmodelbox/engine/external_data_map.cc index 637f16e98..0f8a52271 100644 --- a/src/libmodelbox/engine/external_data_map.cc +++ b/src/libmodelbox/engine/external_data_map.cc @@ -288,6 +288,12 @@ std::shared_ptr ExternalDataMapImpl::GetSessionConfig() { return ctx->GetConfig(); } +void ExternalDataMapImpl::SetPrivate(std::shared_ptr ptr) { + private_ptr_ = ptr; +} + +std::shared_ptr ExternalDataMapImpl::GetPrivate() { return private_ptr_; } + void ExternalDataMapImpl::SetLastError(std::shared_ptr error) { last_error_ = std::move(error); } diff --git a/src/libmodelbox/engine/flow_stream_io.cc b/src/libmodelbox/engine/flow_stream_io.cc index 6a79fdbd9..ffd0fd3c8 100644 --- a/src/libmodelbox/engine/flow_stream_io.cc +++ b/src/libmodelbox/engine/flow_stream_io.cc @@ -45,6 +45,9 @@ Status FlowStreamIO::Recv(const std::string &output_name, auto status = data_map_->Recv(map_buffer_list, timeout); if (!status) { + if (status == STATUS_EOF) { + return status; + } MBLOG_ERROR << "Recv data failed, ret " << status; return status; } diff --git a/src/libmodelbox/include/modelbox/error.h b/src/libmodelbox/include/modelbox/error.h index 3933f1304..aa5f9e0db 100644 --- a/src/libmodelbox/include/modelbox/error.h +++ b/src/libmodelbox/include/modelbox/error.h @@ -30,6 +30,7 @@ class FlowUnitError { const Status& error_status); virtual ~FlowUnitError(); std::string GetDesc(); + Status GetStatus(); private: std::string desc_; diff --git a/src/libmodelbox/include/modelbox/external_data_map.h b/src/libmodelbox/include/modelbox/external_data_map.h index 97511d5fa..f69973921 100644 --- a/src/libmodelbox/include/modelbox/external_data_map.h +++ b/src/libmodelbox/include/modelbox/external_data_map.h @@ -45,6 +45,15 @@ class ExternalDataMap : public SessionIO { virtual std::shared_ptr GetSessionContext() = 0; virtual std::shared_ptr GetSessionConfig() = 0; virtual std::shared_ptr GetLastError() = 0; + + virtual void SetPrivate(std::shared_ptr ptr) = 0; + + virtual std::shared_ptr GetPrivate() = 0; + + template + inline std::shared_ptr GetPrivate() { + return std::static_pointer_cast(GetPrivate()); + } }; class ExternalDataMapImpl @@ -74,6 +83,10 @@ class ExternalDataMapImpl std::shared_ptr GetSessionConfig() override; + void SetPrivate(std::shared_ptr ptr) override; + + std::shared_ptr GetPrivate() override; + void SetLastError(std::shared_ptr error); std::shared_ptr GetLastError() override; @@ -127,6 +140,7 @@ class ExternalDataMapImpl bool close_flag_{false}; bool shutdown_flag_{false}; std::recursive_mutex close_state_lock_; + std::shared_ptr private_ptr_; }; class ExternalDataSelect diff --git a/src/libmodelbox/include/modelbox/flowunit.h b/src/libmodelbox/include/modelbox/flowunit.h index 26464f057..bbdd65552 100644 --- a/src/libmodelbox/include/modelbox/flowunit.h +++ b/src/libmodelbox/include/modelbox/flowunit.h @@ -527,6 +527,11 @@ class FlowUnitStreamContext { std::shared_ptr GetPrivate(const std::string &key); + template + inline std::shared_ptr GetPrivate(const std::string &key) { + return std::static_pointer_cast(GetPrivate(key)); + } + Status CloseAll(); Status Close(const std::string &port); diff --git a/src/libmodelbox/include/modelbox/graph_checker.h b/src/libmodelbox/include/modelbox/graph_checker.h index 8659f3843..4eb86e37b 100644 --- a/src/libmodelbox/include/modelbox/graph_checker.h +++ b/src/libmodelbox/include/modelbox/graph_checker.h @@ -86,10 +86,7 @@ class LeastCommonAncestor { const std::string &port_name, IndexPortType &port_type); std::unordered_map> all_nodes_; - - int nodes_num_; std::map> paths_; - std::unordered_map index_name_map_; std::unordered_map name_index_map_; }; diff --git a/src/libmodelbox/include/modelbox/inner_event.h b/src/libmodelbox/include/modelbox/inner_event.h index 758ae14f1..57ed96ce9 100644 --- a/src/libmodelbox/include/modelbox/inner_event.h +++ b/src/libmodelbox/include/modelbox/inner_event.h @@ -33,6 +33,11 @@ class FlowUnitEvent { const std::shared_ptr &private_content); std::shared_ptr GetPrivate(const std::string &key); + template + inline std::shared_ptr GetPrivate(const std::string &key) { + return std::static_pointer_cast(GetPrivate(key)); + } + private: std::unordered_map> private_map_; }; diff --git a/src/libmodelbox/include/modelbox/session_context.h b/src/libmodelbox/include/modelbox/session_context.h index 23b17cf79..4eda497a9 100644 --- a/src/libmodelbox/include/modelbox/session_context.h +++ b/src/libmodelbox/include/modelbox/session_context.h @@ -56,6 +56,16 @@ class SessionContext { */ std::shared_ptr GetPrivate(const std::string &key); + /** + * @brief Get private data from session context + * @param key private data key + * @return private data + */ + template + inline std::shared_ptr GetPrivate(const std::string &key) { + return std::static_pointer_cast(GetPrivate(key)); + } + /** * @brief Get private data typeid from session context * @param key private data key diff --git a/src/modelbox/manager/src/manager.c b/src/modelbox/manager/src/manager.c index 38f2d1fee..8f5cddb3c 100644 --- a/src/modelbox/manager/src/manager.c +++ b/src/modelbox/manager/src/manager.c @@ -173,7 +173,7 @@ int manager_reload(void) { return -1; } - tlog_setlevel(conf_log_level); + tlog_setlevel((tlog_level)conf_log_level); manager_reload_apps(oldapps); @@ -360,7 +360,7 @@ int manager_init(const char *conf_file, char *name) { } tlog_setlogscreen(g_is_verbose); - tlog_setlevel(conf_log_level); + tlog_setlevel((tlog_level)conf_log_level); manager_log(MANAGER_LOG_INFO, "%s starting... (Build : %s %s)", program_invocation_short_name, __DATE__, __TIME__); diff --git a/src/modelbox/server/CMakeLists.txt b/src/modelbox/server/CMakeLists.txt index dbf2bd20f..2fb9e40ad 100644 --- a/src/modelbox/server/CMakeLists.txt +++ b/src/modelbox/server/CMakeLists.txt @@ -16,8 +16,6 @@ cmake_minimum_required(VERSION 3.10) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic") - if(DUKTAPE_FOUND) add_definitions(-DENABLE_JS_PLUGIN) endif() @@ -52,6 +50,7 @@ set(HEADER add_subdirectory(plugin) add_executable(modelbox-server ${MODELBOX_SOURCES}) +set_target_properties(modelbox-server PROPERTIES ENABLE_EXPORTS 1) target_link_libraries(modelbox-server ${LIBMODELBOX_SHARED}) target_link_libraries(modelbox-server ${MODELBOX_COMMON_LIBRARY}) target_link_libraries(modelbox-server pthread) diff --git a/src/modelbox/tool/CMakeLists.txt b/src/modelbox/tool/CMakeLists.txt index c172f1e64..787e06d37 100644 --- a/src/modelbox/tool/CMakeLists.txt +++ b/src/modelbox/tool/CMakeLists.txt @@ -35,6 +35,7 @@ set(HEADER ) add_executable(modelbox-tool ${MODELBOX_TOOL_SOURCES}) +set_target_properties(modelbox-tool PROPERTIES ENABLE_EXPORTS 1) target_link_libraries(modelbox-tool ${TLOG_STATIC_LIBRARIES}) target_link_libraries(modelbox-tool ${LIBMODELBOX_SHARED}) target_link_libraries(modelbox-tool ${MODELBOX_COMMON_LIBRARY}) diff --git a/test/mock/CMakeLists.txt b/test/mock/CMakeLists.txt index 3bed2f678..995d2b36a 100644 --- a/test/mock/CMakeLists.txt +++ b/test/mock/CMakeLists.txt @@ -21,4 +21,5 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) endif() add_subdirectory(drivers) -add_subdirectory(minimodelbox) \ No newline at end of file +add_subdirectory(minimodelbox) +add_subdirectory(flowunit) \ No newline at end of file diff --git a/test/mock/drivers/flowunit_mockflowunit/flowunit_mockflowunit.h b/test/mock/drivers/flowunit_mockflowunit/flowunit_mockflowunit.h index e5ef5ce22..6bb3cf759 100644 --- a/test/mock/drivers/flowunit_mockflowunit/flowunit_mockflowunit.h +++ b/test/mock/drivers/flowunit_mockflowunit/flowunit_mockflowunit.h @@ -32,14 +32,14 @@ class MockFlowUnit : public FlowUnit { MockFlowUnit() = default; ~MockFlowUnit() override = default; - MOCK_METHOD(Status, Open, (const std::shared_ptr &opts)); - MOCK_METHOD(Status, Close, ()); - - MOCK_METHOD(Status, Process, (std::shared_ptr)); - MOCK_METHOD(Status, DataPre, (std::shared_ptr)); - MOCK_METHOD(Status, DataPost, (std::shared_ptr)); - MOCK_METHOD(Status, DataGroupPre, (std::shared_ptr)); - MOCK_METHOD(Status, DataGroupPost, (std::shared_ptr)); + MOCK_METHOD(Status, Open, (const std::shared_ptr &opts), (override)); + MOCK_METHOD(Status, Close, (), (override)); + + MOCK_METHOD(Status, Process, (std::shared_ptr), (override)); + MOCK_METHOD(Status, DataPre, (std::shared_ptr), (override)); + MOCK_METHOD(Status, DataPost, (std::shared_ptr), (override)); + MOCK_METHOD(Status, DataGroupPre, (std::shared_ptr), (override)); + MOCK_METHOD(Status, DataGroupPost, (std::shared_ptr), (override)); }; class MockFlowUnitFactory : public FlowUnitFactory { diff --git a/test/mock/drivers/graph_conf_mockgraphconf/graph_conf_mockgraphconf.h b/test/mock/drivers/graph_conf_mockgraphconf/graph_conf_mockgraphconf.h index 8d85bd5d5..680974008 100644 --- a/test/mock/drivers/graph_conf_mockgraphconf/graph_conf_mockgraphconf.h +++ b/test/mock/drivers/graph_conf_mockgraphconf/graph_conf_mockgraphconf.h @@ -74,10 +74,10 @@ class MockGraphConfigFactory : public modelbox::GraphConfigFactory { ~MockGraphConfigFactory() override = default; MOCK_METHOD(std::shared_ptr, CreateGraphConfigFromStr, - (const std::string &config_path)); + (const std::string &config_path), (override)); MOCK_METHOD(std::shared_ptr, CreateGraphConfigFromFile, - (const std::string &file_path)); - MOCK_METHOD(std::string, GetGraphConfFactoryType, ()); + (const std::string &file_path), (override)); + MOCK_METHOD(std::string, GetGraphConfFactoryType, (), (override)); private: std::shared_ptr bind_factory_; diff --git a/test/mock/flowunit/CMakeLists.txt b/test/mock/flowunit/CMakeLists.txt new file mode 100644 index 000000000..eada4a1c7 --- /dev/null +++ b/test/mock/flowunit/CMakeLists.txt @@ -0,0 +1,36 @@ +# +# Copyright 2021 The Modelbox Project Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +cmake_minimum_required(VERSION 3.10) + +project(modelbox-drivers-test-flowunit) + +if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) + message(FATAL_ERROR "Do not build in source directory!") +endif() + +subdirlist(SUBDIRS ${CMAKE_CURRENT_SOURCE_DIR} "CMakeLists.txt") + +foreach(subdir ${SUBDIRS}) + add_subdirectory(${subdir}) +endforeach() + +list(APPEND DRIVER_UNIT_TEST_INCLUDE ${ACL_INCLUDE_DIR}) +list(APPEND DRIVER_UNIT_TEST_INCLUDE ${DSMI_INCLUDE_DIR}) +set(DRIVER_UNIT_TEST_INCLUDE ${DRIVER_UNIT_TEST_INCLUDE} CACHE INTERNAL "") +list(APPEND DRIVER_UNIT_TEST_LINK_LIBRARIES ${ACL_LIBRARIES}) +list(APPEND DRIVER_UNIT_TEST_LINK_LIBRARIES ${DSMI_LIBRARIES}) +set(DRIVER_UNIT_TEST_LINK_LIBRARIES ${DRIVER_UNIT_TEST_LINK_LIBRARIES} CACHE INTERNAL "") \ No newline at end of file diff --git a/test/mock/flowunit/passthrouth/CMakeLists.txt b/test/mock/flowunit/passthrouth/CMakeLists.txt new file mode 100644 index 000000000..a670d0283 --- /dev/null +++ b/test/mock/flowunit/passthrouth/CMakeLists.txt @@ -0,0 +1,54 @@ +# +# Copyright 2021 The Modelbox Project Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +cmake_minimum_required(VERSION 3.10) + +set(UNIT_DEVICE "cpu") +set(UNIT_NAME "passthrouth") + +project(modelbox-flowunit-${UNIT_DEVICE}-${UNIT_NAME}) + +file(GLOB_RECURSE UNIT_SOURCE *.cpp *.cc *.c) +group_source_test_files(MODELBOX_UNIT_SOURCE MODELBOX_UNIT_TEST_SOURCE "_test.c*" ${UNIT_SOURCE}) + +include_directories(${CMAKE_CURRENT_LIST_DIR}) +include_directories(${LIBMODELBOX_INCLUDE}) +include_directories(${LIBMODELBOX_BASE_INCLUDE}) +include_directories(${LIBMODELBOX_DEVICE_CPU_INCLUDE}) + +set(MODELBOX_UNIT_SHARED libmodelbox-unit-${UNIT_DEVICE}-${UNIT_NAME}-shared) +set(MODELBOX_UNIT_SOURCE_INCLUDE ${CMAKE_CURRENT_LIST_DIR}) + +add_library(${MODELBOX_UNIT_SHARED} SHARED ${MODELBOX_UNIT_SOURCE}) + +set_target_properties(${MODELBOX_UNIT_SHARED} PROPERTIES + SOVERSION ${MODELBOX_VERSION_MAJOR} + VERSION ${MODELBOX_VERSION_MAJOR}.${MODELBOX_VERSION_MINOR}.${MODELBOX_VERSION_PATCH} +) + +target_link_libraries(${MODELBOX_UNIT_SHARED} pthread) +target_link_libraries(${MODELBOX_UNIT_SHARED} rt) +target_link_libraries(${MODELBOX_UNIT_SHARED} dl) +target_link_libraries(${MODELBOX_UNIT_SHARED} ${LIBMODELBOX_DEVICE_CPU_SHARED}) +target_link_libraries(${MODELBOX_UNIT_SHARED} ${LIBMODELBOX_SHARED}) + +set_target_properties(${MODELBOX_UNIT_SHARED} PROPERTIES OUTPUT_NAME "modelbox-unit-${UNIT_DEVICE}-${UNIT_NAME}") + +# driver test +list(APPEND DRIVER_UNIT_TEST_SOURCE ${MODELBOX_UNIT_TEST_SOURCE}) +list(APPEND DRIVER_UNIT_TEST_TARGET ${MODELBOX_UNIT_SHARED}) +set(DRIVER_UNIT_TEST_SOURCE ${DRIVER_UNIT_TEST_SOURCE} CACHE INTERNAL "") +set(DRIVER_UNIT_TEST_TARGET ${DRIVER_UNIT_TEST_TARGET} CACHE INTERNAL "") \ No newline at end of file diff --git a/test/mock/flowunit/passthrouth/passthrouth.cc b/test/mock/flowunit/passthrouth/passthrouth.cc new file mode 100644 index 000000000..caf450a26 --- /dev/null +++ b/test/mock/flowunit/passthrouth/passthrouth.cc @@ -0,0 +1,55 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "passthrouth.h" + +#include "modelbox/flowunit_api_helper.h" + +modelbox::Status PassThrouthFlowUnit::Open( + const std::shared_ptr &opts) { + return modelbox::STATUS_OK; +} + +modelbox::Status PassThrouthFlowUnit::Process( + std::shared_ptr data_ctx) { + auto indata = data_ctx->Input("in"); + auto output = data_ctx->Output("out"); + + for (const auto &buff : *indata) { + output->PushBack(buff); + } + + return modelbox::STATUS_OK; +} + +modelbox::Status PassThrouthFlowUnit::Close() { return modelbox::STATUS_OK; } + +MODELBOX_FLOWUNIT(PassThrouthFlowUnit, desc) { + desc.SetFlowUnitName(FLOWUNIT_NAME); + desc.AddFlowUnitInput({"in"}); + desc.AddFlowUnitOutput({"out"}); + desc.SetFlowType(modelbox::NORMAL); + desc.SetInputContiguous(false); + desc.SetDescription(FLOWUNIT_DESC); +} + +MODELBOX_DRIVER_FLOWUNIT(desc) { + desc.Desc.SetName(FLOWUNIT_NAME); + desc.Desc.SetClass(modelbox::DRIVER_CLASS_FLOWUNIT); + desc.Desc.SetType(FLOWUNIT_TYPE); + desc.Desc.SetDescription(FLOWUNIT_DESC); + desc.Desc.SetVersion("1.0.0"); +} \ No newline at end of file diff --git a/test/mock/flowunit/passthrouth/passthrouth.h b/test/mock/flowunit/passthrouth/passthrouth.h new file mode 100644 index 000000000..91e1e4f1d --- /dev/null +++ b/test/mock/flowunit/passthrouth/passthrouth.h @@ -0,0 +1,46 @@ +/* + * Copyright 2021 The Modelbox Project Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODELBOX_FLOWUNIT_CPU_PASSTHROUGH_H_ +#define MODELBOX_FLOWUNIT_CPU_PASSTHROUGH_H_ + +#include +#include +#include +#include +#include +#include + +constexpr const char *FLOWUNIT_TYPE = "cpu"; +constexpr const char *FLOWUNIT_NAME = "passthrouth"; +constexpr const char *FLOWUNIT_DESC = + "\n\t@Brief: A passthrouth flowunit on cpu device. \n"; + +class PassThrouthFlowUnit : public modelbox::FlowUnit { + public: + PassThrouthFlowUnit() = default; + ~PassThrouthFlowUnit() override = default; + + modelbox::Status Open( + const std::shared_ptr &opts) override; + + modelbox::Status Close() override; + + modelbox::Status Process( + std::shared_ptr data_ctx) override; +}; + +#endif // MODELBOX_FLOWUNIT_CPU_PASSTHROUGH_H_ diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index f61d7894d..993ff254d 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.10) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic") file(GLOB_RECURSE UNIT_TEST_SOURCE *.cpp *.cc *.c) @@ -36,6 +36,8 @@ add_executable(unit EXCLUDE_FROM_ALL ${TEST_MAIN_SOURCE} ) +set_target_properties(unit PROPERTIES ENABLE_EXPORTS 1) + if (TARGET ${MODELBOX_SERVER_PLUGIN_EDITOR}) add_dependencies(unit ${MODELBOX_SERVER_PLUGIN_EDITOR})