Skip to content

Commit

Permalink
ch18: update
Browse files Browse the repository at this point in the history
  • Loading branch information
gav2xlin committed Feb 9, 2025
1 parent 409460c commit 31a3721
Show file tree
Hide file tree
Showing 21 changed files with 345 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Chapter17/minio/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.28)

project(
ch17
MinIO
VERSION 0.0.1
LANGUAGES CXX)

Expand Down
2 changes: 2 additions & 0 deletions Chapter17/minio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ os=Linux

### Building

**Important**: MinIO's dependency requires Python 3

To build the project, configure the Conan profile as described above, cd to its directory, and then run:

```bash
Expand Down
11 changes: 7 additions & 4 deletions Chapter17/s3/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.28)

project(
ch17
S3
VERSION 0.0.1
LANGUAGES CXX)

Expand All @@ -17,8 +17,11 @@ endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}")

find_package(AWSSDK REQUIRED)
find_package(spdlog REQUIRED)

add_executable(s3 s3.cpp)
target_link_libraries(s3 PRIVATE AWS::aws-sdk-cpp-s3 spdlog::spdlog)
if(NOT MSVC)
find_package(AWSSDK REQUIRED)

add_executable(s3 s3.cpp)
target_link_libraries(s3 PRIVATE AWS::aws-sdk-cpp-s3 spdlog::spdlog)
endif()
2 changes: 2 additions & 0 deletions Chapter17/s3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ os=Linux

### Building

**Important**: AWS SDK for C++ requires development libraries out of Conan packages

To build the project, configure the Conan profile as described above, cd to its directory, and then run:

```bash
Expand Down
13 changes: 13 additions & 0 deletions Chapter17/s3/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from conan import ConanFile

class Pkg(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "CMakeDeps"

def requirements(self):
self.requires("spdlog/1.15.0")
if not self.settings.os == "Windows":
self.requires("aws-sdk-cpp/1.11.352")

def build_requirements(self):
pass
6 changes: 0 additions & 6 deletions Chapter17/s3/conanfile.txt

This file was deleted.

57 changes: 57 additions & 0 deletions Chapter18/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
cmake_minimum_required(VERSION 3.15)

project(
Chapter18
VERSION 0.0.1
LANGUAGES CXX)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)

find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
endif()

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}")

include(CommonCompileFlags)

if(NOT MSVC)
find_package(redis++ REQUIRED)

add_executable(redis_client redis/redis.cpp)
target_compile_features(redis_client PRIVATE cxx_std_17)
target_compile_options(redis_client PRIVATE "${BASE_COMPILE_FLAGS}")
target_link_libraries(redis_client PRIVATE redis++::redis++_static)

find_package(gRPC REQUIRED)
find_package(protobuf REQUIRED)
endif()

if(NOT MSVC)
add_library(grpc_service grpc/service.proto)
target_link_libraries(grpc_service PUBLIC protobuf::libprotobuf gRPC::grpc++)

include(protobuf-generate)
protobuf_generate(TARGET grpc_service LANGUAGE cpp)
protobuf_generate(
TARGET
grpc_service
LANGUAGE
grpc
GENERATE_EXTENSIONS
.grpc.pb.h
.grpc.pb.cc
PLUGIN
"protoc-gen-grpc=\$<TARGET_FILE:gRPC::grpc_cpp_plugin>")
target_include_directories(grpc_service PUBLIC "${CMAKE_CURRENT_BINARY_DIR}")

add_executable(grpc_client grpc/AsyncClient.cpp)
target_link_libraries(grpc_client grpc_service)

add_executable(grpc_server grpc/AsyncServer.cpp)
target_link_libraries(grpc_server grpc_service)
endif()
90 changes: 90 additions & 0 deletions Chapter18/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Software Architecture with C++, Second Edition

Software Architecture with C++, Second Edition, Published by Packt

## Chapter 18: Microservices

### Prerequisites

Install the following software:

