diff --git a/lib/include/restd_server.h b/lib/include/restd_server.h index 0713da4..eba4a5e 100644 --- a/lib/include/restd_server.h +++ b/lib/include/restd_server.h @@ -147,6 +147,8 @@ enum restd_log_e restd_log_level(enum restd_log_e log_level); extern restd_server_t *restd_server_new(void); extern void restd_server_free(restd_server_t *server); extern int restd_server_start(restd_server_t *server); +extern int restd_server_attach_event_loop(restd_server_t *server, struct event_base *ev_base); + extern void restd_server_set_option(restd_server_t *server, const char *key, const char *value); extern char *restd_server_get_option(restd_server_t *server, const char *key); diff --git a/lib/src/restd_server.c b/lib/src/restd_server.c index ede569f..68bad0d 100644 --- a/lib/src/restd_server.c +++ b/lib/src/restd_server.c @@ -334,6 +334,17 @@ int restd_server_start(restd_server_t *server) return exitstatus; } +/*--------------------------------------------------------------------------*/ + +int restd_server_attach_event_loop(restd_server_t *server, struct event_base *ev_base) +{ + if (server == NULL) + return -1; + + server->evbase = ev_base; + return 0; +} + /** * Set server option. * diff --git a/lib/tests/launcher.sh b/lib/tests/launcher.sh new file mode 100755 index 0000000..ff793f5 --- /dev/null +++ b/lib/tests/launcher.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +if [ $# = 0 ]; then + echo "This program is called by make. Please use \"make test\" command instead." + exit 1 +fi + +FAIL=0 +FAILDESC="" +for EXECUTABLE in $*; do + ./$EXECUTABLE + echo "" + if [ $? != 0 ]; then + FAIL=1 + FAILDESC="$FAILDESC $EXECUTABLE" + fi +done + +if [ $FAIL != 0 ]; then + echo "======================================================================" + echo "**** OOOOOPS!!! UNSUCESSFUL UNIT TEST FOUND. PLEASE FIX AND RERUN ****" + echo "======================================================================" + echo "Fails in =>$FAILDESC" + exit 1 +fi + +echo "======================================================================" +echo "**** Good job! All tests are successful ****" +echo "======================================================================" +echo "* ____ _ All tests have finished successfully. *" +echo "* / ___| ___ ___ __| | | | ___ | |__ | | *" +echo "* | | _ / _ \ / _ \ / _\` | _ | |/ _ \| '_ \ | | *" +echo "* | |_| | (_) | (_) | (_| | | |_| | (_) | |_) | |_| *" +echo "* \____|\___/ \___/ \__,_| \___/ \___/|_.__/ (_) *" +echo "======================================================================" +echo "Tested: $*" +exit 0 diff --git a/lib/tests/qunit.h b/lib/tests/qunit.h new file mode 100644 index 0000000..4765572 --- /dev/null +++ b/lib/tests/qunit.h @@ -0,0 +1,125 @@ +/****************************************************************************** + * qunit - C Unit Test Framework + * + * Copyright (c) 2014-2015 Seungyoung Kim. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +/** + * qunit C Unit Test Framework. + * + * @file qunit.h + */ + +#ifndef QUNIT_H +#define QUNIT_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define OUTSTREAM (stdout) +#define PRINT(fmt, args...) do { \ + fprintf(OUTSTREAM, "" fmt, ##args); \ + } while(0) +#define PRINTLN(fmt, args...) do { \ + fprintf(OUTSTREAM, "" fmt "\n", ##args); \ + } while(0) + +#define QUNIT_START(title) \ +char *_q_title = title; \ +int _q_tot_tests = 0; \ +int _q_tot_failed = 0; \ +int _q_this_failed = 0; \ +int _q_errcnt = 0; \ +int _q_assert_cnt = 0; /* number of assert test in a test */ \ +int _q_assert_dot_cnt = 0; /* number of dots printed out in a test. */ \ +long _q_timer; \ +int main(int argc, char **argv) { \ + PRINTLN("%s", _q_title); \ + PRINTLN("======================================================================"); \ + +#define QUNIT_END() \ + _TEST_RESULT(); \ + PRINTLN("======================================================================"); \ + PRINTLN("%s - %d/%d tests passed.", \ + ((_q_tot_failed == 0) ? "PASS" : "FAIL"), \ + (_q_tot_tests - _q_tot_failed), _q_tot_tests); \ + return _q_tot_failed; \ +} + +#define TEST(name) \ + _TEST_RESULT(); \ + _q_tot_tests++; \ + _q_assert_cnt = 0; \ + _q_assert_dot_cnt = 0; \ + PRINT("* TEST : %s ", name); \ + TIMER_START(_q_timer); + +#define _TEST_RESULT() \ + TIMER_STOP(_q_timer); \ + if (_q_tot_tests ) PRINTLN(" %s (%d assertions, %ldms)", \ + (_q_this_failed) ? "FAIL" : "OK", _q_assert_cnt, _q_timer); \ + _q_tot_failed += (_q_this_failed) ? 1 : 0; \ + _q_this_failed = 0; + +#define ASSERT(expr) \ + _q_assert_cnt++; \ + if (! (expr)) { \ + _q_this_failed++; \ + PRINTLN("\nAssertion '%s' failed (%s:%d)", #expr, __FILE__, __LINE__); \ + } else if (_q_assert_dot_cnt < 30) { \ + PRINT("."); \ + _q_assert_dot_cnt++; \ + } + +#define ASSERT_EQUAL_STR(s1, s2) ASSERT(!strcmp(s1, s2)) +#define ASSERT_EQUAL_INT(d1, d2) ASSERT(d1 == d2) +#define ASSERT_EQUAL_BOOL(d1, d2) ASSERT(d1 == d2) +#define ASSERT_EQUAL_PT(p1, p2) ASSERT(p1 == p2) +#define ASSERT_EQUAL_MEM(p1, p2, n) ASSERT(!memcmp(p1, p2, n)) +#define ASSERT_NULL(p) ASSERT(NULL == p) +#define ASSERT_NOT_NULL(p) ASSERT(NULL != p) +#define ASSERT_TRUE(b) ASSERT(b) +#define ASSERT_FALSE(b) ASSERT(!(b)) + +#define TIMER_START(x) do { \ + x = qtime_current_milli(); \ + } while(0) + +#define TIMER_STOP(x) do { \ + x = qtime_current_milli() - x; \ + } while(0) + +#ifdef __cplusplus +} +#endif + +#endif /* QUNIT_H */ diff --git a/lib/tests/restd.c b/lib/tests/restd.c new file mode 100644 index 0000000..547d3b2 --- /dev/null +++ b/lib/tests/restd.c @@ -0,0 +1,102 @@ +/*! + * main.c + * + * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * @Author: NADAL Jean-Baptiste + * @Date: 08/11/2019 + * + */ + +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com + +/*-------------------------------- INCLUDES ---------------------------------*/ + +#include + +#include + +/*--------------------------------------------------------------------------*/ + +int my_http_get_handler(short event, restd_conn_t *conn, void *userdata) +{ + if (event & RESTD_EVENT_READ) + { + if (restd_http_get_status(conn) == RESTD_HTTP_REQ_DONE) + { + restd_http_response(conn, 200, "application/json", "{\"status\": false}", 17); + return restd_http_is_keepalive_request(conn) ? RESTD_DONE : RESTD_CLOSE; + } + } + return RESTD_OK; +} + +/*--------------------------------------------------------------------------*/ + +int my_error_handler(short event, restd_conn_t *conn, void *userdata) +{ + int http_code = 500; + if (event & RESTD_ERROR_METHOD_NOT_ALLOWED) + { + http_code = 405; + } + else if (event & RESTD_ERROR_PATH_NOT_FOUND) + { + http_code = 404; + } + + restd_http_response(conn, http_code, "application/json", "{\"status\":\"error\"}", 18); + return RESTD_CLOSE; // Close connection. +} + +/*--------------------------------------------------------------------------*/ + +void usage(void) +{ + printf("Usage : domo-iot [web server path] \n"); + printf("web server path: \t root path of the Web server.\n"); +} + +/*--------------------------------------------------------------------------*/ + +int main(int argc, char **argv) +{ + restd_server_t *server; + + if (argc < 2) + { + usage(); + return -1; + } + + restd_log_level(RESTD_LOG_DEBUG); + server = restd_server_new(); + restd_server_set_option(server, "server.port", "8888"); + restd_server_set_option(server, "server.root_path", argv[1]); + + restd_server_register_request_handler(server, restd_rest_handler); + restd_server_register_error_handler(server, my_error_handler); + + restd_server_register_hook(server, restd_http_handler, NULL); + restd_server_register_hook_on_path(server, "GET", "/api/zob", my_http_get_handler, NULL); + restd_server_register_hook_on_path(server, "GET", "/api/zob2", my_http_get_handler, NULL); + restd_server_register_hook_on_path(server, "PUT", "/api/zob/25", my_http_get_handler, NULL); + + return restd_server_start(server); +} diff --git a/lib/tests/test_restd.c b/lib/tests/test_restd.c new file mode 100644 index 0000000..84730bf --- /dev/null +++ b/lib/tests/test_restd.c @@ -0,0 +1,15 @@ +#include "qunit.h" +#include "qlibc.h" + +QUNIT_START("Test title"); + +TEST("Test name1") { + ASSERT_EQUAL_STR("abc", "abc"); + ASSERT_EQUAL_INT(8, 8); +} + +TEST("Test name2") { + ASSERT_EQUAL_PT(NULL == NULL); +} + +QUNIT_END(); \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ffb0d7e..02e18cf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,6 +13,7 @@ include_directories (${CMAKE_SOURCE_DIR}/build/libevent/include) include_directories (${CMAKE_SOURCE_DIR}/qlibc/include) include_directories (${CMAKE_SOURCE_DIR}/json-c) include_directories (${CMAKE_SOURCE_DIR}/build/json-c) +include_directories (${CMAKE_SOURCE_DIR}/nats.c/src) include_directories (${CMAKE_CURRENT_SOURCE_DIR}) #set(CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic -Werror=strict-aliasing") @@ -21,11 +22,13 @@ file( GLOB_RECURSE source_files main.c + broker/nats_broker.c devices/devices_manager.c devices/device.c devices/outlet_dio.c devices/shutter.c devices/sprinkler.c + rest/rest_handler.c ) add_executable (domo-iot ${source_files}) @@ -36,8 +39,9 @@ target_link_libraries (domo-iot restd-static qlibc-static qlibcext-static - event json-c + event + event_pthreads ) install (TARGETS domo-iot DESTINATION local/bin) diff --git a/src/broker/nats_broker.c b/src/broker/nats_broker.c new file mode 100644 index 0000000..1e54986 --- /dev/null +++ b/src/broker/nats_broker.c @@ -0,0 +1,140 @@ +/*! + * nats_broker.c + * + * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * @Author: NADAL Jean-Baptiste + * @Date: 26/12/2019 + * + */ + +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com + +/*------------------------------- INCLUDES ----------------------------------*/ + +#include + +#include + +#include "macro.h" + +#include "nats_broker.h" + +#define kNatsServerURL "nats.nadal-fr.com" + +/*--------------------------------------------------------------------------*/ + +static void onMsg(natsConnection *nc, natsSubscription *sub, natsMsg *msg, void *closure) +{ + printf("Received msg: %s - %.*s\n", + natsMsg_GetSubject(msg), + natsMsg_GetDataLength(msg), + natsMsg_GetData(msg)); + + // Need to destroy the message! + natsMsg_Destroy(msg); +} + +/*--------------------------------------------------------------------------*/ + +nats_broker_t *nats_broker_new(void) +{ + nats_broker_t *broker = NEW_OBJECT(nats_broker_t); + if (broker == NULL) + { + return NULL; + } + + bzero((void *)broker, sizeof(nats_broker_t)); + + return broker; +} + +/*--------------------------------------------------------------------------*/ + +void nats_broker_free(nats_broker_t *broker) +{ + if (broker == NULL) + { + return; + } + + // Destroy all our objects to avoid report of memory leak + if (broker->sub != NULL) + natsSubscription_Destroy(broker->sub); + if (broker->conn != NULL) + natsConnection_Destroy(broker->conn); + if (broker->opts != NULL) + natsOptions_Destroy(broker->opts); + + free(broker); +} + +/*--------------------------------------------------------------------------*/ + +int nats_broker_setup(nats_broker_t *broker, struct event_base *ev_base) +{ + natsStatus status; + + if (broker == NULL) + { + return -1; + } + + nats_Open(-1); + + // One time initialization of things that we need. + natsLibevent_Init(); + + if (natsOptions_Create(&broker->opts) != NATS_OK) + return -1; + + if (natsOptions_UseGlobalMessageDelivery(broker->opts, true) != NATS_OK) + return -2; + + // Indicate which loop and callbacks to use once connected. + if (natsOptions_SetEventLoop(broker->opts, (void *)ev_base, + natsLibevent_Attach, + natsLibevent_Read, + natsLibevent_Write, + natsLibevent_Detach) != NATS_OK) + return -3; + + if (natsOptions_SetURL(broker->opts, kNatsServerURL) != NATS_OK) + return -4; + + return 0; +} + +/*--------------------------------------------------------------------------*/ + +int nats_broker_connect(nats_broker_t *broker, const char *subject) +{ + if (natsConnection_Connect(&broker->conn, broker->opts) != NATS_OK) + return -1; + + if (natsConnection_Subscribe(&broker->sub, broker->conn, subject, onMsg, NULL) != NATS_OK) + return -2; + + // For maximum performance, set no limit on the number of pending messages. + if (natsSubscription_SetPendingLimits(broker->sub, -1, -1)!= NATS_OK) + return -3; + + return 0; +} diff --git a/src/broker/nats_broker.h b/src/broker/nats_broker.h new file mode 100644 index 0000000..7bb7fb7 --- /dev/null +++ b/src/broker/nats_broker.h @@ -0,0 +1,55 @@ +/*! + * nats_broker.h + * + * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * @Author: NADAL Jean-Baptiste + * @Date: 26/12/2019 + * + */ + +#ifndef _NATS_BROKER_H +#define _NATS_BROKER_H + +/*------------------------------- INCLUDES ----------------------------------*/ + +#include + +/*------------------------------- TYPEDEFS ----------------------------------*/ + +typedef struct nats_broker_s nats_broker_t; + +/** + * Nats Broker Container. + */ +struct nats_broker_s +{ + natsConnection *conn; + natsOptions *opts; + natsSubscription *sub; +}; + +/*--------------------------- PUBLIC FUNCTIONS -------------------------------*/ + +extern nats_broker_t *nats_broker_new(void); +extern void nats_broker_free(nats_broker_t *broker); + +extern int nats_broker_setup(nats_broker_t *broker, struct event_base *ev_base); +extern int nats_broker_connect(nats_broker_t *broker, const char *subject); + +#endif /*_NATS_BROKER_H */ diff --git a/src/deprecated/broker/nats-broker.cpp b/src/deprecated/broker/nats-broker.cpp deleted file mode 100644 index b24cec4..0000000 --- a/src/deprecated/broker/nats-broker.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/*! - * nats-broker.cpp - * - * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * @Author: NADAL Jean-Baptiste - * @Date: 13/11/2019 - * - */ - -// This is an independent project of an individual developer. Dear PVS-Studio, please check it. -// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com - -/*------------------------------- INCLUDES ----------------------------------*/ - -#include - -#include "nats-broker.h" - -#include - -#define kNatsServerURL "nats.nadal-fr.com" - -static void onMsg(natsConnection *nc, natsSubscription *sub, natsMsg *msg, void *closure) -{ - printf("Received msg: %s - %.*s\n", - natsMsg_GetSubject(msg), - natsMsg_GetDataLength(msg), - natsMsg_GetData(msg)); - - // Need to destroy the message! - natsMsg_Destroy(msg); -} - -/*! ---------------------------------------------------------------------------- - * @fn NatsBroker - * - * @brief Constructor of the Nats Broker. - */ -NatsBroker::NatsBroker(void) : m_conn(NULL), m_opts(NULL), m_sub(NULL) -{ -} - -/*! ---------------------------------------------------------------------------- - * @fn ~NatsBroker - * - * @brief Destructor of the Nats. - */ -NatsBroker::~NatsBroker(void) -{ -} - -/*! ---------------------------------------------------------------------------- - * @fn setup - * - * @brief Setup the Broker. - */ -int NatsBroker::setup(uv_loop_t *an_evt_loop) -{ - natsStatus the_status; - - nats_Open(-1); - - // One time initialization of things that we need. - natsLibuv_Init(); - - // Libuv is not thread-safe. Almost all calls to libuv need to - // occur from the thread where the loop is running. NATS library - // may have to call into the event loop from different threads. - // This call allows natsLibuv APIs to know if they are executing - // from the event loop thread or not. - natsLibuv_SetThreadLocalLoop(an_evt_loop); - - if (natsOptions_Create(&m_opts) != NATS_OK) - - return -1; - - if (natsOptions_UseGlobalMessageDelivery(m_opts, true) != NATS_OK) - return -2; - - // Indicate which loop and callbacks to use once connected. - if (natsOptions_SetEventLoop(m_opts, (void *)an_evt_loop, - natsLibuv_Attach, - natsLibuv_Read, - natsLibuv_Write, - natsLibuv_Detach) != NATS_OK) - return -3; - - if (natsOptions_SetURL(m_opts, kNatsServerURL) != NATS_OK) - return -4; - - return 0; -} - -/*! ---------------------------------------------------------------------------- - * @fn terminate - * - * @brief Terminate the Broker. - */ -int NatsBroker::terminate(void) -{ - // Destroy all our objects to avoid report of memory leak - if (m_sub != NULL) - natsSubscription_Destroy(m_sub); - if (m_conn != NULL) - natsConnection_Destroy(m_conn); - if (m_opts != NULL) - natsOptions_Destroy(m_opts); - - return 0; -} - -/*! ---------------------------------------------------------------------------- - * @fn connect - * - * @brief Ccnnect to the Broker server. - */ -int NatsBroker::connect(void) -{ - if (natsConnection_Connect(&m_conn, m_opts) != NATS_OK) - return -1; - - if (natsConnection_Subscribe(&m_sub, m_conn, "foo", onMsg, NULL) != NATS_OK) - return -2; - - // For maximum performance, set no limit on the number of pending messages. - if (natsSubscription_SetPendingLimits(m_sub, -1, -1)!= NATS_OK) - return -3; - - return 0; -} diff --git a/src/main.c b/src/main.c index 547d3b2..32c3e03 100644 --- a/src/main.c +++ b/src/main.c @@ -1,83 +1,53 @@ /*! - * main.c - * - * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * @Author: NADAL Jean-Baptiste - * @Date: 08/11/2019 - * - */ + * main.c + * + * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * @Author: NADAL Jean-Baptiste + * @Date: 08/11/2019 + * + */ // This is an independent project of an individual developer. Dear PVS-Studio, please check it. // PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com /*-------------------------------- INCLUDES ---------------------------------*/ -#include +#include -#include - -/*--------------------------------------------------------------------------*/ - -int my_http_get_handler(short event, restd_conn_t *conn, void *userdata) -{ - if (event & RESTD_EVENT_READ) - { - if (restd_http_get_status(conn) == RESTD_HTTP_REQ_DONE) - { - restd_http_response(conn, 200, "application/json", "{\"status\": false}", 17); - return restd_http_is_keepalive_request(conn) ? RESTD_DONE : RESTD_CLOSE; - } - } - return RESTD_OK; -} - -/*--------------------------------------------------------------------------*/ - -int my_error_handler(short event, restd_conn_t *conn, void *userdata) -{ - int http_code = 500; - if (event & RESTD_ERROR_METHOD_NOT_ALLOWED) - { - http_code = 405; - } - else if (event & RESTD_ERROR_PATH_NOT_FOUND) - { - http_code = 404; - } - - restd_http_response(conn, http_code, "application/json", "{\"status\":\"error\"}", 18); - return RESTD_CLOSE; // Close connection. -} +#include "rest/rest_handler.h" +#include "broker/nats_broker.h" /*--------------------------------------------------------------------------*/ void usage(void) { - printf("Usage : domo-iot [web server path] \n"); - printf("web server path: \t root path of the Web server.\n"); + printf("Usage : domo-iot [web server path] \n"); + printf("web server path: \t root path of the Web server.\n"); } /*--------------------------------------------------------------------------*/ int main(int argc, char **argv) { - restd_server_t *server; + struct event_base *ev_base; + restd_server_t *rest_server; + nats_broker_t *nats_broker; if (argc < 2) { @@ -86,17 +56,42 @@ int main(int argc, char **argv) } restd_log_level(RESTD_LOG_DEBUG); - server = restd_server_new(); - restd_server_set_option(server, "server.port", "8888"); - restd_server_set_option(server, "server.root_path", argv[1]); - restd_server_register_request_handler(server, restd_rest_handler); - restd_server_register_error_handler(server, my_error_handler); + /* event loop */ + ev_base = event_base_new(); + if (!ev_base) + { + fprintf(stderr, "Failed to create a new event base.\n"); + return -1; + } - restd_server_register_hook(server, restd_http_handler, NULL); - restd_server_register_hook_on_path(server, "GET", "/api/zob", my_http_get_handler, NULL); - restd_server_register_hook_on_path(server, "GET", "/api/zob2", my_http_get_handler, NULL); - restd_server_register_hook_on_path(server, "PUT", "/api/zob/25", my_http_get_handler, NULL); + /* Create the rest Server. */ + rest_server = restd_server_new(); + if (!rest_server) + { + fprintf(stderr, "Failed to create a rest server.\n"); + return -1; + } - return restd_server_start(server); + restd_server_attach_event_loop(rest_server, ev_base); + + if (setup_rest_server(rest_server, "8888", argv[1]) != 0) + { + fprintf(stderr, "Failed to setup rest Server\n."); + restd_server_free(rest_server); + return -1; + } + + /* create and setup the nats broker. */ + nats_broker = nats_broker_new(); + if (!nats_broker) + { + fprintf(stderr, "Failed to create a nats broker.\n"); + return -1; + } + nats_broker_setup(nats_broker, ev_base); + nats_broker_connect(nats_broker, "foo"); + + /* start the rest server */ + return restd_server_start(rest_server); } diff --git a/src/rest/rest_handler.c b/src/rest/rest_handler.c new file mode 100644 index 0000000..1b67d5d --- /dev/null +++ b/src/rest/rest_handler.c @@ -0,0 +1,64 @@ +/*! + * rest_handler.c + * + * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * @Author: NADAL Jean-Baptiste + * @Date: 26/12/2019 + * + */ + +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com + +/*------------------------------- INCLUDES ----------------------------------*/ + +#include "rest_handler.h" + +/*--------------------------------------------------------------------------*/ + +int my_error_handler(short event, restd_conn_t *conn, void *userdata) +{ + int http_code = 500; + if (event & RESTD_ERROR_METHOD_NOT_ALLOWED) + { + http_code = 405; + } + else if (event & RESTD_ERROR_PATH_NOT_FOUND) + { + http_code = 404; + } + + restd_http_response(conn, http_code, "application/json", "{\"status\":\"error\"}", 18); + return RESTD_CLOSE; // Close connection. +} + +/*--------------------------------------------------------------------------*/ + +int setup_rest_server(restd_server_t *rest_server, const char *port, const char *root_path) +{ + restd_server_set_option(rest_server, "server.port", port); + restd_server_set_option(rest_server, "server.root_path",root_path); + + restd_server_register_request_handler(rest_server, restd_rest_handler); + restd_server_register_error_handler(rest_server, my_error_handler); + + restd_server_register_hook(rest_server, restd_http_handler, NULL); + + return 0; +} diff --git a/src/deprecated/broker/nats-broker.h b/src/rest/rest_handler.h similarity index 62% rename from src/deprecated/broker/nats-broker.h rename to src/rest/rest_handler.h index 1f27cb1..0d05568 100644 --- a/src/deprecated/broker/nats-broker.h +++ b/src/rest/rest_handler.h @@ -1,5 +1,5 @@ /*! - * nats-broker.h + * rest_handler.h * * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. * @@ -19,37 +19,17 @@ * MA 02110-1301 USA * * @Author: NADAL Jean-Baptiste - * @Date: 13/11/2019 + * @Date: 26/12/2019 * */ -#ifndef _NATS_BROKER_H -#define _NATS_BROKER_H +#ifndef _REST_HANDLER_H +#define _REST_HANDLER_H /*------------------------------- INCLUDES ----------------------------------*/ -#include -#include +#include -/*---------------------------------- Deps -----------------------------------*/ +extern int setup_rest_server(restd_server_t *rest_server, const char *port, const char *root_path); -/*--------------------------------- CLASS ----------------------------------*/ - -class NatsBroker -{ -public: - NatsBroker(void); - ~NatsBroker(void); - - int setup(uv_loop_t *an_evt_loop); - int terminate(void); - - int connect(void); - -private: - natsConnection *m_conn; - natsOptions *m_opts; - natsSubscription *m_sub; -}; - -#endif /* _NATS_BROKER_H */ +#endif /*_REST_HANDLER_H */