Skip to content
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

238 refactor dronecore server #295

Merged
merged 4 commits into from
Mar 2, 2018
Merged
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
23 changes: 15 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@ list(APPEND CMAKE_FIND_ROOT_PATH ${CMAKE_BINARY_DIR}/third_party)

project(dronecore)

option(BUILD_TESTS "Build tests" ON)

include(cmake/compiler_flags.cmake)
include(cmake/zlib.cmake)
include(cmake/curl.cmake)

if(BUILD_TESTS AND (IOS OR ANDROID))
message(STATUS "Building for iOS or Android: forcing BUILD_TESTS to FALSE...")
set(BUILD_TESTS OFF)
endif()

if(ANDROID)
set(lib_path "lib/android/${ANDROID_ABI}")
elseif(IOS)
Expand All @@ -31,14 +38,7 @@ if (DEFINED EXTERNAL_DIR AND NOT EXTERNAL_DIR STREQUAL "")
include_directories(${EXTERNAL_DIR})
endif()

if (CMAKE_BUILD_DRONECORESERVER)
message(STATUS "Building dronecore server")
add_subdirectory(grpc/server)
else()
message(STATUS "BUILD_DRONECORESERVER not set: not building dronecore server")
endif()

if(NOT IOS AND NOT ANDROID)
if(BUILD_TESTS)
enable_testing()
add_subdirectory(${CMAKE_SOURCE_DIR}/third_party/gtest EXCLUDE_FROM_ALL)

Expand All @@ -52,6 +52,13 @@ if(NOT IOS AND NOT ANDROID)
include(cmake/unit_tests.cmake)
endif()

if (CMAKE_BUILD_DRONECORESERVER)
message(STATUS "Building dronecore server")
add_subdirectory(grpc/server)
else()
message(STATUS "BUILD_DRONECORESERVER not set: not building dronecore server")
endif()

if (DROP_DEBUG EQUAL 1)
add_definitions(-DDROP_DEBUG=${DROP_DEBUG})

Expand Down
4 changes: 1 addition & 3 deletions cmake/unit_tests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,4 @@ target_link_libraries(unit_tests_runner
gmock
)

add_test(unit_tests
unit_tests_runner
)
add_test(unit_tests unit_tests_runner)
2 changes: 1 addition & 1 deletion core/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ void Device::set_disconnected()
_parent->notify_on_timeout(_target_uuid);

// Let's reset the flag hope again for the next time we see this target.
_target_uuid_initialized = 0;
_target_uuid_initialized = false;
}

{
Expand Down
19 changes: 19 additions & 0 deletions core/mocks/dronecore_mock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <gmock/gmock.h>

#include "connection_result.h"

namespace dronecore {
namespace testing {

typedef std::function<void(uint64_t uuid)> event_callback_t;

class MockDroneCore
{
public:
MOCK_CONST_METHOD1(add_udp_connection, ConnectionResult(int local_port_number));
MOCK_CONST_METHOD1(register_on_discover, void(event_callback_t));
MOCK_CONST_METHOD1(register_on_timeout, void(event_callback_t));
};

} // testing
} // dronecore
6 changes: 5 additions & 1 deletion grpc/server/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 3.1)

project(dronecore-server)

Expand All @@ -9,3 +9,7 @@ include(GNUInstallDirs)
include(cmake/helpers/build_external.cmake)

add_subdirectory(src)

if(BUILD_TESTS)
add_subdirectory(test)
endif()
94 changes: 32 additions & 62 deletions grpc/server/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,67 +1,33 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.1)

file(STRINGS ${PLUGINS_DIR}/plugins.conf PLUGINS_LIST)
set(COMPONENTS_LIST core action mission telemetry)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! No plugin list ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, it is hard-coded. We need to deliver a first version soon. So our first version will not really support plugins (i.e. the backend has all our plugins). Later, we'll upgrade for a more dynamic architecture.

Still, the frontend now should look like the plugins are loaded dynamically, so that it is transparent to the user when we update the backend :-).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK :-)


