From a0b566775bacd842f4fe6917c63ca7043094542f Mon Sep 17 00:00:00 2001 From: Eric Ren Date: Fri, 7 Oct 2022 18:48:12 +0100 Subject: [PATCH 1/2] [SDK-604]Demo to invoke ECS S3 Java client SDK in c++. --- ecs-cpp-jni-s3-workshop/CMakeLists.txt | 40 +++++ ecs-cpp-jni-s3-workshop/CMakePresets.json | 101 ++++++++++++ ecs-cpp-jni-s3-workshop/README.txt | 13 ++ .../examples/01_getversion.cpp | 45 ++++++ .../examples/02_listbucket.cpp | 55 +++++++ ecs-cpp-jni-s3-workshop/lib/ecss3client.cpp | 55 +++++++ ecs-cpp-jni-s3-workshop/lib/ecss3client.h | 27 ++++ ecs-cpp-jni-s3-workshop/lib/ecss3factory.cpp | 146 ++++++++++++++++++ ecs-cpp-jni-s3-workshop/lib/ecss3factory.h | 50 ++++++ 9 files changed, 532 insertions(+) create mode 100644 ecs-cpp-jni-s3-workshop/CMakeLists.txt create mode 100644 ecs-cpp-jni-s3-workshop/CMakePresets.json create mode 100644 ecs-cpp-jni-s3-workshop/README.txt create mode 100644 ecs-cpp-jni-s3-workshop/examples/01_getversion.cpp create mode 100644 ecs-cpp-jni-s3-workshop/examples/02_listbucket.cpp create mode 100644 ecs-cpp-jni-s3-workshop/lib/ecss3client.cpp create mode 100644 ecs-cpp-jni-s3-workshop/lib/ecss3client.h create mode 100644 ecs-cpp-jni-s3-workshop/lib/ecss3factory.cpp create mode 100644 ecs-cpp-jni-s3-workshop/lib/ecss3factory.h diff --git a/ecs-cpp-jni-s3-workshop/CMakeLists.txt b/ecs-cpp-jni-s3-workshop/CMakeLists.txt new file mode 100644 index 0000000..9e777a2 --- /dev/null +++ b/ecs-cpp-jni-s3-workshop/CMakeLists.txt @@ -0,0 +1,40 @@ +# CMakeList.txt : CMake project for ecs-cpp-jni-s3-workshop, include source and define +# project specific logic here. +# +cmake_minimum_required (VERSION 3.8) + +project ("ecs-cpp-jni-s3-workshop") + +find_package(Java REQUIRED) +message(STATUS "JAVA_HOME= $ENV{JAVA_HOME}") +message(STATUS "") + +find_package(JNI REQUIRED) +message(STATUS "JNI_INCLUDE_DIRS= ${JNI_INCLUDE_DIRS}") +message(STATUS "") + +if (NOT MSVC) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + find_library(STD_CPP_FS stdc++fs) +endif() + +include_directories(${JNI_INCLUDE_DIRS} ${_classDir} ${_stubDir}) + +# Add source to this project's executable. +add_library(ecss3factorylib STATIC "lib/ecss3factory.cpp" "lib/ecss3client.cpp") +target_link_libraries(ecss3factorylib ${JNI_LIBRARIES} ) + +add_executable (example-getversion "examples/01_getversion.cpp") +target_link_libraries(example-getversion ${JNI_LIBRARIES} ecss3factorylib) + +add_executable (example-listbucket "examples/02_listbucket.cpp") +target_link_libraries(example-listbucket ${JNI_LIBRARIES} ecss3factorylib) + +if (CMAKE_VERSION VERSION_GREATER 3.12) + set_property(TARGET ecss3factorylib PROPERTY CXX_STANDARD 20) + set_property(TARGET example-getversion PROPERTY CXX_STANDARD 20) + set_property(TARGET example-listbucket PROPERTY CXX_STANDARD 20) +endif() + +# TODO: Add tests and install targets if needed. diff --git a/ecs-cpp-jni-s3-workshop/CMakePresets.json b/ecs-cpp-jni-s3-workshop/CMakePresets.json new file mode 100644 index 0000000..f4bc98b --- /dev/null +++ b/ecs-cpp-jni-s3-workshop/CMakePresets.json @@ -0,0 +1,101 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "windows-base", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "installDir": "${sourceDir}/out/install/${presetName}", + "cacheVariables": { + "CMAKE_C_COMPILER": "cl.exe", + "CMAKE_CXX_COMPILER": "cl.exe" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + }, + { + "name": "x64-debug", + "displayName": "x64 Debug", + "inherits": "windows-base", + "architecture": { + "value": "x64", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "x64-release", + "displayName": "x64 Release", + "inherits": "x64-debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "x86-debug", + "displayName": "x86 Debug", + "inherits": "windows-base", + "architecture": { + "value": "x86", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "x86-release", + "displayName": "x86 Release", + "inherits": "x86-debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "linux-debug", + "displayName": "Linux Debug", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "installDir": "${sourceDir}/out/install/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Linux" + }, + "vendor": { + "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { + "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" + } + } + }, + { + "name": "macos-debug", + "displayName": "macOS Debug", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "installDir": "${sourceDir}/out/install/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Darwin" + }, + "vendor": { + "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { + "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" + } + } + } + ] +} diff --git a/ecs-cpp-jni-s3-workshop/README.txt b/ecs-cpp-jni-s3-workshop/README.txt new file mode 100644 index 0000000..d9b4e71 --- /dev/null +++ b/ecs-cpp-jni-s3-workshop/README.txt @@ -0,0 +1,13 @@ +The sample demonstrates how to invoke ECS S3 Java SDK in C++. It's created to fit in some specific customer use scenario, however, we always recommend to directly use ECS S3 Java SDK if possible or seek alternative S3 SDKs available in C++ from other vendors. +std::filesystem is used to simplify the jar discovery thus compiler needs to support C++17 or later. The code is generally platform independent with compiler and operating system properly configured. + +Setup: +------ +1. Unzip ECS S3 Java SDK package and fill in the path to below: + ECSS3Factory::libPath in lib/ecss3factory.h +2. Fill in S3 connection info to below: + ECSS3Factory::S3_URI,S3_ACCESS_KEY_ID,S3_SECRET_KEY in lib/ecss3factory.h + +Build: +------ +#cmake --build . diff --git a/ecs-cpp-jni-s3-workshop/examples/01_getversion.cpp b/ecs-cpp-jni-s3-workshop/examples/01_getversion.cpp new file mode 100644 index 0000000..7fd61bd --- /dev/null +++ b/ecs-cpp-jni-s3-workshop/examples/01_getversion.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 DELL/EMC Corporation + * All Rights Reserved + * + * This software contains the intellectual property of DELL/EMC Corporation + * or is licensed to DELL/EMC Corporation from third parties. Use of this + * software and the intellectual property contained therein is expressly + * limited to the terms and conditions of the License Agreement under which + * it is provided by or on behalf of DELL/EMC. + */ + +#include "../lib/ecss3client.h" + +int main() { + ECSS3Client s3client = ECSS3Client(); + ECSS3Factory* s3factory = s3client.getECSS3Factory(); + jobject listDataNodesResult = s3client.listDataNodes(); + + if (listDataNodesResult == nullptr) { + cout << "failed to list data nodes"; + return -1; + } + + jclass jc_ListDataNode = s3factory->findClass("com/emc/object/s3/bean/ListDataNode"); + jmethodID jm_ListDataNode_getVersionInfo = s3factory->getMethodID(jc_ListDataNode, "getVersionInfo", "()Ljava/lang/String;"); + jstring versionInfo = (jstring)s3factory->getJNIEnv()->CallObjectMethod(listDataNodesResult, jm_ListDataNode_getVersionInfo); + cout << "ECS Version:" << s3factory->getJNIEnv()->GetStringUTFChars(versionInfo, 0) << endl; + + jmethodID jm_ListDataNode_getDataNodes = s3factory->getMethodID(jc_ListDataNode, "getDataNodes", "()Ljava/util/List;"); + jobject dataNodeList = s3factory->getJNIEnv()->CallObjectMethod(listDataNodesResult, jm_ListDataNode_getDataNodes); + + jclass jc_List = s3factory->findClass("java/util/List"); + jmethodID jm_List_getsize = s3factory->getMethodID(jc_List, "size", "()I"); + jint size = s3factory->getJNIEnv()->CallIntMethod(dataNodeList, jm_List_getsize); + cout << "Total number of Nodes:" << size << endl; + + jmethodID jm_List_get = s3factory->getJNIEnv()->GetMethodID(jc_List, "get", "(I)Ljava/lang/Object;"); + for (int i = 0; i < size; i++) { + jstring nodeName = (jstring)s3factory->getJNIEnv()->CallObjectMethod(dataNodeList, jm_List_get, i); + const char* str = s3factory->getJNIEnv()->GetStringUTFChars(nodeName, 0); + cout << str << endl; + } + + return 0; +} \ No newline at end of file diff --git a/ecs-cpp-jni-s3-workshop/examples/02_listbucket.cpp b/ecs-cpp-jni-s3-workshop/examples/02_listbucket.cpp new file mode 100644 index 0000000..81cf3ed --- /dev/null +++ b/ecs-cpp-jni-s3-workshop/examples/02_listbucket.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 DELL/EMC Corporation + * All Rights Reserved + * + * This software contains the intellectual property of DELL/EMC Corporation + * or is licensed to DELL/EMC Corporation from third parties. Use of this + * software and the intellectual property contained therein is expressly + * limited to the terms and conditions of the License Agreement under which + * it is provided by or on behalf of DELL/EMC. + */ + +#include "../lib/ecss3client.h" + +int main() { + ECSS3Client s3client = ECSS3Client(); + ECSS3Factory* s3factory = s3client.getECSS3Factory(); + string bucket = "ecs-cpp-jini-s3-bucket"; + s3client.createBucket(bucket); + + jobject listBucketsResult = s3client.listBuckets(); + + if (listBucketsResult == nullptr) { + cout << "failed to list bucket"; + return -1; + } + + //Print listed buckets + jclass jc_ListBucketsResult = s3factory->findClass("com/emc/object/s3/bean/ListBucketsResult"); + + jmethodID jmgetBuckets = s3factory->getMethodID(jc_ListBucketsResult, "getBuckets", "()Ljava/util/List;"); + jobject bucketList = s3factory->getJNIEnv()->CallObjectMethod(listBucketsResult, jmgetBuckets); + + jclass jcList = s3factory->findClass("java/util/List"); + jmethodID jm_List_getsize = s3factory->getMethodID(jcList, "size", "()I"); + jint size = s3factory->getJNIEnv()->CallIntMethod(bucketList, jm_List_getsize); + cout << "Total number of buckets:" << size << endl; + + jmethodID jmget = s3factory->getJNIEnv()->GetMethodID(jcList, "get", "(I)Ljava/lang/Object;"); + + jclass jc_Bucket = s3factory->findClass("com/emc/object/s3/bean/Bucket"); + jmethodID jm_Bucket_getName = s3factory->getMethodID(jc_Bucket, "getName", "()Ljava/lang/String;"); + for (int i = 0; i < size; i++) { + jobject myobj = s3factory->getJNIEnv()->CallObjectMethod(bucketList, jmget, i); + + jstring bucketName = (jstring)s3factory->getJNIEnv()->CallObjectMethod(myobj, jm_Bucket_getName); + const char* str = s3factory->getJNIEnv()->GetStringUTFChars(bucketName, 0); + if (bucket.compare(str) == 0) { + cout << str << "\t----(bucket created and found!)" << endl; + } + else { + cout << str << endl; + } + } + return 0; +} \ No newline at end of file diff --git a/ecs-cpp-jni-s3-workshop/lib/ecss3client.cpp b/ecs-cpp-jni-s3-workshop/lib/ecss3client.cpp new file mode 100644 index 0000000..0cf9088 --- /dev/null +++ b/ecs-cpp-jni-s3-workshop/lib/ecss3client.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 DELL/EMC Corporation + * All Rights Reserved + * + * This software contains the intellectual property of DELL/EMC Corporation + * or is licensed to DELL/EMC Corporation from third parties. Use of this + * software and the intellectual property contained therein is expressly + * limited to the terms and conditions of the License Agreement under which + * it is provided by or on behalf of DELL/EMC. + */ + +#include "ecss3client.h" + +ECSS3Factory* ECSS3Client::s3factory = nullptr; +jobject ECSS3Client::s3client = nullptr; + +ECSS3Client::ECSS3Client(){ + if (s3factory == nullptr) { + s3factory = new ECSS3Factory(); + } + if (s3client == nullptr) { + s3client = s3factory->getS3Client(); + jc_S3JerseyClient = s3factory->findClass("com/emc/object/s3/jersey/S3JerseyClient"); + } +} + +ECSS3Client::~ECSS3Client() { + if (s3factory != nullptr) { + delete s3factory; + s3factory = nullptr; + } +} + +ECSS3Factory* ECSS3Client::getECSS3Factory() { + return s3factory; +} + +jobject ECSS3Client::listDataNodes() { + jmethodID jm_S3JerseyClient_listDataNodes = s3factory->getMethodID(jc_S3JerseyClient, "listDataNodes", "()Lcom/emc/object/s3/bean/ListDataNode;"); + jobject listDataNode = s3factory->getJNIEnv()->CallObjectMethod(s3client, jm_S3JerseyClient_listDataNodes); + return listDataNode; + +} + +jobject ECSS3Client::listBuckets() { + jmethodID jm_S3JerseyClient_listBucket = s3factory->getMethodID(jc_S3JerseyClient, "listBuckets", "()Lcom/emc/object/s3/bean/ListBucketsResult;"); + jobject listBucketsResult = s3factory->getJNIEnv()->CallObjectMethod(s3client, jm_S3JerseyClient_listBucket); + + return listBucketsResult; +} + +void ECSS3Client::createBucket(string bucket) { + jmethodID jm_S3JerseyClient_createBucket = s3factory->getMethodID(jc_S3JerseyClient, "createBucket", "(Ljava/lang/String;)V"); + s3factory->getJNIEnv()->CallObjectMethod(s3client, jm_S3JerseyClient_createBucket, s3factory->getJNIEnv()->NewStringUTF(bucket.c_str())); +} \ No newline at end of file diff --git a/ecs-cpp-jni-s3-workshop/lib/ecss3client.h b/ecs-cpp-jni-s3-workshop/lib/ecss3client.h new file mode 100644 index 0000000..494a35f --- /dev/null +++ b/ecs-cpp-jni-s3-workshop/lib/ecss3client.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 DELL/EMC Corporation + * All Rights Reserved + * + * This software contains the intellectual property of DELL/EMC Corporation + * or is licensed to DELL/EMC Corporation from third parties. Use of this + * software and the intellectual property contained therein is expressly + * limited to the terms and conditions of the License Agreement under which + * it is provided by or on behalf of DELL/EMC. + */ + +#pragma once +#include "ecss3factory.h" + +class ECSS3Client { + static ECSS3Factory* s3factory; + static jobject s3client; + jclass jc_S3JerseyClient; + +public: + ECSS3Client(); + ~ECSS3Client(); + ECSS3Factory* getECSS3Factory(); + jobject listDataNodes(); + jobject listBuckets(); + void createBucket(string bucke); +}; \ No newline at end of file diff --git a/ecs-cpp-jni-s3-workshop/lib/ecss3factory.cpp b/ecs-cpp-jni-s3-workshop/lib/ecss3factory.cpp new file mode 100644 index 0000000..0bf46b7 --- /dev/null +++ b/ecs-cpp-jni-s3-workshop/lib/ecss3factory.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2022 DELL/EMC Corporation + * All Rights Reserved + * + * This software contains the intellectual property of DELL/EMC Corporation + * or is licensed to DELL/EMC Corporation from third parties. Use of this + * software and the intellectual property contained therein is expressly + * limited to the terms and conditions of the License Agreement under which + * it is provided by or on behalf of DELL/EMC. + */ + +#include "ecss3factory.h" + +using namespace std; + +map ECSS3Factory::_classInfo = {}; +jobject ECSS3Factory::s3client = nullptr; + +void ECSS3Factory::appendClassPath(string& option, string path) { + for (const auto& file : std::filesystem::recursive_directory_iterator(path.c_str())) { + if (!file.is_directory() && file.path().extension().compare(".jar") == 0) { + option += file.path().generic_string() + os_pathsep; + } + } +} + +int ECSS3Factory::setupJNI() { + //==================== prepare loading of Java VM ============================ + JavaVMInitArgs vm_args; // Initialization arguments + JavaVMOption* options = new JavaVMOption[2]; // JVM invocation options + string classPathOption = "-Djava.class.path="; + string option2 = "-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true"; + appendClassPath(classPathOption, libPath); + options[0].optionString = (char*)classPathOption.c_str(); + options[1].optionString = (char*)option2.c_str(); + vm_args.version = JNI_VERSION_1_8; // minimum Java version + vm_args.nOptions = 2; // number of options + vm_args.options = options; + vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail + + //================= load and initialize Java VM and JNI interface =============== + jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); + + if (rc != JNI_OK) { + if (rc == JNI_EVERSION) + cerr << "FATAL ERROR: JVM is oudated and doesn't meet requirements" << endl; + else if (rc == JNI_ENOMEM) + cerr << "FATAL ERROR: not enough memory for JVM" << endl; + else if (rc == JNI_EINVAL) + cerr << "FATAL ERROR: invalid ragument for launching JVM" << endl; + else if (rc == JNI_EEXIST) + cerr << "FATAL ERROR: the process can only launch one JVM an not more" << endl; + else + cerr << "FATAL ERROR: could not create the JVM instance (error code " << rc << ")" << endl; + } + else { + jint ver = env->GetVersion(); + cout << "JVM load succeeded. \nJNI Version " << ((ver >> 16) & 0x0f) << "." << (ver & 0x0f) << endl; + } + delete[] options; + return rc; +} + + +ECSS3Factory::ECSS3Factory() { + if (setupJNI() != JNI_OK) { + cerr << "Failed to setup JNI!"; + exit(EXIT_FAILURE); + }; +} + +ECSS3Factory::~ECSS3Factory() { + if (jvm != nullptr) { + jvm->DestroyJavaVM(); + jvm = nullptr; + } +} + +JNIEnv* ECSS3Factory::getJNIEnv() { + return env; +} + +jobject ECSS3Factory::getS3Client() { + if (s3client == nullptr) { + jclass jc_URI = findClass("java/net/URI"); + jmethodID jm_URI_Constructor = getMethodID(jc_URI, "", "(Ljava/lang/String;)V"); // FIND AN OBJECT CONSTRUCTOR + jobject uriObject = env->NewObject(jc_URI, jm_URI_Constructor, env->NewStringUTF(S3_URI.c_str())); + + jclass jc_S3Config = findClass("com/emc/object/s3/S3Config"); + jmethodID jm_S3Config_Constructor = env->GetMethodID(jc_S3Config, "", "(Ljava/net/URI;)V"); // FIND AN OBJECT CONSTRUCTOR + jobject s3Config = env->NewObject(jc_S3Config, jm_S3Config_Constructor, uriObject); + if (s3Config == nullptr) { + cout << "ERROR: failed create S3Config!"; + exit(EXIT_FAILURE); + } + + jmethodID jm_S3Config_setIdentity = env->GetMethodID(jc_S3Config, "setIdentity", "(Ljava/lang/String;)V"); + env->CallVoidMethod(s3Config, jm_S3Config_setIdentity, env->NewStringUTF(S3_ACCESS_KEY_ID.c_str())); + + jmethodID jm_S3Config_setSecretKey = env->GetMethodID(jc_S3Config, "setSecretKey", "(Ljava/lang/String;)V"); + env->CallVoidMethod(s3Config, jm_S3Config_setSecretKey, env->NewStringUTF(S3_SECRET_KEY.c_str())); + + jclass jc_S3JerseyClient = findClass("com/emc/object/s3/jersey/S3JerseyClient"); + jmethodID jm_jc_S3JerseyClient_Constructor = env->GetMethodID(jc_S3JerseyClient, "", "(Lcom/emc/object/s3/S3Config;)V"); // FIND AN OBJECT CONSTRUCTOR + s3client = env->NewObject(jc_S3JerseyClient, jm_jc_S3JerseyClient_Constructor, s3Config); + if (s3client == nullptr) { + if (env->ExceptionOccurred()) + env->ExceptionDescribe(); + else + cout << "s3client is null but no exception was thrown." << endl; + exit(EXIT_FAILURE); + } + cout << "s3client is succesfully created!" << endl; + } + return s3client; +} + +jclass ECSS3Factory::findClass(string className) { + if (_classInfo.find(className) != _classInfo.end()) { + return _classInfo[className]; + } + else { + jclass myclass = env->FindClass(className.c_str()); + if (myclass == nullptr) { + if (env->ExceptionOccurred()) + env->ExceptionDescribe(); + cerr << "ERROR: class " << className << " not found !" << endl; + exit(EXIT_FAILURE); + } + else { + _classInfo[className] = myclass; + } + return myclass; + } +} + +jmethodID ECSS3Factory::getMethodID(jclass clazz, string methodName, string sig) { + jmethodID method = env->GetMethodID(clazz, methodName.c_str(), sig.c_str()); + if (method == nullptr) { + if (env->ExceptionOccurred()) + env->ExceptionDescribe(); + cerr << "ERROR: method " << methodName << " " << sig << " not found !" << endl; + exit(EXIT_FAILURE); + } + return method; +} \ No newline at end of file diff --git a/ecs-cpp-jni-s3-workshop/lib/ecss3factory.h b/ecs-cpp-jni-s3-workshop/lib/ecss3factory.h new file mode 100644 index 0000000..842d133 --- /dev/null +++ b/ecs-cpp-jni-s3-workshop/lib/ecss3factory.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 DELL/EMC Corporation + * All Rights Reserved + * + * This software contains the intellectual property of DELL/EMC Corporation + * or is licensed to DELL/EMC Corporation from third parties. Use of this + * software and the intellectual property contained therein is expressly + * limited to the terms and conditions of the License Agreement under which + * it is provided by or on behalf of DELL/EMC. + */ + +#pragma once + +#include +#include +#include +#include +#include + +using namespace std; + +#ifdef _WIN32 + const std::string os_pathsep(";"); +#else + const std::string os_pathsep(":"); +#endif + +class ECSS3Factory { + JavaVM* jvm = nullptr; // Pointer to the JVM (Java Virtual Machine) + JNIEnv* env = nullptr; // Pointer to native interface + //string libPath = "."; + string libPath = "/tmp/test/object-client-3.5.0"; + static map _classInfo; + static jobject s3client; + + string S3_URI = "http://xxx.xxx.xxx.xxx:9020"; + string S3_ACCESS_KEY_ID = "userid"; + string S3_SECRET_KEY = "secretkey"; + + void appendClassPath(string& option, string path); + int setupJNI(); + +public: + ECSS3Factory(); + ~ECSS3Factory(); + JNIEnv* getJNIEnv(); + jobject getS3Client(); + jclass findClass(string className); + jmethodID getMethodID(jclass clazz, string methodName, string sig); +}; \ No newline at end of file From 466fed805af08f4b0b375d9581937444323f1b57 Mon Sep 17 00:00:00 2001 From: Eric Ren Date: Tue, 11 Oct 2022 09:57:57 +0000 Subject: [PATCH 2/2] Update README --- ecs-cpp-jni-s3-workshop/README.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ecs-cpp-jni-s3-workshop/README.txt b/ecs-cpp-jni-s3-workshop/README.txt index d9b4e71..4de21b9 100644 --- a/ecs-cpp-jni-s3-workshop/README.txt +++ b/ecs-cpp-jni-s3-workshop/README.txt @@ -1,5 +1,7 @@ The sample demonstrates how to invoke ECS S3 Java SDK in C++. It's created to fit in some specific customer use scenario, however, we always recommend to directly use ECS S3 Java SDK if possible or seek alternative S3 SDKs available in C++ from other vendors. -std::filesystem is used to simplify the jar discovery thus compiler needs to support C++17 or later. The code is generally platform independent with compiler and operating system properly configured. +std::filesystem is used to simplify the jar discovery thus compiler needs to support C++17 or later. The code is generally platform independent with compiler and operating system properly configured, and tested working in Ubuntu and Windows 10(VS 2022 + vcpkg). + +Currently methods S3JerseyClient::listDataNodes(), S3JerseyClient::createBucket(String bucketName), S3JerseyClient::listBuckets() are implemented, more methods can be added into class ECSS3Client in a similar way. Setup: ------ @@ -10,4 +12,5 @@ Setup: Build: ------ +#cmake . #cmake --build .