From 37ebf68d6bed2b8c73f414421d933fa32cd23baa Mon Sep 17 00:00:00 2001 From: Matthias Janetschek Date: Wed, 20 May 2015 17:23:02 +0200 Subject: [PATCH] . --- src/hos_cosgi_common/CMakeLists.txt | 14 + src/hos_cosgi_common/Doxyfile.in | 361 ++++++++++++++++++ .../hos/cosgi/service/interface.h | 169 +++++++- .../resources/DevicesHTTPResource.cpp | 165 +++++++- .../webserver/resources/DevicesHTTPResource.h | 9 +- .../resources/SchemaHTTPResource.cpp | 39 +- .../webserver/resources/SchemaHTTPResource.h | 6 +- .../webserver/webserver_serviceimpl.cpp | 4 +- .../hos_cpp_common/hos/common/observable.h | 12 +- .../src/libmicrohttpd/aclocal.m4 | 7 +- .../src/libmicrohttpd/configure | 4 +- .../src/libmicrohttpd/doc/libmicrohttpd.info | Bin 195253 -> 195255 bytes .../src/libmicrohttpd/doc/stamp-vti | 4 +- .../src/libmicrohttpd/doc/version.texi | 4 +- .../w32/VS2013/microhttpd_dll_res_vc.rc | 42 -- 15 files changed, 745 insertions(+), 95 deletions(-) create mode 100644 src/hos_cosgi_common/Doxyfile.in delete mode 100644 src/hos_libhttpserver/src/libmicrohttpd/w32/VS2013/microhttpd_dll_res_vc.rc diff --git a/src/hos_cosgi_common/CMakeLists.txt b/src/hos_cosgi_common/CMakeLists.txt index 85101221..07ad65aa 100644 --- a/src/hos_cosgi_common/CMakeLists.txt +++ b/src/hos_cosgi_common/CMakeLists.txt @@ -159,3 +159,17 @@ install(DIRECTORY include/${PROJECT_NAME}/ ## Add folders to be run by python nosetests # catkin_add_nosetests(test) + +################### +## Documentation ## +################### + +find_package(Doxygen) +if(DOXYGEN_FOUND) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) + add_custom_target(doc + ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen" VERBATIM + ) +endif(DOXYGEN_FOUND) diff --git a/src/hos_cosgi_common/Doxyfile.in b/src/hos_cosgi_common/Doxyfile.in new file mode 100644 index 00000000..9ca4db30 --- /dev/null +++ b/src/hos_cosgi_common/Doxyfile.in @@ -0,0 +1,361 @@ +# Doxyfile 1.8.8 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = hos_cosgi_common +PROJECT_NUMBER = +PROJECT_BRIEF = +PROJECT_LOGO = +OUTPUT_DIRECTORY = doc +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +TCL_SUBST = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/include +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.as \ + *.js +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = YES +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = YES +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_SUBDIR = +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +DOCBOOK_PROGRAMLISTING = NO +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +DIA_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/src/hos_cosgi_common/include/hos_cosgi_common/hos/cosgi/service/interface.h b/src/hos_cosgi_common/include/hos_cosgi_common/hos/cosgi/service/interface.h index 0ace68d2..61cc6657 100644 --- a/src/hos_cosgi_common/include/hos_cosgi_common/hos/cosgi/service/interface.h +++ b/src/hos_cosgi_common/include/hos_cosgi_common/hos/cosgi/service/interface.h @@ -1,87 +1,238 @@ -/* - * cosgi_common.h - * - * Created on: 19.04.2015 - * Author: matzman - */ -#ifndef INCLUDE_HOS_COSGI_COMMON_COSGI_CORE_H_ -#define INCLUDE_HOS_COSGI_COMMON_COSGI_CORE_H_ + + +#pragma once + #include +// main namespace namespace hos { namespace cosgi{ namespace service { namespace interface { + +/** + * Basic public OSGI interface class. + * + * Every public OSGI interface class needs to inherit from this class. + * At the moment it only defines an empty virtual destructor. + */ class Object { public: virtual ~Object() {} }; + +/** + * Basic public OSGI service interface class. + * + * Every public OSGI service interface class needs to inherit from this class. + * Defines generic methods to get information about a service. + */ class Service : public virtual Object { public: + /** + * Returns the name of the service. + * + * The service name is used to register a service in the OSGI framework. + * + * \return service name. + **/ virtual const char* getServiceName() = 0; + + /** + * Returns the version of the service. + * + * The version numbers are used to determine compatibility. Different major numbers are incompatible with each other. + * Different minor numbers are backwards compatible (e.g. a mininum requirement of 1.2 means that service version 1.3 is compatible + * but service version 1.1 is incompatible). + * + * \param[out] major version major number. + * \param[out] minor version minor number. + */ virtual void getServiceVersion(int& major, int& minor) = 0; }; + +/** + * General template implementing the observer from the observer-pattern. + * + * This template does not provide any functionality, so do not use it but use only its specializations. + */ template class Observer {}; + + + +/** + * General template implementing the observable from the observer-pattern. + * + * This template does not provide any functionality, so do not use it but use only its specializations. + */ template class Observable {}; + + + +/** + * Convenience template merging the Object class and the Observable template into a single template. + */ template class ObservableObject : public virtual Object, public virtual Observable<_Args...> {}; + + + +/** + * Convenience template merging the Service class and the Observable template into a single template. + */ template class ObservableService : public virtual Service, public virtual Observable<_Args...> {}; + +/** + * Specialization of the Observer template with one template argument (the event emitted from the observable). + */ template class Observer<_Event> : public virtual Object { public: + /** + * Specifies the type of compatible observables. + */ typedef Observable<_Event> observable_type; + /** + * Function that is called when an event is emitted by the observable object. + * + * \param[in] o observable object emitting the event. + * \param[in] e the event (can be null). + */ virtual void notificationReceived(observable_type* o, const _Event* e) = 0; }; + +/** + * Specialization of the Observer template with two template arguments (the key used to filter observers, + * and the event emitted from the observable). + */ template class Observer<_Key, _Event> : public virtual Object { public: + /** + * Specifies the type of compatible observables. + */ typedef Observable<_Key, _Event> observable_type; + /** + * Function that is called when an event is emitted by the observable object. + * + * \param[in] o observable object emitting the event. + * \param[in] key the filter key. + * \param[in] e the event (can be null). + */ virtual void notificationReceived(observable_type* o, const _Key& key, const _Event* e) = 0; }; + +/** + * Specialization of the Observable template with one template argument (the event emitted from the observable). + * + * When an event is emitted, all registered observers will be notified. + */ template class Observable<_Event> : public virtual Object { protected: + /** + * Notify observers of a new event. + * + * \param[in] e event. + */ virtual void notifyObservers(const _Event* e) = 0; public: + /** + * Specifies the type of compatible observers. + */ typedef Observer<_Event> observer_type; + /** + * Registers an observer. + * + * \param[in] o observer to be registered. + */ virtual void addObserver(observer_type* o) = 0; + /** + * Unregisters an observer. + * + * \param[in] o observer to be unregistered. + */ virtual void deleteObserver(observer_type* o) = 0; + /** + * Unregisters all observers. + */ virtual void deleteObservers() = 0; + /** + * Returns the number of registered observers. + * + * \return number of registered observers. + */ virtual size_t countObservers() = 0; }; + +/** + * Specialization of the Observable template with two template arguments (the key used to filter observers, + * and the event emitted from the observable). + * + * When an event is emitted, only observers registered under the specified key will be notified. + */ template class Observable<_Key, _Event> : public virtual Object { protected: + /** + * Notify observers of a new event. + * + * \param[in] key observer filter key. + * \param[in] e event. + */ virtual void notifyObservers(const _Key& key, const _Event* e) = 0; public: + /** + * Specifies the type of compatible observers. + */ typedef Observer<_Key, _Event> observer_type; + /** + * Registers an observer. + * + * \param[in] key filter key. + * \param[in] o observer to be registered. + */ virtual void addObserver(_Key& key, observer_type* o) = 0; + /** + * Unregisters an observer. + * + * \param[in] key filter key. + * \param[in] o observer to be unregistered. + */ virtual void deleteObserver(_Key& key, observer_type* o) = 0; + /** + * Unregisters all observers. + */ virtual void deleteObservers() = 0; + /** + * Returns the number of registered observers. + * + * \return number of registered observers. + */ virtual size_t countObservers() = 0; }; + } // namespace interface } // namespace service } // namespace cosgi } // namespace hos -#endif /* INCLUDE_HOS_COSGI_COMMON_COSGI_CORE_H_ */ diff --git a/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/DevicesHTTPResource.cpp b/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/DevicesHTTPResource.cpp index d61261e5..5ec010fe 100644 --- a/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/DevicesHTTPResource.cpp +++ b/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/DevicesHTTPResource.cpp @@ -1,5 +1,7 @@ #include "DevicesHTTPResource.h" +#include +#include // Service Namespace @@ -10,9 +12,22 @@ namespace webserver { namespace resources { using namespace httpserver; +using namespace ::libvariant; -DevicesHTTPResource::DevicesHTTPResource(devicerepository::DeviceRepositoryService* repoService) - : repoService(repoService) { + +class ResourceException : public std::runtime_error { +protected: + int errorCode; +public: + ResourceException(std::string msg, int errorCode) + : std::runtime_error(msg), errorCode(errorCode) {} + + int getErrorCode() { return errorCode; } +}; + + +DevicesHTTPResource::DevicesHTTPResource(devicerepository::DeviceRepositoryService* repoService, size_t prefixPathPieces) + : repoService(repoService), prefixPathPieces(prefixPathPieces) { disallow_all(); set_allowing(MHD_HTTP_METHOD_GET, true); set_allowing(MHD_HTTP_METHOD_POST, true); @@ -22,19 +37,161 @@ DevicesHTTPResource::DevicesHTTPResource(devicerepository::DeviceRepositoryServi void DevicesHTTPResource::render_GET(const httpserver::http_request& req, httpserver::http_response** res) { std::cout << "DevicesHTTPResource::render_GET()" << std::endl; std::cout << req; - *res = new http_response(http_response_builder("GET response", 200).string_response()); + + try { + + if (req.get_path_pieces_size() < prefixPathPieces) { + ROS_ERROR_STREAM("Requested path " << req.get_path() << " has fewer pieces than prefix path."); + throw ResourceException("Internal Server Error", 500); + } else { + + bool isSetCommand = false; + Variant setValue; + if (req.get_arg("command").compare("set") == 0) { + isSetCommand = true; + std::string value = req.get_arg("value"); + if (value.empty()) { + throw ResourceException("No value given for set command.", 400); + } else { + boost::algorithm::trim(value); + if (boost::starts_with(value, "{") || boost::starts_with(value, "[")) { + setValue = DeserializeJSON(value); + } else { + setValue = Variant(value); + } + } + } + + if (req.get_path_pieces_size() == prefixPathPieces) { + if (isSetCommand) { + throw ResourceException("No device given for set command.", 400); + } + std::vector> devices; + repoService->getDevices(devices); + Variant result; + for (auto d : devices) { + result[d->getDeviceID()] = getDeviceInfo(d.get()); + } + *res = new http_response(http_response_builder(SerializeJSON(result, true), 200).string_response()); + } else { + std::string devid = req.get_path_piece(prefixPathPieces); + auto device = repoService->getDevice(devid); + if (device) { + if (isSetCommand) { + std::vector path; + for (int i = prefixPathPieces+1; i < req.get_path_pieces_size(); i++) { + path.push_back(req.get_path_piece(i)); + } + setDeviceState(device.get(), setValue, path); + *res = new http_response(http_response_builder("OK", 200).string_response()); + } else { + std::string info; + if (req.get_path_pieces_size() > prefixPathPieces+1) { + info = req.get_path_piece(prefixPathPieces+1); + } + std::stringstream ss; + for (int i = prefixPathPieces+2; i < req.get_path_pieces_size(); i++) { + ss << "/" << req.get_path_piece(i); + } + std::string path = ss.str(); + Variant result = getDeviceInfo(device.get(), info, path); + *res = new http_response(http_response_builder(SerializeJSON(result, true), 200).string_response()); + } + } else { + throw ResourceException((boost::format("Could not find device \"%1%\"") % devid).str(), 404); + } + } + } + } catch (ResourceException& e) { + *res = new http_response(http_response_builder(e.what(), e.getErrorCode()).string_response()); + } catch (std::exception& e) { + *res = new http_response(http_response_builder(e.what(), 500).string_response()); + } + std::cout << **res; } + +Variant DevicesHTTPResource::getDeviceInfo(devicerepository::Device* device, std::string info, const std::string path) { + Variant retval; + if (info.empty()) { + retval["type"] = device->getDeviceType(); + retval["status_topic"] = device->getStatusTopic(); + retval["command_topic"] = device->getCmdTopic(); + retval["current_state"] = device->getCurrentState(); + retval["last_state"] = device->getLastState(); + } else { + if (info.compare("type") == 0) { + if (path.empty()) { + retval = device->getDeviceType(); + } else { + throw ResourceException("Device info \"type\" has no path.", 400); + } + } else if (info.compare("status_topic") == 0) { + if (path.empty()) { + retval = device->getStatusTopic(); + } else { + throw ResourceException("Device info \"status_topic\" has no path.", 400); + } + } else if (info.compare("command_topic") == 0) { + if (path.empty()) { + retval = device->getCmdTopic(); + } else { + throw ResourceException("Device info \"command_topic\" has no path.", 400); + } + } else if (info.compare("current_state") == 0) { + retval = device->getCurrentState(); + if (!path.empty()) { + if (retval.HasPath(path)) { + retval = retval.GetPath(path); + } else { + throw ResourceException((boost::format("Unknown path \"%1%\" for device info \"current_state\".") % path).str(), 404); + } + } + } else if (info.compare("last_state") == 0) { + retval = device->getLastState(); + if (!path.empty()) { + if (retval.HasPath(path)) { + retval = retval.GetPath(path); + } else { + throw ResourceException((boost::format("Unknown path \"%1%\" for device info \"last_state\".") % path).str(), 404); + } + } + } else { + throw ResourceException((boost::format("Unknown device info \"%1%\"") % info).str(), 404); + } + } + return retval; +} + +void DevicesHTTPResource::setDeviceState(devicerepository::Device* device, Variant cmd, std::vector path) { + Variant cmdMsg; + if (path.size() > 0) { + Variant& current = cmdMsg; + for (int i = 0; i < path.size()-1; i++) { + Variant tmp; + current[path[i]] = tmp; + current = tmp; + } + current[path[path.size()-1]] = cmd; + } else { + cmdMsg = cmd; + } + device->sendCommand(cmdMsg); +} + + void DevicesHTTPResource::render_POST(const httpserver::http_request& req, httpserver::http_response** res) { std::cout << "DevicesHTTPResource::render_POST()" << std::endl; std::cout << req; - *res = new http_response(http_response_builder("POST response", 200).string_response()); + *res = new http_response(http_response_builder("ToDo: Implement POST", 500).string_response()); std::cout << **res; } + + } // namespace resources } // namespace webserver } // namespace service diff --git a/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/DevicesHTTPResource.h b/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/DevicesHTTPResource.h index 981d1e94..7334a133 100644 --- a/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/DevicesHTTPResource.h +++ b/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/DevicesHTTPResource.h @@ -5,6 +5,8 @@ #include #include #include +#include +#include // Service Namespace namespace hos { @@ -18,11 +20,16 @@ namespace resources { class DevicesHTTPResource : public httpserver::http_resource { private: devicerepository::DeviceRepositoryService* repoService = nullptr; + size_t prefixPathPieces; public: - DevicesHTTPResource(devicerepository::DeviceRepositoryService* repoService); + DevicesHTTPResource(devicerepository::DeviceRepositoryService* repoService, size_t prefixPathPieces); void render_GET(const httpserver::http_request& req, httpserver::http_response** res); void render_POST(const httpserver::http_request& req, httpserver::http_response** res); + + ::libvariant::Variant getDeviceInfo(devicerepository::Device* device, const std::string info = std::string(), const std::string path = std::string()); + + void setDeviceState(devicerepository::Device* device, ::libvariant::Variant cmd, std::vector path = std::vector()); }; } // namespace resources diff --git a/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/SchemaHTTPResource.cpp b/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/SchemaHTTPResource.cpp index c282eddd..470f589f 100644 --- a/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/SchemaHTTPResource.cpp +++ b/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/SchemaHTTPResource.cpp @@ -1,5 +1,6 @@ #include "SchemaHTTPResource.h" +#include // Service Namespace @@ -10,28 +11,36 @@ namespace webserver { namespace resources { using namespace httpserver; +using namespace ::libvariant; -SchemaHTTPResource::SchemaHTTPResource(ros::NodeHandle* nodehandle) - : nodehandle(nodehandle) { + +SchemaHTTPResource::SchemaHTTPResource(ros::NodeHandle* nodehandle, size_t prefixPathPieces) + : nodehandle(nodehandle), prefixPathPieces(prefixPathPieces) { disallow_all(); set_allowing(MHD_HTTP_METHOD_GET, true); - set_allowing(MHD_HTTP_METHOD_POST, true); + schemaLoader.reset(new libvariant::HosSchemaLoader()); } void SchemaHTTPResource::render_GET(const httpserver::http_request& req, httpserver::http_response** res) { - std::cout << "SchemaHTTPResource::render_GET()" << std::endl; - std::cout << req; - *res = new http_response(http_response_builder("GET response", 200).string_response()); - std::cout << **res; -} - - -void SchemaHTTPResource::render_POST(const httpserver::http_request& req, httpserver::http_response** res) { - std::cout << "SchemaHTTPResource::render_POST()" << std::endl; - std::cout << req; - *res = new http_response(http_response_builder("POST response", 200).string_response()); - std::cout << **res; + if (req.get_path_pieces_size() < prefixPathPieces) { + ROS_ERROR_STREAM("Requested path " << req.get_path() << " has fewer pieces than prefix path."); + *res = new http_response(http_response_builder("Internal Server Error", 500).string_response()); + } else if (req.get_path_pieces_size() == prefixPathPieces) { + *res = new http_response(http_response_builder("No schema given", 400).string_response()); + } else { + std::stringstream ss; + for (int i = prefixPathPieces; i < req.get_path_pieces_size(); i++) { + ss << "/" << req.get_path_piece(i); + } + auto schemaPath = (boost::format("hos:schema:/%1%") % ss.str()).str(); + try { + auto schema = schemaLoader->GetSchema(schemaPath); + *res = new http_response(http_response_builder(SerializeJSON(schema, true), 200).string_response()); + } catch(std::exception& e) { + *res = new http_response(http_response_builder((boost::format("Could not find schema \"%1%\": %2%") % schemaPath % e.what()).str(), 404).string_response()); + } + } } diff --git a/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/SchemaHTTPResource.h b/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/SchemaHTTPResource.h index d08d57d3..8b90270d 100644 --- a/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/SchemaHTTPResource.h +++ b/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/resources/SchemaHTTPResource.h @@ -4,6 +4,7 @@ #include #include +#include // Service Namespace namespace hos { @@ -17,11 +18,12 @@ namespace resources { class SchemaHTTPResource : public httpserver::http_resource { private: ros::NodeHandle* nodehandle = nullptr; + std::unique_ptr schemaLoader; + size_t prefixPathPieces; public: - SchemaHTTPResource(ros::NodeHandle* nodehandle); + SchemaHTTPResource(ros::NodeHandle* nodehandle, size_t prefixPathPieces); void render_GET(const httpserver::http_request& req, httpserver::http_response** res); - void render_POST(const httpserver::http_request& req, httpserver::http_response** res); }; } // namespace resources diff --git a/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/webserver_serviceimpl.cpp b/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/webserver_serviceimpl.cpp index e7e02dfd..74447f08 100644 --- a/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/webserver_serviceimpl.cpp +++ b/src/hos_cosgi_webserver/src/hos/cosgi/service/webserver/webserver_serviceimpl.cpp @@ -61,8 +61,8 @@ void WebServerServiceImpl::init() { create_webserver serverParams(8888); serverParams.max_threads(5).regex_checking(); webServer.reset(new webserver::webserver(serverParams)); - devicesResource.reset(new resources::DevicesHTTPResource(repoService)); - schemaResource.reset(new resources::SchemaHTTPResource(nodehandle)); + devicesResource.reset(new resources::DevicesHTTPResource(repoService, 2)); + schemaResource.reset(new resources::SchemaHTTPResource(nodehandle, 2)); webServer->register_resource("/hos/devices", devicesResource.get(), true); webServer->register_resource("/hos/schemas", schemaResource.get(), true); webServer->start(false); diff --git a/src/hos_cpp_common/include/hos_cpp_common/hos/common/observable.h b/src/hos_cpp_common/include/hos_cpp_common/hos/common/observable.h index 8dc90ec8..16668c81 100644 --- a/src/hos_cpp_common/include/hos_cpp_common/hos/common/observable.h +++ b/src/hos_cpp_common/include/hos_cpp_common/hos/common/observable.h @@ -1,12 +1,6 @@ -/* - * observable.h - * - * Created on: 25.04.2015 - * Author: matzman - */ -#ifndef INCLUDE_HOS_CPP_COMMON_OBSERVABLE_H_ -#define INCLUDE_HOS_CPP_COMMON_OBSERVABLE_H_ +#pragma once + #include #include @@ -143,5 +137,3 @@ public: } // namespace common } // namespace hos - -#endif /* INCLUDE_HOS_CPP_COMMON_OBSERVABLE_H_ */ diff --git a/src/hos_libhttpserver/src/libmicrohttpd/aclocal.m4 b/src/hos_libhttpserver/src/libmicrohttpd/aclocal.m4 index 96258cce..fdc4449a 100644 --- a/src/hos_libhttpserver/src/libmicrohttpd/aclocal.m4 +++ b/src/hos_libhttpserver/src/libmicrohttpd/aclocal.m4 @@ -318,10 +318,9 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- diff --git a/src/hos_libhttpserver/src/libmicrohttpd/configure b/src/hos_libhttpserver/src/libmicrohttpd/configure index 08d040cf..a846be6b 100755 --- a/src/hos_libhttpserver/src/libmicrohttpd/configure +++ b/src/hos_libhttpserver/src/libmicrohttpd/configure @@ -2666,8 +2666,8 @@ test "$program_suffix" != NONE && ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in diff --git a/src/hos_libhttpserver/src/libmicrohttpd/doc/libmicrohttpd.info b/src/hos_libhttpserver/src/libmicrohttpd/doc/libmicrohttpd.info index c460a85f9e76b194255dffb7fbdd9c168ef82d32..7db83c7d3ae42ef30d67db7ba883bbe1c67081db 100644 GIT binary patch delta 569 zcmYk2O=}ZT6o#1-W~QBqqC^tgP&z9qLiOG|-`PmXKyI~gYv(2aND z!c|Kli~BpekS+wVzd-#7BI43+nwjaM^kycaiwoyG@439^Js;2YlXLy(KsAlEC=T|H z$1f`XY6aeB@`p^8PBIxDoPnv0f9UmPW+H59&uG78^n=}2MC1M--tUB6%3S1_Je)v7 z^7!clYAb_qm@sS;4{Mu)9&H)>K{p<}N|LCzI!xkGH(?fW{bG6nys1Hr|CxYNA*g7^ z+rMOfBL!Kq_;Cui_}vsVz2~6e*Y(^ z3Uf`DI3;LiQ2i^me;1--A&<8+SgeSR`Q<~Yt}+i{mlRE-y3-j3UFHd37Gz0b9`Uiw zzh%(mUo&XvMkflGk8CtcW8|O$DU*Hq4D%}UOzD*v8Cjlav`rsVLWTzI<( zO^Z4|JCNp7h7tB%T#|c-()^MjwuQ;;r0bi{S2xz%8-hB>Cj9yZtTdee#3zr0W?P6@ z8bAFcytXeup2Mgd8L#QL5yPHK(2N*cZzF0v4SVzr!#)uQ)0VZzVb9p=?25OuN3|>T C8@jas delta 545 zcmYjN&ubGw6lUI%Y~1ZZtZ7IkcBO}kP?(wQ?CeHR53RklK}8Q91k=r?Ew;NMjfkf~ zJb0=I5#Pa!|ABarp8F5@4|q@yz1a#SO_LnN*)@WP2k-mA<9px!sr~uXezTWnfwR_l z{^{*QW3s;N8?X8X+3y>$d;;9UgC}Gf>jN+^aqC{xsyVH#jaobEw35zFBMu`asmHKA zfD)1+O!vNB&&?|)xD2d%(u``(&Q{n-HoM(+b8)xZc^Y<=tHsQ0hU?0$3Yh`?HGl$P zcsITB_|P*frU2~NV%}9JeLO549)hAf17#b2~GvRI0Keu)~;Fn zat1cA3HY!;^g&sb+|8IP8VDi&$sex~GpD3Jn?2@+p%v-AkC< zBsonm$yrKNa?0lc!=oXT^2(P&w{bj#xxYU-BRB^%Yq5y8Mldz0v}ikF62~g=0wysY z!93_-jXhG#DMp!x2Lrf>M<*~WUAF_bP)YtCAZo6h~lhMx89$od1ETBMr* diff --git a/src/hos_libhttpserver/src/libmicrohttpd/doc/stamp-vti b/src/hos_libhttpserver/src/libmicrohttpd/doc/stamp-vti index dbbe7e46..c8c24ba0 100644 --- a/src/hos_libhttpserver/src/libmicrohttpd/doc/stamp-vti +++ b/src/hos_libhttpserver/src/libmicrohttpd/doc/stamp-vti @@ -1,4 +1,4 @@ -@set UPDATED 19 May 2015 -@set UPDATED-MONTH May 2015 +@set UPDATED 3 April 2015 +@set UPDATED-MONTH April 2015 @set EDITION 0.9.42 @set VERSION 0.9.42 diff --git a/src/hos_libhttpserver/src/libmicrohttpd/doc/version.texi b/src/hos_libhttpserver/src/libmicrohttpd/doc/version.texi index dbbe7e46..c8c24ba0 100644 --- a/src/hos_libhttpserver/src/libmicrohttpd/doc/version.texi +++ b/src/hos_libhttpserver/src/libmicrohttpd/doc/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 19 May 2015 -@set UPDATED-MONTH May 2015 +@set UPDATED 3 April 2015 +@set UPDATED-MONTH April 2015 @set EDITION 0.9.42 @set VERSION 0.9.42 diff --git a/src/hos_libhttpserver/src/libmicrohttpd/w32/VS2013/microhttpd_dll_res_vc.rc b/src/hos_libhttpserver/src/libmicrohttpd/w32/VS2013/microhttpd_dll_res_vc.rc deleted file mode 100644 index 62247171..00000000 --- a/src/hos_libhttpserver/src/libmicrohttpd/w32/VS2013/microhttpd_dll_res_vc.rc +++ /dev/null @@ -1,42 +0,0 @@ -/* W32 resources for .dll */ - -#include - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,9,42,0 - PRODUCTVERSION 0,9,42,0 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#if defined(_DEBUG) - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0 -#endif - FILEOS VOS_NT_WINDOWS32 - FILETYPE VFT_DLL - FILESUBTYPE VFT2_UNKNOWN -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "04090000" /* Lang = US English, Charset = ASCII */ - BEGIN - VALUE "ProductName", "GNU libmicrohttpd\0" - VALUE "ProductVersion", "0.9.42\0" - VALUE "FileVersion", "0.9.42\0" - VALUE "FileDescription", "GNU libmicrohttpd dll for Windows (VC build)\0" - VALUE "InternalName", "libmicrohttpd\0" -#if defined(_DEBUG) - VALUE "OriginalFilename", "libmicrohttpd_d.dll\0" -#else - VALUE "OriginalFilename", "libmicrohttpd.dll\0" -#endif - VALUE "CompanyName", "Free Software Foundation\0" - VALUE "LegalCopyright", "Copyright (C) 2007-2015 Christian Grothoff and project contributors\0" - VALUE "Comments", "http://www.gnu.org/software/libmicrohttpd/\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0409, 0 /* US English, ASCII */ - END -END