- CMake 3.28
- Conan 2.12.1
- GCC 14

Assuming you're on Linux or using WSL, configure a local Conan profile and remotes by running:

```bash
rm -rf ./build/
conan profile detect --name ./build/conan_profile
```

Make sure that the profile section `[settings]` contains:

```text
arch=x86_64
compiler=gcc
compiler.libcxx=libstdc++11
compiler.version=14
os=Linux
```

### Building

To build the project, configure the Conan profile as described above, cd to its directory, and then run:

```bash
cd build
conan install .. --build=missing -s build_type=Release -pr:a=./conan_profile -of .
cmake .. -DCMAKE_BUILD_TYPE=Release # build type must match Conan's
cmake --build .
```

If GCC 14 is not your default compiler, you can tell CMake to use it with the `CMAKE_CXX_COMPILER` flag:

```bash
cd build
conan install .. --build=missing -s build_type=Release -pr:a=./conan_profile -of .
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=`which g++-14` # build type must match Conan's
cmake --build .
```

To pass the settings directly without a Conan profile, use the command line option `--settings:all` or `-s:a`, and the keys `arch`, `build_type`, `compiler`, `compiler.cppstd`, `compiler.libcxx`, `compiler.version`, `os`:

```bash
rm -rf ./build/ && mkdir build && cd build
conan install .. --build=missing -s:a build_type=Release -s:a compiler=gcc -of .
cmake .. -DCMAKE_BUILD_TYPE=Release # build type must match Conan's
cmake --build .
```

To apply Conan dependency as a CMake Dependency Provider, clone this Git repository and then run the next command:

```bash
rm -rf ./build/cmake-conan
git clone https://github.com/conan-io/cmake-conan.git build/cmake-conan
```

```bash
cmake -S . -B build -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./build/cmake-conan/conan_provider.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build build
```

### Docker, Redis, Valkey and Dragonfly

You need to install Docker tools to run the example:

