Skip to content

[SDK-604]Demo to invoke ECS S3 Java client SDK in c++. #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions ecs-cpp-jni-s3-workshop/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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.
101 changes: 101 additions & 0 deletions ecs-cpp-jni-s3-workshop/CMakePresets.json
Original file line number Diff line number Diff line change
@@ -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}"
}
}
}
]
}
16 changes: 16 additions & 0 deletions ecs-cpp-jni-s3-workshop/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
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, 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:
------
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 .
#cmake --build .
45 changes: 45 additions & 0 deletions ecs-cpp-jni-s3-workshop/examples/01_getversion.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
55 changes: 55 additions & 0 deletions ecs-cpp-jni-s3-workshop/examples/02_listbucket.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
55 changes: 55 additions & 0 deletions ecs-cpp-jni-s3-workshop/lib/ecss3client.cpp
Original file line number Diff line number Diff line change
@@ -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()));
}
27 changes: 27 additions & 0 deletions ecs-cpp-jni-s3-workshop/lib/ecss3client.h
Original file line number Diff line number Diff line change
@@ -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);
};
Loading