From 5b34bbaa6b0e6e7c1f3fb78810619cd1266ff223 Mon Sep 17 00:00:00 2001 From: =?utf8?q?C=C3=A9dric=20Aguerre?= Date: Fri, 7 Aug 2015 15:54:43 +0200 Subject: [PATCH] API c++ --- projects/GDE_API_CPP/api/CMakeLists.txt | 11 ++ .../api/cmake_files/FindPOCO.cmake | 167 ++++++++++++++++++ projects/GDE_API_CPP/api/src/CMakeLists.txt | 38 ++++ .../GDE_API_CPP/api/src/CommandResultTO.cpp | 28 +++ .../GDE_API_CPP/api/src/CommandResultTO.hpp | 43 +++++ projects/GDE_API_CPP/api/src/CommandTO.cpp | 91 ++++++++++ projects/GDE_API_CPP/api/src/CommandTO.hpp | 41 +++++ .../GDE_API_CPP/api/src/HttpConnection.cpp | 84 +++++++++ .../GDE_API_CPP/api/src/HttpConnection.hpp | 35 ++++ .../GDE_API_CPP/api/src/JsonFormatter.cpp | 30 ++++ .../GDE_API_CPP/api/src/JsonFormatter.hpp | 21 +++ projects/GDE_API_CPP/api/src/User.hpp | 36 ++++ projects/GDE_API_CPP/api/src/UserService.cpp | 55 ++++++ projects/GDE_API_CPP/api/src/UserService.hpp | 37 ++++ 14 files changed, 717 insertions(+) create mode 100644 projects/GDE_API_CPP/api/CMakeLists.txt create mode 100644 projects/GDE_API_CPP/api/cmake_files/FindPOCO.cmake create mode 100644 projects/GDE_API_CPP/api/src/CMakeLists.txt create mode 100644 projects/GDE_API_CPP/api/src/CommandResultTO.cpp create mode 100644 projects/GDE_API_CPP/api/src/CommandResultTO.hpp create mode 100644 projects/GDE_API_CPP/api/src/CommandTO.cpp create mode 100644 projects/GDE_API_CPP/api/src/CommandTO.hpp create mode 100644 projects/GDE_API_CPP/api/src/HttpConnection.cpp create mode 100644 projects/GDE_API_CPP/api/src/HttpConnection.hpp create mode 100644 projects/GDE_API_CPP/api/src/JsonFormatter.cpp create mode 100644 projects/GDE_API_CPP/api/src/JsonFormatter.hpp create mode 100644 projects/GDE_API_CPP/api/src/User.hpp create mode 100644 projects/GDE_API_CPP/api/src/UserService.cpp create mode 100644 projects/GDE_API_CPP/api/src/UserService.hpp diff --git a/projects/GDE_API_CPP/api/CMakeLists.txt b/projects/GDE_API_CPP/api/CMakeLists.txt new file mode 100644 index 0000000..48e3fb4 --- /dev/null +++ b/projects/GDE_API_CPP/api/CMakeLists.txt @@ -0,0 +1,11 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(GdeApiCpp C CXX) + +# Ensure a proper linker behavior: +CMAKE_POLICY(SET CMP0003 NEW) + +LIST(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_files") +FIND_PACKAGE(POCO REQUIRED) +INCLUDE_DIRECTORIES(${Poco_INCLUDE_DIRS}) + +ADD_SUBDIRECTORY(src) diff --git a/projects/GDE_API_CPP/api/cmake_files/FindPOCO.cmake b/projects/GDE_API_CPP/api/cmake_files/FindPOCO.cmake new file mode 100644 index 0000000..dcbd767 --- /dev/null +++ b/projects/GDE_API_CPP/api/cmake_files/FindPOCO.cmake @@ -0,0 +1,167 @@ +# - Find the Poco includes and libraries. +# The following variables are set if Poco is found. If Poco is not +# found, Poco_FOUND is set to false. +# Poco_FOUND - True when the Poco include directory is found. +# Poco_INCLUDE_DIRS - the path to where the poco include files are. +# Poco_LIBRARY_DIRS - The path to where the poco library files are. +# Poco_BINARY_DIRS - The path to where the poco dlls are. + +# ---------------------------------------------------------------------------- +# If you have installed Poco in a non-standard location. +# Then you have three options. +# In the following comments, it is assumed that +# points to the root directory of the include directory of Poco. e.g +# If you have put poco in C:\development\Poco then is +# "C:/development/Poco" and in this directory there will be two +# directories called "include" and "lib". +# 1) After CMake runs, set Poco_INCLUDE_DIR to /poco<-version> +# 2) Use CMAKE_INCLUDE_PATH to set a path to /poco<-version>. This will allow find_path() +# to locate Poco_INCLUDE_DIR by utilizing the PATH_SUFFIXES option. e.g. +# set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "/include") +# 3) Set an environment variable called ${POCO_ROOT} that points to the root of where you have +# installed Poco, e.g. . It is assumed that there is at least a subdirectory called +# Foundation/include/Poco in this path. +# +# Note: +# 1) If you are just using the poco headers, then you do not need to use +# Poco_LIBRARY_DIR in your CMakeLists.txt file. +# 2) If Poco has not been installed, then when setting Poco_LIBRARY_DIR +# the script will look for /lib first and, if this fails, then for /stage/lib. +# +# Usage: +# In your CMakeLists.txt file do something like this: +# ... +# # Poco +# find_package(Poco) +# ... +# include_directories(${Poco_INCLUDE_DIRS}) +# link_directories(${Poco_LIBRARY_DIR}) +# +# In Windows, we make the assumption that, if the Poco files are installed, the default directory +# will be C:\poco or C:\Program Files\Poco or C:\Programme\Poco. + +set(POCO_INCLUDE_PATH_DESCRIPTION "top-level directory containing the poco include directories.") +set(POCO_INCLUDE_DIR_MESSAGE "Set the Poco_INCLUDE_DIR cmake cache entry to the ${POCO_INCLUDE_PATH_DESCRIPTION}") +set(POCO_LIBRARY_PATH_DESCRIPTION "directory containing the poco libraries:") + + +set(POCO_DIR_SEARCH $ENV{POCO_ROOT}) +if(POCO_DIR_SEARCH) + file(TO_CMAKE_PATH ${POCO_DIR_SEARCH} POCO_DIR_SEARCH) +endif(POCO_DIR_SEARCH) +list(APPEND POCO_DIR_SEARCH ${Poco_DIR}) + +if(WIN32) + set(POCO_DIR_SEARCH + ${POCO_DIR_SEARCH} + C:/poco + D:/poco + "C:/Program Files/poco" + "C:/Programme/poco" + "D:/Program Files/poco" + "D:/Programme/poco" + ) +endif(WIN32) + +# Add in some path suffixes. These will have to be updated whenever a new Poco version comes out. +set(SUFFIX_FOR_INCLUDE_PATH + include +) + +set(SUFFIX_FOR_LIBRARY_PATH + lib + bin +) + +# +# Look for an installation. +# +find_path(Poco_INCLUDE_DIR NAMES Poco/Poco.h PATH_SUFFIXES ${SUFFIX_FOR_INCLUDE_PATH} PATHS + + # Look in other places. + ${POCO_DIR_SEARCH} + + # Help the user find it if we cannot. + DOC "The ${POCO_INCLUDE_PATH_DESCRIPTION}" +) + +if(NOT Poco_INCLUDE_DIR) + + # Look for standard unix include paths + find_path(Poco_INCLUDE_DIR Poco/Poco.h DOC "The ${POCO_INCLUDE_PATH_DESCRIPTION}") + +endif(NOT Poco_INCLUDE_DIR) + +# Assume we didn't find it. +set(Poco_FOUND 0) + +set(Poco_LIBRARIES ) +set(Poco_LIBRARY_DIRS ) + +# Now try to get the include and library path. +# Find all libraries, store debug and release separately +foreach(lib + Crypto + Data + DataMySQL + DataSQLite + Foundation + JSON + MongoDB + Net + NetSSL + PDF + Util + XML + Zip + ) + + # Find Release libraries + find_library(Poco_${lib}_LIBRARY_RELEASE + NAMES Poco${lib} + PATH_SUFFIXES ${SUFFIX_FOR_LIBRARY_PATH} + PATHS ${POCO_DIR_SEARCH} + DOC "The ${POCO_LIBRARY_PATH_DESCRIPTION} Poco${lib}" + ) + + # Find Debug libraries + find_library(Poco_${lib}_LIBRARY_DEBUG + NAMES Poco${lib}d + PATH_SUFFIXES ${SUFFIX_FOR_LIBRARY_PATH} + PATHS ${POCO_DIR_SEARCH} + DOC "The ${POCO_LIBRARY_PATH_DESCRIPTION} Poco${lib}d" + ) + + mark_as_advanced(Poco_${lib}_LIBRARY_RELEASE) + mark_as_advanced(Poco_${lib}_LIBRARY_DEBUG) + + # Add libraries to variable according to build type + set(Poco_${lib}_LIBRARY) + if(Poco_${lib}_LIBRARY_RELEASE) + list(APPEND Poco_LIBRARIES optimized ${Poco_${lib}_LIBRARY_RELEASE}) + list(APPEND Poco_${lib}_LIBRARY optimized ${Poco_${lib}_LIBRARY_RELEASE}) + get_filename_component(lib_dir ${Poco_${lib}_LIBRARY_RELEASE} PATH) + list(APPEND Poco_LIBRARY_DIRS ${lib_dir}) + endif() + + if(Poco_${lib}_LIBRARY_DEBUG) + list(APPEND Poco_LIBRARIES debug ${Poco_${lib}_LIBRARY_DEBUG}) + list(APPEND Poco_${lib}_LIBRARY debug ${Poco_${lib}_LIBRARY_DEBUG}) + get_filename_component(lib_dir ${Poco_${lib}_LIBRARY_RELEASE} PATH) + list(APPEND Poco_LIBRARY_DIRS ${lib_dir}) + endif() + +endforeach() + +if(Poco_LIBRARY_DIRS) + list(REMOVE_DUPLICATES Poco_LIBRARY_DIRS) +endif() + +set(Poco_INCLUDE_DIRS ${Poco_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Poco DEFAULT_MSG + Poco_INCLUDE_DIRS + Poco_Foundation_LIBRARY + Poco_LIBRARIES + ) diff --git a/projects/GDE_API_CPP/api/src/CMakeLists.txt b/projects/GDE_API_CPP/api/src/CMakeLists.txt new file mode 100644 index 0000000..c9a9655 --- /dev/null +++ b/projects/GDE_API_CPP/api/src/CMakeLists.txt @@ -0,0 +1,38 @@ + +INCLUDE_DIRECTORIES( + ${Poco_INCLUDE_DIRS} +) + +LINK_DIRECTORIES( + ${Poco_LIBRARY_DIRS} + ) + +SET(_link_LIBRARIES +# ${Poco_LIBRARIES} # all packages + PocoFoundation + PocoNet + PocoJSON +) + +SET(gde_api_cpp_HEADERS + CommandResultTO.hpp + CommandTO.hpp + HttpConnection.hpp + JsonFormatter.hpp + User.hpp + UserService.hpp +) + +SET(gde_api_cpp_SOURCES + CommandResultTO.cpp + CommandTO.cpp + HttpConnection.cpp + JsonFormatter.cpp + UserService.cpp +) + +ADD_LIBRARY(GdeApiCpp SHARED ${gde_api_cpp_SOURCES}) +TARGET_LINK_LIBRARIES(GdeApiCpp ${_link_LIBRARIES} ) +INSTALL(TARGETS GdeApiCpp EXPORT ${PROJECT_NAME}TargetGroup DESTINATION lib) + +INSTALL(FILES ${gde_api_cpp_HEADERS} DESTINATION include) diff --git a/projects/GDE_API_CPP/api/src/CommandResultTO.cpp b/projects/GDE_API_CPP/api/src/CommandResultTO.cpp new file mode 100644 index 0000000..011bd62 --- /dev/null +++ b/projects/GDE_API_CPP/api/src/CommandResultTO.cpp @@ -0,0 +1,28 @@ +#include "CommandResultTO.hpp" +#include "JsonFormatter.hpp" + +gde::CommandResultTO::CommandResultTO(const CommandResultTO& cto) + : _code(cto._code), _message(cto._message), _data(cto._data) +{ +} + +gde::CommandResultTO +gde::CommandResultTO::fromJson(std::string json) +{ + Poco::JSON::Object::Ptr object = JsonFormatter::parse(json); + int code = JsonFormatter::extract(object, "code"); + std::string message = JsonFormatter::extract(object, "message"); + std::string data = JsonFormatter::extract(object, "data"); + return CommandResultTO(code, message, data); +} + +std::string +gde::CommandResultTO::toJson() +{ + Poco::JSON::Object obj; + obj.set("code", Poco::Dynamic::Var(_code)); + obj.set("message", Poco::Dynamic::Var(_message)); + obj.set("data", Poco::Dynamic::Var(_data)); + + return JsonFormatter::stringify(obj); +} diff --git a/projects/GDE_API_CPP/api/src/CommandResultTO.hpp b/projects/GDE_API_CPP/api/src/CommandResultTO.hpp new file mode 100644 index 0000000..c29e709 --- /dev/null +++ b/projects/GDE_API_CPP/api/src/CommandResultTO.hpp @@ -0,0 +1,43 @@ +#ifndef GDE_COMMAND_RESULT_TO_HPP +#define GDE_COMMAND_RESULT_TO_HPP + +#include +#include + +namespace gde { + + class CommandResultTO { + + public : + // WARNING: keep enum values synchronized to WEB API (CommandResultTO) + enum { OK = 1, ERROR = 2}; + + public: + CommandResultTO(int code = -1, + std::string message = std::string(), + std::string data = std::string()) + : _code(code), _message(message), _data(data) {} + CommandResultTO(const CommandResultTO&); + ~CommandResultTO() {} + + inline std::string getMessage() const { return _message; } + inline void setMessage(std::string message) { this->_message = message; } + + inline std::string getData() const { return _data; } + inline void setData(std::string data) { this->_data = data; } + + inline int getCode() const { return _code; } + inline void setCode(int code) { this->_code = code; } + + static CommandResultTO fromJson(std::string json); + std::string toJson(); + + private: + int _code; + std::string _message; // JSON format + std::string _data; // JSON format + }; + +}; + +#endif diff --git a/projects/GDE_API_CPP/api/src/CommandTO.cpp b/projects/GDE_API_CPP/api/src/CommandTO.cpp new file mode 100644 index 0000000..92d19b9 --- /dev/null +++ b/projects/GDE_API_CPP/api/src/CommandTO.cpp @@ -0,0 +1,91 @@ +#include "CommandTO.hpp" +#include "JsonFormatter.hpp" + +#include +#include + +template +std::string +toString(const T& value) +{ + std::ostringstream oss; + oss << value; + return oss.str(); +} + +template +T +fromString(const std::string& valueString) +{ + std::istringstream iss(valueString); + T value; + return iss >> value ? value : 0; +} + + +gde::CommandTO::CommandTO(const CommandTO& cto) + : _method(cto._method), _data(cto._data), _parameters(cto._parameters) +{ +} + +template +T +gde::CommandTO::getParameter(std::string name) +{ + if (_parameters.find(name) == _parameters.end()) { + std::cerr << "Unknown parameter: " << name << std::endl; + return 0; + } + else { + return fromString(_parameters[name]); + } +} + +template +void +gde::CommandTO::setParameter(std::string name, const T& value, bool replaceIfExist) +{ + if (replaceIfExist) { + _parameters[name] = toString(value); + } + else { + if (_parameters.find(name) != _parameters.end()) { + std::cerr << "Parameter already exists: " << name << std::endl; + } + } +} + +gde::CommandTO +gde::CommandTO::fromJson(std::string json) +{ + Poco::JSON::Object::Ptr object = JsonFormatter::parse(json); + int method = JsonFormatter::extract(object, "method"); + std::string data = JsonFormatter::extract(object, "data"); + + ParametersMap parameters; + Poco::JSON::Object::Ptr objParameters = JsonFormatter::extract(object, "parameters"); + for (Poco::JSON::Object::ConstIterator itr = objParameters->begin(); itr != objParameters->end(); ++itr) { + std::string paramName = itr->first; + std::string paramValue = itr->second; + parameters[paramName] = paramValue; + } + + return CommandTO(method, data, parameters); +} + +std::string +gde::CommandTO::toJson() +{ + Poco::JSON::Object obj; + obj.set("method", Poco::Dynamic::Var(_method)); + obj.set("data", Poco::Dynamic::Var(_data)); + + Poco::JSON::Object::Ptr objParameters = new Poco::JSON::Object(true); + typedef std::map::iterator MapIterator; + for (MapIterator itr = _parameters.begin(); itr != _parameters.end(); ++itr) { + objParameters->set(itr->first, itr->second); + } + obj.set("parameters", objParameters); + + return JsonFormatter::stringify(obj); +} diff --git a/projects/GDE_API_CPP/api/src/CommandTO.hpp b/projects/GDE_API_CPP/api/src/CommandTO.hpp new file mode 100644 index 0000000..b00d847 --- /dev/null +++ b/projects/GDE_API_CPP/api/src/CommandTO.hpp @@ -0,0 +1,41 @@ +#ifndef GDE_COMMAND_TO_HPP +#define GDE_COMMAND_TO_HPP + +#include +#include + +namespace gde { + + class CommandTO { + + typedef std::map ParametersMap; + + public: + CommandTO(int method = -1, + std::string data = std::string(), + const ParametersMap& parameters=ParametersMap()) + : _method(method), _data(data), _parameters(parameters) {} + CommandTO(const CommandTO&); + ~CommandTO() {} + + inline std::string getData() const { return _data; } + inline void setData(std::string data) { this->_data = data; } + + inline int getMethod() const { return _method; } + inline void setMethod(int method) { this->_method = method; } + + template T getParameter(std::string name); + template void setParameter(std::string name, const T& value, bool replaceIfExist=true); + + static CommandTO fromJson(std::string json); + std::string toJson(); + + private: + int _method; + std::string _data; // JSON format + ParametersMap _parameters; + }; + +}; + +#endif diff --git a/projects/GDE_API_CPP/api/src/HttpConnection.cpp b/projects/GDE_API_CPP/api/src/HttpConnection.cpp new file mode 100644 index 0000000..5a2e16d --- /dev/null +++ b/projects/GDE_API_CPP/api/src/HttpConnection.cpp @@ -0,0 +1,84 @@ +#include "HttpConnection.hpp" +#include "JsonFormatter.hpp" + +#include +#include +#include + +#include +#include + +using namespace Poco::Net; + +gde::HttpConnection::HttpConnection(Poco::URI uri) + : _path("/") +{ + try { + _session.setHost(uri.getHost()); + _session.setPort(uri.getPort()); + //_session.setProxy(machine, port); + } catch (Poco::Exception& e) { + std::cerr << e.displayText() << std::endl; + return; + } + + _path = uri.getPathAndQuery(); + if (_path.empty()) + _path = "/"; +} + +gde::HttpConnection::~HttpConnection() +{ +} + +// Workflow: +// 1. request (json) --> CommandTO object +// 2. command data (json) from CommandTO --> TO +// 3. call DAO with TO and obtain another TO +// 4. latter TO --> (json) CommandResultTO data +// 5. set CommandResultTO code +// 6. CommandResultTO --> (json) response + +gde::CommandResultTO +gde::HttpConnection::_processRequest(const HTTPRequest& request, + const std::string& requestBody) +{ + int code = CommandResultTO::OK; + std::string message = ""; + std::string data = ""; + + try { + std::ostream& os = _session.sendRequest((HTTPRequest&)request); + // Send request body, if any + if (!requestBody.empty()) { + std::istringstream iss(requestBody); + Poco::StreamCopier::copyStream((std::istream&)iss, os); + } + + // Get response + HTTPResponse response; + std::istream& rs = _session.receiveResponse(response); + //std::cout << response.getStatus() << " " << response.getReason() << endl; + std::ostringstream responseBody; + Poco::StreamCopier::copyStream(rs, responseBody); + // responseBody contains a CommandResultTO in json format + return CommandResultTO::fromJson(responseBody.str()); + } catch (Poco::Exception& e) { + std::cerr << e.displayText() << std::endl; + return CommandResultTO(CommandResultTO::ERROR); + } +} + +gde::CommandResultTO +gde::HttpConnection::doGet(const CommandTO& cto) +{ + HTTPRequest request(HTTPRequest::HTTP_GET, _path, HTTPMessage::HTTP_1_1); + return _processRequest(request, cto.getData()); +} + +gde::CommandResultTO +gde::HttpConnection::doPost(const CommandTO& cto) +{ + HTTPRequest request(HTTPRequest::HTTP_PUT, _path, HTTPMessage::HTTP_1_1); + return _processRequest(request, cto.getData()); +} diff --git a/projects/GDE_API_CPP/api/src/HttpConnection.hpp b/projects/GDE_API_CPP/api/src/HttpConnection.hpp new file mode 100644 index 0000000..661358a --- /dev/null +++ b/projects/GDE_API_CPP/api/src/HttpConnection.hpp @@ -0,0 +1,35 @@ +#ifndef GDE_HTTP_CONNECTION_HPP +#define GDE_HTTP_CONNECTION_HPP + +#include "CommandTO.hpp" +#include "CommandResultTO.hpp" + +#include + +#include +#include +#include + +namespace gde { + + class HttpConnection { + + public: + HttpConnection(Poco::URI); + ~HttpConnection(); + + CommandResultTO doGet(const CommandTO&); + CommandResultTO doPost(const CommandTO&); + + private: + gde::CommandResultTO _processRequest(const Poco::Net::HTTPRequest&, + const std::string& requestBody); + + private: + Poco::Net::HTTPClientSession _session; + std::string _path; + }; + +}; + +#endif diff --git a/projects/GDE_API_CPP/api/src/JsonFormatter.cpp b/projects/GDE_API_CPP/api/src/JsonFormatter.cpp new file mode 100644 index 0000000..2bee2a5 --- /dev/null +++ b/projects/GDE_API_CPP/api/src/JsonFormatter.cpp @@ -0,0 +1,30 @@ +#include "JsonFormatter.hpp" + +#include + +#include + +Poco::JSON::Object::Ptr +gde::JsonFormatter::parse(const std::string& json) +{ + Poco::JSON::Parser parser; + Poco::Dynamic::Var result = parser.parse(json); + // use pointers to avoid copying + Poco::JSON::Object::Ptr object = result.extract(); + return object; +} + +template +T +gde::JsonFormatter::extract(Poco::JSON::Object::Ptr object, const std::string& varName) +{ + Poco::Dynamic::Var v = object->get(varName); + return v.convert(); +} + +std::string +gde::JsonFormatter::stringify(const Poco::JSON::Object& object) { + std::ostringstream jsonStream; + object.stringify(jsonStream); + return jsonStream.str(); +} diff --git a/projects/GDE_API_CPP/api/src/JsonFormatter.hpp b/projects/GDE_API_CPP/api/src/JsonFormatter.hpp new file mode 100644 index 0000000..395bbcb --- /dev/null +++ b/projects/GDE_API_CPP/api/src/JsonFormatter.hpp @@ -0,0 +1,21 @@ +#ifndef JSON_FORMATTER_HPP +#define JSON_FORMATTER_HPP + +#include + +#include + +namespace gde { + + class JsonFormatter { + public: + + static Poco::JSON::Object::Ptr parse(const std::string&); + template static T extract(Poco::JSON::Object::Ptr, const std::string&); + + static std::string stringify(const Poco::JSON::Object&); + }; + +}; + +#endif diff --git a/projects/GDE_API_CPP/api/src/User.hpp b/projects/GDE_API_CPP/api/src/User.hpp new file mode 100644 index 0000000..131508b --- /dev/null +++ b/projects/GDE_API_CPP/api/src/User.hpp @@ -0,0 +1,36 @@ +#ifndef GDE_USER_HPP +#define GDE_USER_HPP + +#include + +namespace gde { + + class User { + friend class UserService; + + public: + inline int getId() const { return _id; } + inline void setId(int id) { this->_id = id; } + + inline std::string getName() const { return _name; } + inline void setName(const std::string& name) { this->_name = name; } + + inline std::string getPassword() const { return _password; } + inline void setPassword(const std::string& password) { this->_password = password; } + + private: + User(int id=-1, std::string name="", std::string password="") + : _id(id), _name(name), _password(password) {} + ~User() {} + User(const User&); // non copyable + User& operator=(const User&); // non copyable + + private: + int _id; + std::string _name; + std::string _password; + }; + +}; + +#endif diff --git a/projects/GDE_API_CPP/api/src/UserService.cpp b/projects/GDE_API_CPP/api/src/UserService.cpp new file mode 100644 index 0000000..2465ed9 --- /dev/null +++ b/projects/GDE_API_CPP/api/src/UserService.cpp @@ -0,0 +1,55 @@ +#include "UserService.hpp" +#include "HttpConnection.hpp" +#include "CommandTO.hpp" +#include "CommandResultTO.hpp" +#include "JsonFormatter.hpp" + +#include +#include + +/* + * WARNING: keep enum values synchronized to WEB API (UserService) + */ +enum { + CREATE_USER = 1, + DELETE_USER, + ADD_TO_GROUP, + REMOVE_FROM_GROUP, + CREATE_GROUP, + DELETE_GROUP, + FIND_USER +}; + +gde::UserService::UserService() + : _servletName("/UserService") +{ +} + +gde::UserService::~UserService() +{ +} + +gde::User +gde::UserService::createUser(std::string name, std::string password) +{ + // build JSON string for CommandTO data + Poco::JSON::Object obj; + obj.set("name", Poco::Dynamic::Var(name)); + obj.set("password", Poco::Dynamic::Var(password)); + std::string data = JsonFormatter::stringify(obj); + + CommandTO cto(CREATE_USER, data); + CommandResultTO crto = gde::HttpConnection(Poco::URI(_servletName)).doPost(cto); + + std::cout << "createUser command:\n"; + std::cout << "\tStatus code (OK=1, ERROR=2): " << crto.getCode() << std::endl; + + // build User object from CommandResultTO data (json format) + { + Poco::JSON::Object::Ptr object = JsonFormatter::parse(crto.getData()); + int id = JsonFormatter::extract(object, "id"); + std::string name = JsonFormatter::extract(object, "name"); + std::string password = JsonFormatter::extract(object, "password"); + return gde::User(id, name, password); + } +} diff --git a/projects/GDE_API_CPP/api/src/UserService.hpp b/projects/GDE_API_CPP/api/src/UserService.hpp new file mode 100644 index 0000000..33ca6b8 --- /dev/null +++ b/projects/GDE_API_CPP/api/src/UserService.hpp @@ -0,0 +1,37 @@ +#ifndef GDE_USER_SERVICE_HPP +#define GDE_USER_SERVICE_HPP + +#include "User.hpp" + +#include + +namespace gde { + + class UserService { + + public: + User createUser(std::string name, std::string password); + + void createUser(); + void deleteUser(); + void findUser(); + + void createGroup(); + void deleteGroup(); + + void addToGroup(); + void removeFromGroup(); + + private: + UserService(); + ~UserService(); + UserService(const UserService&); // non copyable + UserService& operator=(const UserService&); // non copyable + + private: + std::string _servletName; + }; + +}; + +#endif -- 2.30.2