- [Docker Desktop](https://www.docker.com/products/docker-desktop/), [Rancher Desktop](https://rancherdesktop.io/) or [Docker](https://docs.docker.com/engine/install/)
- [Docker Compose](https://docs.docker.com/compose/)

And Redis Insight or Redis CLI to see the results:

- [Redis Insight](https://redis.io/insight/)
- [Redis CLI](https://redis.io/docs/latest/develop/tools/cli/)
- Or on Docker with `./redis/compose-redis-insight.yaml` in this directory

In the last case, open [http://localhost:5540](http://localhost:5540) (Redis Insight UI) in a browser and add these databases:

- redis://default@redis:6379
- redis://default@valkey:6379
- redis://default@dragonfly:6379
5 changes: 5 additions & 0 deletions Chapter18/cmake/CommonCompileFlags.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
list(
APPEND
BASE_COMPILE_FLAGS
"$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:-Wall;-Wextra;-pedantic;-Werror>"
"$<$<CXX_COMPILER_ID:MSVC>:/W4;/WX>")
7 changes: 7 additions & 0 deletions Chapter18/conanfile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[requires]
redis-plus-plus/1.3.13
grpc/1.67.1
protobuf/5.27.0

[generators]
CMakeDeps
28 changes: 28 additions & 0 deletions Chapter18/grpc/AsyncClient.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <grpcpp/grpcpp.h>

#include <string>

#include "grpc/service.grpc.pb.h"

using grpc::ClientContext;
using grpc::Status;

int main() {
std::string address("localhost:50000");
auto channel =
grpc::CreateChannel(address, grpc::InsecureChannelCredentials());
auto stub = Greeter::NewStub(channel);

GreetRequest request;
request.set_name("World");

GreetResponse reply;
ClientContext context;
Status status = stub->Greet(&context, request, &reply);

if (status.ok()) {
std::cout << reply.reply() << '\n';
} else {
std::cerr << "Error: " << status.error_code() << '\n';
}
}
34 changes: 34 additions & 0 deletions Chapter18/grpc/AsyncServer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <grpcpp/grpcpp.h>

#include <string>

#include "grpc/service.grpc.pb.h"

using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using grpc::StatusCode;

class GreeterImpl : public Greeter::Service {
Status Greet(ServerContext *context, const GreetRequest *request,
GreetResponse *reply) override {
auto name = request->name();
if (name.empty()) {
return Status(StatusCode::INVALID_ARGUMENT, "name is empty");
}
reply->set_reply("Hello " + name);
return Status::OK;
}
};

int main() {
std::string address("localhost:50000");
GreeterImpl service;
ServerBuilder builder;

builder.AddListeningPort(address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);

auto server(builder.BuildAndStart());
server->Wait();
}
13 changes: 13 additions & 0 deletions Chapter18/grpc/service.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
syntax = "proto3";

service Greeter {
rpc Greet(GreetRequest) returns (GreetResponse);
}

message GreetRequest {
string name = 1;
}

message GreetResponse {
string reply = 1;
}
6 changes: 6 additions & 0 deletions Chapter18/redis/compose-dragonfly.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
services:
dragonfly:
image: docker.dragonflydb.io/dragonflydb/dragonfly
hostname: dragonfly
ports:
- "6379:6379"
9 changes: 9 additions & 0 deletions Chapter18/redis/compose-redis-insight.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
redis-insight:
image: redis/redisinsight:latest
ports:
- "5540:5540"
volumes:
- redis-insight:/data
volumes:
redis-insight:
8 changes: 8 additions & 0 deletions Chapter18/redis/compose-redis.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
services:
redis:
image: bitnami/redis:latest
hostname: redis
environment:
- ALLOW_EMPTY_PASSWORD=yes
ports:
- "6379:6379"
8 changes: 8 additions & 0 deletions Chapter18/redis/compose-valkey.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
services:
valkey:
image: bitnami/valkey:latest
hostname: valkey
environment:
- ALLOW_EMPTY_PASSWORD=yes
ports:
- "6379:6379"
32 changes: 32 additions & 0 deletions Chapter18/redis/redis.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <sw/redis++/redis++.h>

#include <algorithm>
#include <iostream>
#include <iterator>

using namespace std;
using namespace sw::redis;

int main() {
try {
auto redis = Redis("tcp://127.0.0.1:6379");

redis.set("key", "val");
if (const auto val = redis.get("key")) {
cout << *val << endl;
}

redis.del("list");

redis.rpush("list", {"a", "b", "c"});
std::vector<std::string> vec;
redis.lrange("list", 0, -1, std::back_inserter(vec));

std::copy(vec.begin(), vec.end(),
std::ostream_iterator<std::string>(std::cout, " "));
} catch (const Error& e) {
cerr << "Error: " << e.what() << endl;
}

return 0;
}
10 changes: 10 additions & 0 deletions docs/devenv_linux.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,13 @@ Conan is [integrated](https://docs.conan.io/2/integrations.html) with different
[Qt Creator](https://doc.qt.io/qtcreator/creator-project-conan.html) ([plugin](https://doc.qt.io/qtcreator/creator-project-conan.html)) and
[Visual Studio Code](https://code.visualstudio.com/docs/cpp/cmake-quickstart) ([plugin](https://marketplace.visualstudio.com/items?itemName=afri-bit.vsconan))
that support CMake-based projects.

Install Docker:

- [Ubuntu](https://docs.docker.com/engine/install/ubuntu/)
- [Debian](https://docs.docker.com/engine/install/debian/)
- [Fedora](https://docs.docker.com/engine/install/fedora/)
- [CentOS](https://docs.docker.com/engine/install/centos/)
- [RHEL](https://docs.docker.com/engine/install/rhel/)
- [Rancher Desktop](https://rancherdesktop.io/)
- [Docker Desktop](https://docs.docker.com/desktop/)
Loading

0 comments on commit 31a3721

Please sign in to comment.