set(PROTOC_BINARY ${CMAKE_BINARY_DIR}/../default/third_party/protobuf/bin/protoc)
set(GRPC_CPP_PLUGIN_BINARY ${CMAKE_BINARY_DIR}/../default/third_party/grpc/bin/grpc_cpp_plugin)
include(cmake/compile_proto.cmake)

if(NOT EXISTS ${PROTOC_BINARY} OR NOT EXISTS ${GRPC_CPP_PLUGIN_BINARY})
message(FATAL_ERROR "Could not find 'protoc' or 'grpc_cpp_plugin' in the 'default' build folder. Please build for your host first (`make BUILD_DRONECORESERVER=YES default`).")
endif()
foreach(COMPONENT_NAME ${COMPONENTS_LIST})
compile_proto_pb(${COMPONENT_NAME} PB_COMPILED_SOURCE)
list(APPEND PB_COMPILED_SOURCES ${PB_COMPILED_SOURCE})

add_custom_command(OUTPUT core/core.grpc.pb.cc
COMMAND ${PROTOC_BINARY}
-I ${PROTO_DIR}
--grpc_out=.
--plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN_BINARY}
${PROTO_DIR}/core/core.proto;
)

add_custom_command(OUTPUT core/core.pb.cc
COMMAND ${PROTOC_BINARY}
-I ${PROTO_DIR}
--cpp_out=.
${PROTO_DIR}/core/core.proto
)

foreach(PLUGIN ${PLUGINS_LIST})
add_custom_command(OUTPUT ${PLUGIN}/${PLUGIN}.grpc.pb.cc
COMMAND ${PROTOC_BINARY}
-I ${PROTO_DIR}
--grpc_out=.
--plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN_BINARY}
--cpp_out=.
${PROTO_DIR}/${PLUGIN}/${PLUGIN}.proto
)
endforeach()

foreach(PLUGIN ${PLUGINS_LIST})
add_custom_command(OUTPUT ${PLUGIN}/${PLUGIN}.pb.cc
COMMAND ${PROTOC_BINARY}
-I ${PROTO_DIR}
--cpp_out=.
${PROTO_DIR}/${PLUGIN}/${PLUGIN}.proto
)
compile_proto_grpc(${COMPONENT_NAME} GRPC_COMPILED_SOURCE)
list(APPEND GRPC_COMPILED_SOURCES ${GRPC_COMPILED_SOURCE})
endforeach()

set(PLUGINS_SRC dronecore_server.cpp core/core.pb.cc core/core.grpc.pb.cc)
foreach(PLUGIN ${PLUGINS_LIST})
list(APPEND PLUGINS_SRC ${PLUGIN}/${PLUGIN}.pb.cc)
list(APPEND PLUGINS_SRC ${PLUGIN}/${PLUGIN}.grpc.pb.cc)
endforeach()

add_executable(dronecore_server ${PLUGINS_SRC})
add_library(backend
backend.cpp
${GRPC_COMPILED_SOURCES}
${PB_COMPILED_SOURCES}
)

