-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
samples: modules: thrift: add samples for thrift module
Here we add a client and server samples for the basic "hello" service. These samples are designed to be run by either Zephyr or the host machine, interchangeably. Additionally, there is a python version of the client to demonstrate Thrift's cross-language capabilities. This code was merged from the following repository at the commit specified below, with minor formatting and coding-style modifications. https://github.com/zephyrproject-rtos/gsoc-2022-thrift e12e014d295918cc5ba0b4c507d1bf595a2f539a Signed-off-by: Chris Friedt <cfriedt@meta.com>
- Loading branch information
1 parent
4c90077
commit 5bbbe04
Showing
21 changed files
with
1,037 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Copyright 2022 Meta | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
cmake_minimum_required(VERSION 3.20.0) | ||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
project(thrift_hello_server) | ||
|
||
FILE(GLOB app_sources | ||
src/*.cpp | ||
) | ||
|
||
include(${ZEPHYR_BASE}/modules/thrift/cmake/thrift.cmake) | ||
|
||
set(generated_sources "") | ||
set(gen_dir ${ZEPHYR_BINARY_DIR}/misc/generated/thrift_hello) | ||
list(APPEND generated_sources ${gen_dir}/gen-cpp/hello_types.h) | ||
list(APPEND generated_sources ${gen_dir}/gen-cpp/Hello.cpp) | ||
list(APPEND generated_sources ${gen_dir}/gen-cpp/Hello.h) | ||
list(APPEND app_sources ${generated_sources}) | ||
|
||
thrift( | ||
app | ||
cpp | ||
:no_skeleton | ||
${gen_dir} | ||
${ZEPHYR_BASE}/samples/modules/thrift/hello/hello.thrift | ||
"" | ||
${generated_sources} | ||
) | ||
|
||
target_sources(app PRIVATE ${app_sources}) | ||
|
||
# needed because std::iterator was deprecated with -std=c++17 | ||
target_compile_options(app PRIVATE -Wno-deprecated-declarations) | ||
|
||
# convert .pem files to array data at build time | ||
zephyr_include_directories(${gen_dir}) | ||
|
||
generate_inc_file_for_target( | ||
app | ||
${ZEPHYR_BASE}/samples/modules/thrift/hello/qemu-cert.pem | ||
${gen_dir}/qemu_cert.pem.inc | ||
) | ||
|
||
generate_inc_file_for_target( | ||
app | ||
${ZEPHYR_BASE}/samples/modules/thrift/hello/qemu-key.pem | ||
${gen_dir}/qemu_key.pem.inc | ||
) | ||
|
||
generate_inc_file_for_target( | ||
app | ||
${ZEPHYR_BASE}/samples/modules/thrift/hello/native-cert.pem | ||
${gen_dir}/native_cert.pem.inc | ||
) | ||
|
||
generate_inc_file_for_target( | ||
app | ||
${ZEPHYR_BASE}/samples/modules/thrift/hello/native-key.pem | ||
${gen_dir}/native_key.pem.inc | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# Copyright (c) 2022 Meta | ||
|
||
source "Kconfig.zephyr" | ||
|
||
config THRIFT_COMPACT_PROTOCOL | ||
bool "Use TCompactProtocol in samples" | ||
depends on THRIFT | ||
help | ||
Enable this option to use TCompactProtocol in samples |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Copyright 2022 Meta | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
.PHONY: all clean | ||
|
||
CXXFLAGS := | ||
CXXFLAGS += -std=c++17 | ||
|
||
GEN_DIR = gen-cpp | ||
GENSRC = $(GEN_DIR)/Hello.cpp $(GEN_DIR)/Hello.h $(GEN_DIR)/hello_types.h | ||
GENHDR = $(filter %.h, $(GENSRC)) | ||
GENOBJ = $(filter-out %.h, $(GENSRC:.cpp=.o)) | ||
|
||
THRIFT_FLAGS := | ||
THRIFT_FLAGS += $(shell pkg-config --cflags thrift) | ||
THRIFT_FLAGS += -I$(GEN_DIR) | ||
THRIFT_LIBS = $(shell pkg-config --libs thrift) | ||
|
||
all: hello_client hello_client_compact hello_client_ssl hello_client_py.stamp | ||
|
||
hello_client.stamp: ../hello.thrift | ||
thrift --gen cpp:no_skeleton $< | ||
|
||
$(GENSRC): hello_client.stamp | ||
touch $@ | ||
|
||
%.o: %.cpp $(GENHDR) | ||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(THRIFT_FLAGS) -o $@ -c $< | ||
|
||
hello_client: src/main.cpp $(GENOBJ) $(GENHDR) | ||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(THRIFT_FLAGS) -o $@ $< $(GENOBJ) $(THRIFT_LIBS) | ||
|
||
hello_client_compact: src/main.cpp $(GENOBJ) $(GENHDR) | ||
$(CXX) -DCONFIG_THRIFT_COMPACT_PROTOCOL=1 $(CPPFLAGS) $(CXXFLAGS) $(THRIFT_FLAGS) -o $@ $< $(GENOBJ) $(THRIFT_LIBS) | ||
|
||
hello_client_ssl: src/main.cpp $(GENOBJ) $(GENHDR) | ||
$(CXX) -DCONFIG_THRIFT_SSL_SOCKET=1 $(CPPFLAGS) $(CXXFLAGS) $(THRIFT_FLAGS) -o $@ $< $(GENOBJ) $(THRIFT_LIBS) | ||
|
||
hello_client_py.stamp: ../hello.thrift | ||
thrift --gen py $< | ||
touch $@ | ||
|
||
clean: | ||
rm -Rf hello_client hello_client_compact hello_client_ssl $(GEN_DIR) gen-py *.stamp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#!/usr/bin/env python3 | ||
# Copyright (c) 2023, Meta | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
"""Thrift Hello Client Sample | ||
Connect to a hello service and demonstrate the | ||
ping(), echo(), and counter() Thrift RPC methods. | ||
Usage: | ||
./hello_client.py [ip] | ||
""" | ||
|
||
import argparse | ||
import sys | ||
sys.path.append('gen-py') | ||
|
||
from thrift.protocol import TBinaryProtocol | ||
from thrift.transport import TTransport | ||
from thrift.transport import TSocket | ||
from hello import Hello | ||
|
||
|
||
def parse_args(): | ||
parser = argparse.ArgumentParser(allow_abbrev=False) | ||
parser.add_argument('--ip', default='192.0.2.1', | ||
help='IP address of hello server') | ||
|
||
return parser.parse_args() | ||
|
||
|
||
def main(): | ||
args = parse_args() | ||
|
||
transport = TSocket.TSocket(args.ip, 4242) | ||
transport = TTransport.TBufferedTransport(transport) | ||
protocol = TBinaryProtocol.TBinaryProtocol(transport) | ||
client = Hello.Client(protocol) | ||
|
||
transport.open() | ||
|
||
client.ping() | ||
client.echo('Hello, world!') | ||
|
||
# necessary to mitigate unused variable warning with for i in range(5) | ||
i = 0 | ||
while i < 5: | ||
client.counter() | ||
i = i + 1 | ||
|
||
transport.close() | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# CONFIG_LIB_CPLUSPLUS Dependencies | ||
CONFIG_NEWLIB_LIBC=y | ||
CONFIG_NEWLIB_LIBC_NANO=n | ||
|
||
# CONFIG_THRIFT Dependencies | ||
CONFIG_CPP=y | ||
CONFIG_STD_CPP17=y | ||
CONFIG_CPP_EXCEPTIONS=y | ||
CONFIG_EXTERNAL_LIBCPP=y | ||
CONFIG_POSIX_API=y | ||
CONFIG_NETWORKING=y | ||
CONFIG_NET_SOCKETS=y | ||
CONFIG_NET_SOCKETPAIR=y | ||
CONFIG_HEAP_MEM_POOL_SIZE=16384 | ||
CONFIG_EVENTFD=y | ||
|
||
CONFIG_THRIFT=y | ||
|
||
CONFIG_TEST_RANDOM_GENERATOR=y | ||
# pthread_cond_wait() triggers sentinel for some reason | ||
CONFIG_STACK_SENTINEL=n | ||
|
||
# Generic networking options | ||
CONFIG_NETWORKING=y | ||
CONFIG_NET_UDP=y | ||
CONFIG_NET_TCP=y | ||
CONFIG_NET_IPV6=n | ||
CONFIG_NET_IPV4=y | ||
CONFIG_NET_SOCKETS=y | ||
CONFIG_POSIX_MAX_FDS=6 | ||
CONFIG_NET_CONNECTION_MANAGER=y | ||
|
||
# Kernel options | ||
CONFIG_ENTROPY_GENERATOR=y | ||
CONFIG_TEST_RANDOM_GENERATOR=y | ||
CONFIG_INIT_STACKS=y | ||
|
||
# Logging | ||
CONFIG_NET_LOG=y | ||
CONFIG_LOG=y | ||
CONFIG_NET_STATISTICS=y | ||
CONFIG_PRINTK=y | ||
|
||
# Network buffers | ||
CONFIG_NET_PKT_RX_COUNT=16 | ||
CONFIG_NET_PKT_TX_COUNT=16 | ||
CONFIG_NET_BUF_RX_COUNT=64 | ||
CONFIG_NET_BUF_TX_COUNT=64 | ||
CONFIG_NET_CONTEXT_NET_PKT_POOL=y | ||
|
||
# IP address options | ||
CONFIG_NET_MAX_CONTEXTS=10 | ||
|
||
# Network application options and configuration | ||
CONFIG_NET_CONFIG_SETTINGS=y | ||
CONFIG_NET_CONFIG_NEED_IPV6=n | ||
CONFIG_NET_CONFIG_NEED_IPV4=y | ||
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" | ||
CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" | ||
|
||
# Number of socket descriptors might need adjusting | ||
# if there are more than 1 handlers defined. | ||
CONFIG_POSIX_MAX_FDS=16 | ||
|
||
# Some platforms require relatively large stack sizes. | ||
# This can be tuned per-board. | ||
CONFIG_MAIN_STACK_SIZE=8192 | ||
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=8192 | ||
CONFIG_NET_TCP_WORKQ_STACK_SIZE=4096 | ||
CONFIG_NET_MGMT_EVENT_STACK_SIZE=4096 | ||
CONFIG_IDLE_STACK_SIZE=4096 | ||
CONFIG_NET_RX_STACK_SIZE=8192 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
sample: | ||
description: Hello Thrift client sample | ||
name: hello thrift client | ||
common: | ||
tags: thrift cpp sample | ||
build_only: true | ||
modules: | ||
- thrift | ||
platform_allow: mps2_an385 qemu_x86_64 | ||
tests: | ||
sample.thrift.hello.server.binaryProtocol: {} | ||
sample.thrift.hello.server.compactProtocol: | ||
extra_configs: | ||
- CONFIG_THRIFT_COMPACT_PROTOCOL=y | ||
sample.thrift.hello.server.tlsTransport: | ||
extra_args: OVERLAY_CONFIG="../overlay-tls.conf" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/* | ||
* Copyright 2022 Young Mei | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#ifdef __ZEPHYR__ | ||
#include <zephyr/kernel.h> | ||
#endif | ||
|
||
#include <cstdlib> | ||
#include <iostream> | ||
|
||
#include <fcntl.h> | ||
|
||
#include <thrift/protocol/TBinaryProtocol.h> | ||
#include <thrift/protocol/TCompactProtocol.h> | ||
#include <thrift/transport/TBufferTransports.h> | ||
#include <thrift/transport/TSSLSocket.h> | ||
#include <thrift/transport/TSocket.h> | ||
|
||
#include "Hello.h" | ||
|
||
using namespace apache::thrift; | ||
using namespace apache::thrift::protocol; | ||
using namespace apache::thrift::transport; | ||
|
||
#ifndef IS_ENABLED | ||
#define IS_ENABLED(flag) flag | ||
#endif | ||
|
||
#ifndef CONFIG_THRIFT_COMPACT_PROTOCOL | ||
#define CONFIG_THRIFT_COMPACT_PROTOCOL 0 | ||
#endif | ||
|
||
#ifndef CONFIG_THRIFT_SSL_SOCKET | ||
#define CONFIG_THRIFT_SSL_SOCKET 0 | ||
#endif | ||
|
||
#ifdef __ZEPHYR__ | ||
int main(void) | ||
#else | ||
int main(int argc, char **argv) | ||
#endif | ||
{ | ||
std::string my_addr; | ||
|
||
#ifdef __ZEPHYR__ | ||
my_addr = CONFIG_NET_CONFIG_PEER_IPV4_ADDR; | ||
#else | ||
if (IS_ENABLED(CONFIG_THRIFT_SSL_SOCKET)) { | ||
if (argc != 5) { | ||
printf("usage: %s <ip> <native-cert.pem> <native-key.pem> " | ||
"<qemu-cert.pem>\n", | ||
argv[0]); | ||
return EXIT_FAILURE; | ||
} | ||
} | ||
|
||
if (argc >= 2) { | ||
my_addr = std::string(argv[1]); | ||
} else { | ||
my_addr = "192.0.2.1"; | ||
} | ||
#endif | ||
|
||
int port = 4242; | ||
std::shared_ptr<TProtocol> protocol; | ||
std::shared_ptr<TTransport> transport; | ||
std::shared_ptr<TSSLSocketFactory> socketFactory; | ||
std::shared_ptr<TTransport> trans; | ||
|
||
if (IS_ENABLED(CONFIG_THRIFT_SSL_SOCKET)) { | ||
const int port = 4242; | ||
socketFactory = std::make_shared<TSSLSocketFactory>(); | ||
socketFactory->authenticate(true); | ||
|
||
#ifdef __ZEPHYR__ | ||
static const char qemu_cert_pem[] = { | ||
#include "qemu_cert.pem.inc" | ||
}; | ||
|
||
static const char qemu_key_pem[] = { | ||
#include "qemu_key.pem.inc" | ||
}; | ||
|
||
static const char native_cert_pem[] = { | ||
#include "native_cert.pem.inc" | ||
}; | ||
|
||
socketFactory->loadCertificateFromBuffer(qemu_cert_pem); | ||
socketFactory->loadPrivateKeyFromBuffer(qemu_key_pem); | ||
socketFactory->loadTrustedCertificatesFromBuffer(native_cert_pem); | ||
#else | ||
socketFactory->loadCertificate(argv[2]); | ||
socketFactory->loadPrivateKey(argv[3]); | ||
socketFactory->loadTrustedCertificates(argv[4]); | ||
#endif | ||
trans = socketFactory->createSocket(my_addr, port); | ||
} else { | ||
trans = std::make_shared<TSocket>(my_addr, port); | ||
} | ||
|
||
transport = std::make_shared<TBufferedTransport>(trans); | ||
|
||
if (IS_ENABLED(CONFIG_THRIFT_COMPACT_PROTOCOL)) { | ||
protocol = std::make_shared<TCompactProtocol>(transport); | ||
} else { | ||
protocol = std::make_shared<TBinaryProtocol>(transport); | ||
} | ||
|
||
HelloClient client(protocol); | ||
|
||
try { | ||
transport->open(); | ||
client.ping(); | ||
std::string s; | ||
client.echo(s, "Hello, world!"); | ||
for (int i = 0; i < 5; ++i) { | ||
client.counter(); | ||
} | ||
|
||
transport->close(); | ||
} catch (std::exception &e) { | ||
printf("caught exception: %s\n", e.what()); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
return EXIT_SUCCESS; | ||
} |
Oops, something went wrong.