target_compile_options(
dronecore_server
PUBLIC
-Wno-unused-parameter
-Wno-shadow
target_link_libraries(backend
dronecore
dronecore_action
dronecore_mission
dronecore_telemetry
gRPC::grpc++
)

target_include_directories(
dronecore_server
PUBLIC
target_include_directories(backend
PRIVATE
${CMAKE_SOURCE_DIR}/core
${CMAKE_SOURCE_DIR}/plugins/action
${CMAKE_SOURCE_DIR}/plugins/mission
Expand All @@ -70,12 +36,16 @@ target_include_directories(
${PLUGINS_DIR}
)

target_link_libraries(
dronecore_server
add_executable(backend_bin
dronecore_server.cpp
)

target_link_libraries(backend_bin
backend
dronecore
dronecore_action
dronecore_mission
dronecore_telemetry
gRPC::grpc++
dl
)

target_include_directories(backend_bin
PRIVATE
${CMAKE_SOURCE_DIR}/core
)
56 changes: 56 additions & 0 deletions grpc/server/src/backend.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "backend.h"

#include <grpc/grpc.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
#include <grpc++/security/server_credentials.h>

#include "action/actionrpc_impl.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So ideally, backend shall include all plugin header files as it doesn't know what a user wants. Is that right ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, plugins are somehow loaded dynamically. But the first version is hard-coded because it is faster to do xD.

#include "core/corerpc_impl.h"
#include "log.h"
#include "mission/missionrpc_impl.h"
#include "telemetry/telemetryrpc_impl.h"

namespace dronecore {
namespace backend {

bool DroneCoreBackend::run(const int mavlink_listen_port)
{
_connection_initiator.start(_dc, 14540);
_connection_initiator.wait();

grpc::ServerBuilder builder;
setup_port(builder);

CoreServiceImpl core(_dc);
builder.RegisterService(&core);

Action action(&_dc.device());
ActionServiceImpl actionService(action);
builder.RegisterService(&actionService);

Mission mission(&_dc.device());
MissionServiceImpl missionService(mission);
builder.RegisterService(&missionService);

Telemetry telemetry(&_dc.device());
TelemetryServiceImpl telemetryService(telemetry);
builder.RegisterService(&telemetryService);

_server = builder.BuildAndStart();
LogInfo() << "Server started";
_server->Wait();

return true;
}

void DroneCoreBackend::setup_port(grpc::ServerBuilder &builder)
{
std::string server_address("0.0.0.0:50051");
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
LogInfo() << "Server set to listen on " << server_address;
}

} // namespace backend
} //namespace dronecore
29 changes: 29 additions & 0 deletions grpc/server/src/backend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <grpc++/server.h>
#include <memory>
#include <mutex>

#include "connection_initiator.h"
#include "dronecore.h"

namespace dronecore {
namespace backend {

class DroneCoreBackend
{
public:
DroneCoreBackend() {}
~DroneCoreBackend() {}

bool run(const int mavlink_listen_port = 14540);

private:
bool run_server();
void setup_port(grpc::ServerBuilder &builder);

dronecore::DroneCore _dc;
dronecore::backend::ConnectionInitiator<dronecore::DroneCore> _connection_initiator;
std::unique_ptr<grpc::Server> _server;
};

} // namespace backend
} // namespace dronecore
30 changes: 30 additions & 0 deletions grpc/server/src/cmake/compile_proto.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
set(PROTOC_BINARY ${CMAKE_BINARY_DIR}/../default/third_party/protobuf/bin/protoc)
set(GRPC_CPP_PLUGIN_BINARY ${CMAKE_BINARY_DIR}/../default/third_party/grpc/bin/grpc_cpp_plugin)

if(NOT EXISTS ${PROTOC_BINARY} OR NOT EXISTS ${GRPC_CPP_PLUGIN_BINARY})
message(FATAL_ERROR "Could not find 'protoc' or 'grpc_cpp_plugin' in the 'default' build folder. Please build for your host first (`make BUILD_DRONECORESERVER=YES default`).")
endif()

function(compile_proto_pb COMPONENT_NAME PB_COMPILED_SOURCE)
add_custom_command(OUTPUT ${COMPONENT_NAME}/${COMPONENT_NAME}.pb.cc
COMMAND ${PROTOC_BINARY}
-I ${PROTO_DIR}
--cpp_out=.
${PROTO_DIR}/${COMPONENT_NAME}/${COMPONENT_NAME}.proto
)

set(PB_COMPILED_SOURCE ${COMPONENT_NAME}/${COMPONENT_NAME}.pb.cc PARENT_SCOPE)
endfunction()

function(compile_proto_grpc COMPONENT_NAME GRPC_COMPILED_SOURCES)
add_custom_command(OUTPUT ${COMPONENT_NAME}/${COMPONENT_NAME}.grpc.pb.cc
COMMAND ${PROTOC_BINARY}
-I ${PROTO_DIR}
--grpc_out=.
--plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN_BINARY}
--cpp_out=.
${PROTO_DIR}/${COMPONENT_NAME}/${COMPONENT_NAME}.proto
)

set(GRPC_COMPILED_SOURCE ${COMPONENT_NAME}/${COMPONENT_NAME}.grpc.pb.cc PARENT_SCOPE)
endfunction()
Loading