diff --git a/include/ut_control_plane.h b/include/ut_control_plane.h index 1858d81..7693953 100644 --- a/include/ut_control_plane.h +++ b/include/ut_control_plane.h @@ -45,48 +45,33 @@ typedef struct int32_t value; } ut_control_keyStringMapping_t; -typedef enum -{ - POST = 0, - GET, - INVALID -}eRestApi_t; - typedef void ut_controlPlane_instance_t; /*!< Handle to a control plane instance */ /** - * @brief Callback function type for handling REST_API from POST triggers. + * @brief Callback function type for handling POST triggers. * * This callback function is invoked when a POST request is received - * at a registered endpoint and the triggerKey is matched on the incoming data. + * at the ut control server and the triggerKey is matched on the incoming data. * * @param triggerKey The trigger key that was matched. * @param instance The key-value pair instance containing the incoming data. * @param userData User-defined data passed to the callback function. */ -typedef void (*ut_control_REST_API_POST_callback_t)(char *triggerKey, ut_kvp_instance_t *instance, void *userData); +typedef void (*ut_control_on_message_callback_t)(char *triggerKey, ut_kvp_instance_t *instance, void *userData); /** * @brief Callback function for handling REST_API from GET triggers. * * This callback function is invoked when a GET request is received - * at a registered endpoint. It allows the user to implement the - * REST API call. + * at UT control server and the rest api name of the GET request matches the restAPI parameter + * registered with the UT control server. * * @param restAPI The name of the REST API being called. * @param userData User-defined data passed to the callback function. * * @returns A character string containing the result of the API call, in JSON or YAML format */ -typedef char *(*ut_control_REST_API_GET_callback_t)(char *restAPI, void *userData); - -typedef struct -{ - ut_control_REST_API_GET_callback_t callbackFunctionGET; - ut_control_REST_API_POST_callback_t callbackFunctionPOST; - eRestApi_t restApiType; // POST = 0, GET = 1 - void *userData; // user-defined data -} ut_control_rest_api_handler_t; +typedef char *(*ut_control_endpoint_callback_t)(char *restAPI, void *userData); /** * @brief Initializes a control plane instance. @@ -101,18 +86,16 @@ ut_controlPlane_instance_t* UT_ControlPlane_Init( uint32_t monitorPort ); * @param key - Null-terminated string representing the message key to trigger the callback. * @param callbackFunction - Callback function to be invoked when the key is received. * @param userData - Handle to the caller instance. - * @param restApiType - Type of REST API to be registered.(POST = 0, GET = 1) * @returns Status of the registration operation (`ut_control_plane_status_t`). * @retval UT_CONTROL_PLANE_STATUS_OK - Success * @retval UT_CONTROL_PLANE_STATUS_INVALID_HANDLE - Invalid control plane instance handle. * @retval UT_CONTROL_PLANE_STATUS_INVALID_PARAM - Invalid parameter passed * @retval UT_CONTROL_PLANE_STATUS_CALLBACK_LIST_FULL - Callback list is full - * *******************NOTE: This function will be deprecated in future major releases.******************* */ ut_control_plane_status_t UT_ControlPlane_RegisterCallbackOnMessage(ut_controlPlane_instance_t *pInstance, char *key, - ut_control_REST_API_POST_callback_t callbackFunction, - void *userData, eRestApi_t restApiType); + ut_control_on_message_callback_t callbackFunction, + void *userData); /** * @brief Registers a callback function for REST API endpoint. @@ -126,10 +109,9 @@ ut_control_plane_status_t UT_ControlPlane_RegisterCallbackOnMessage(ut_controlPl * * @returns A status code indicating the success or failure of the registration. */ -ut_control_plane_status_t UT_ControlPlane_RegisterAPIEndpointHandler( +ut_control_plane_status_t UT_ControlPlane_RegisterEndPointCallback( ut_controlPlane_instance_t *pInstance, - char *restAPI, - ut_control_rest_api_handler_t *handler); + char *restAPI, ut_control_endpoint_callback_t callbackFunction, void *userData); /** * @brief Starts the control plane listening for incoming messages. diff --git a/src/ut_control_plane.c b/src/ut_control_plane.c index 324470b..bceef55 100644 --- a/src/ut_control_plane.c +++ b/src/ut_control_plane.c @@ -39,12 +39,16 @@ typedef struct { - char key[UT_KVP_MAX_ELEMENT_SIZE]; - ut_control_REST_API_POST_callback_t pCallback; - ut_control_REST_API_GET_callback_t pStringCallback; - void* userData; - eRestApi_t pRestApi; -}CallbackEntry_t; + ut_control_on_message_callback_t pCallback; + ut_control_endpoint_callback_t pStringCallback; +}Callback_type_t; + +typedef struct +{ + char key[UT_KVP_MAX_ELEMENT_SIZE]; + Callback_type_t pCallbackType; + void *userData; +} CallbackEntry_t; typedef enum { @@ -170,7 +174,7 @@ static void call_callback_on_match(cp_message_t *mssg, ut_cp_instance_internal_t if (UT_KVP_STATUS_SUCCESS == ut_kvp_getStringField(pkvpInstance, entry.key, result_kvp, UT_KVP_MAX_ELEMENT_SIZE)) { // call callback - entry.pCallback(entry.key, pkvpInstance, entry.userData); + entry.pCallbackType.pCallback(entry.key, pkvpInstance, entry.userData); } } ut_kvp_destroyInstance(pkvpInstance); @@ -321,7 +325,7 @@ static char* create_response(ut_cp_instance_internal_t *pInternal, const char* k if (compareStrings(entry.key, key) == 0) { - kvpData = entry.pStringCallback((char *)key, entry.userData); + kvpData = entry.pCallbackType.pStringCallback((char *)key, entry.userData); pkvpInstance = ut_kvp_createInstance(); // The `kvpData` memory passed gets freed as part of destroy instance @@ -712,7 +716,7 @@ void UT_ControlPlane_Stop( ut_controlPlane_instance_t *pInstance ) pInternal->state_machine_thread_handle = 0; } -ut_control_plane_status_t UT_ControlPlane_RegisterCallbackOnMessage(ut_controlPlane_instance_t *pInstance, char *key, ut_control_REST_API_POST_callback_t callbackFunction, void *userData, eRestApi_t restApiType) +ut_control_plane_status_t UT_ControlPlane_RegisterCallbackOnMessage(ut_controlPlane_instance_t *pInstance, char *key, ut_control_on_message_callback_t callbackFunction, void *userData) { ut_cp_instance_internal_t *pInternal = (ut_cp_instance_internal_t *)pInstance; @@ -740,30 +744,20 @@ ut_control_plane_status_t UT_ControlPlane_RegisterCallbackOnMessage(ut_controlPl return UT_CONTROL_PLANE_STATUS_INVALID_PARAM; } - if ( restApiType == INVALID ) - { - UT_CONTROL_PLANE_ERROR("Invalid Rest API\n"); - return UT_CONTROL_PLANE_STATUS_INVALID_PARAM; - } - if ( pInternal->callback_entry_index >= UT_CONTROL_PLANE_MAX_CALLBACK_ENTRIES ) { return UT_CONTROL_PLANE_STATUS_LIST_FULL; } strncpy(pInternal->callbackEntryList[pInternal->callback_entry_index].key, key,UT_KVP_MAX_ELEMENT_SIZE); - pInternal->callbackEntryList[pInternal->callback_entry_index].pCallback = callbackFunction; + pInternal->callbackEntryList[pInternal->callback_entry_index].pCallbackType.pCallback = callbackFunction; pInternal->callbackEntryList[pInternal->callback_entry_index].userData = userData; - pInternal->callbackEntryList[pInternal->callback_entry_index].pStringCallback = NULL; - pInternal->callbackEntryList[pInternal->callback_entry_index].pRestApi = restApiType; + pInternal->callbackEntryList[pInternal->callback_entry_index].pCallbackType.pStringCallback = NULL; pInternal->callback_entry_index++; UT_CONTROL_PLANE_DEBUG("callback_entry_index : %d\n", pInternal->callback_entry_index); return UT_CONTROL_PLANE_STATUS_OK; } -ut_control_plane_status_t UT_ControlPlane_RegisterAPIEndpointHandler( - ut_controlPlane_instance_t *pInstance, - char *restAPI, - ut_control_rest_api_handler_t *handler) +ut_control_plane_status_t UT_ControlPlane_RegisterEndPointCallback(ut_controlPlane_instance_t *pInstance, char *restAPI, ut_control_endpoint_callback_t callbackFunction, void *userData) { ut_cp_instance_internal_t *pInternal = (ut_cp_instance_internal_t *)pInstance; @@ -780,22 +774,15 @@ ut_control_plane_status_t UT_ControlPlane_RegisterAPIEndpointHandler( return UT_CONTROL_PLANE_STATUS_INVALID_PARAM; } - if (handler->callbackFunctionGET == NULL && handler->callbackFunctionPOST == NULL) + if (callbackFunction == NULL) { - UT_CONTROL_PLANE_ERROR("NULL callbackFunctions\n"); + UT_CONTROL_PLANE_ERROR("NULL callbackFunction\n"); return UT_CONTROL_PLANE_STATUS_INVALID_PARAM; } - if (handler->userData == NULL && handler->restApiType == POST) + if (userData == NULL) { UT_CONTROL_PLANE_ERROR("NULL userData\n"); - return UT_CONTROL_PLANE_STATUS_INVALID_PARAM; - } - - if (handler->restApiType == INVALID) - { - UT_CONTROL_PLANE_ERROR("Invalid Rest API\n"); - return UT_CONTROL_PLANE_STATUS_INVALID_PARAM; } if (pInternal->callback_entry_index >= UT_CONTROL_PLANE_MAX_CALLBACK_ENTRIES) @@ -803,10 +790,9 @@ ut_control_plane_status_t UT_ControlPlane_RegisterAPIEndpointHandler( return UT_CONTROL_PLANE_STATUS_LIST_FULL; } strncpy(pInternal->callbackEntryList[pInternal->callback_entry_index].key, restAPI, UT_KVP_MAX_ELEMENT_SIZE); - pInternal->callbackEntryList[pInternal->callback_entry_index].pCallback = handler->callbackFunctionPOST; - pInternal->callbackEntryList[pInternal->callback_entry_index].userData = handler->userData; - pInternal->callbackEntryList[pInternal->callback_entry_index].pStringCallback = handler->callbackFunctionGET; - pInternal->callbackEntryList[pInternal->callback_entry_index].pRestApi = handler->restApiType; + pInternal->callbackEntryList[pInternal->callback_entry_index].pCallbackType.pCallback = NULL; + pInternal->callbackEntryList[pInternal->callback_entry_index].userData = userData; + pInternal->callbackEntryList[pInternal->callback_entry_index].pCallbackType.pStringCallback = callbackFunction; pInternal->callback_entry_index++; UT_CONTROL_PLANE_DEBUG("callback_entry_index : %d\n", pInternal->callback_entry_index); return UT_CONTROL_PLANE_STATUS_OK; diff --git a/tests/src/ut_test_control_plane.c b/tests/src/ut_test_control_plane.c index 9b205c3..8fd0859 100644 --- a/tests/src/ut_test_control_plane.c +++ b/tests/src/ut_test_control_plane.c @@ -41,6 +41,7 @@ static UT_test_suite_t *gpAssertSuite1 = NULL; static UT_test_suite_t *gpAssertSuite2 = NULL; static UT_test_suite_t *gpAssertSuite3 = NULL; +static UT_test_suite_t *gpAssertSuite4 = NULL; static ut_controlPlane_instance_t *gInstance = NULL; static volatile bool gMessageRecievedYAML = false; @@ -126,66 +127,91 @@ static void test_ut_control_l1_testStartStop() UT_LOG("test_ut_control_l1_testStartStop\n"); } -static void test_ut_control_l1_regsiterCallback() +static void test_ut_control_l1_regsiter_on_message_Callback() { ut_controlPlane_instance_t *pInstance; ut_control_plane_status_t status; void* userData = (void* )strdup("testJSONCallbackStringInvalidParam"); - UT_LOG("\ntest_ut_control_l1_regsiterCallback\n"); + UT_LOG("\test_ut_control_l1_regsiter_on_message_Callback\n"); pInstance = UT_ControlPlane_Init(9000); UT_ASSERT(pInstance != NULL); - ut_control_rest_api_handler_t handler = { - .callbackFunctionGET = &testGETJSONCallback, - .callbackFunctionPOST = &testYAMLCallback, - .userData = userData, - .restApiType = POST - }; - status = UT_ControlPlane_RegisterAPIEndpointHandler(pInstance, NULL, &handler); + status = UT_ControlPlane_RegisterCallbackOnMessage(pInstance, NULL, &testYAMLCallback, userData); UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_INVALID_PARAM); - handler.callbackFunctionGET = NULL; - handler.callbackFunctionPOST = NULL; - status = UT_ControlPlane_RegisterAPIEndpointHandler(pInstance, "test/yamlData", &handler); + status = UT_ControlPlane_RegisterCallbackOnMessage(pInstance, "test/yamlData", NULL, userData); UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_INVALID_PARAM); - handler.callbackFunctionGET = &testGETYamlCallback; - handler.callbackFunctionPOST = &testYAMLCallback; - handler.userData = NULL; - status = UT_ControlPlane_RegisterAPIEndpointHandler(pInstance, "test/yamlData", &handler); + status = UT_ControlPlane_RegisterCallbackOnMessage(pInstance, "test/yamlData", &testYAMLCallback, NULL); UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_INVALID_PARAM); - handler.userData = userData; - handler.restApiType = INVALID; - status = UT_ControlPlane_RegisterAPIEndpointHandler(pInstance, "test/yamlData", &handler); + status = UT_ControlPlane_RegisterCallbackOnMessage(NULL, "test/yamlData", &testYAMLCallback, userData); + UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_INVALID_HANDLE); + + status = UT_ControlPlane_RegisterCallbackOnMessage(pInstance, "ttest/yamlData", &testYAMLCallback, userData); + UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_OK); + free(userData); //freeing the userData after registration + + userData = (void* )strdup("testJSONCallbackString"); + for (int i = 0; i< UT_CONTROL_PLANE_MAX_CALLBACK_ENTRIES - 1; i++ ) + { + status = UT_ControlPlane_RegisterCallbackOnMessage(pInstance, "test/yamlData", &testYAMLCallback, userData); + UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_OK); + } + free(userData); //freeing the userData after registration + + userData = (void* )strdup("testJSONCallbackString"); + status = UT_ControlPlane_RegisterCallbackOnMessage(pInstance, "test/yamlData", &testYAMLCallback, userData); + UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_LIST_FULL); + free(userData); //freeing the userData after registration + + UT_ControlPlane_Exit(pInstance); + + UT_LOG("test_ut_control_l1_regsiter_on_message_Callback\n"); +} + +static void test_ut_control_l1_regsiter_endpoint_Callback() +{ + ut_controlPlane_instance_t *pInstance; + ut_control_plane_status_t status; + void* userData = (void* )strdup("testJSONCallbackStringInvalidParam"); + + UT_LOG("\ntest_ut_control_l1_regsiter_endpoint_Callback\n"); + + pInstance = UT_ControlPlane_Init(9000); + UT_ASSERT(pInstance != NULL); + + status = UT_ControlPlane_RegisterEndPointCallback(pInstance, NULL, &testGETJSONCallback, userData); + UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_INVALID_PARAM); + + status = UT_ControlPlane_RegisterEndPointCallback(pInstance, "/v1/callMyFunction2", NULL, userData); UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_INVALID_PARAM); - handler.restApiType = POST; - status = UT_ControlPlane_RegisterAPIEndpointHandler(NULL, "test/yamlData", &handler); + status = UT_ControlPlane_RegisterEndPointCallback(NULL, "/v1/callMyFunction2", &testGETJSONCallback, userData); UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_INVALID_HANDLE); - status = UT_ControlPlane_RegisterAPIEndpointHandler(pInstance, "ttest/yamlData", &handler); + status = UT_ControlPlane_RegisterEndPointCallback(pInstance, "/v1/callMyFunction2", &testGETJSONCallback, userData); UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_OK); free(userData); //freeing the userData after registration userData = (void* )strdup("testJSONCallbackString"); for (int i = 0; i< UT_CONTROL_PLANE_MAX_CALLBACK_ENTRIES - 1; i++ ) { - status = UT_ControlPlane_RegisterAPIEndpointHandler(pInstance, "test/yamlData", &handler); + status = UT_ControlPlane_RegisterEndPointCallback(pInstance, "/v1/callMyFunction2", &testGETJSONCallback, userData); UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_OK); } free(userData); //freeing the userData after registration userData = (void* )strdup("testJSONCallbackString"); - status = UT_ControlPlane_RegisterAPIEndpointHandler(pInstance, "test/yamlData", &handler); + status = UT_ControlPlane_RegisterEndPointCallback(pInstance, "/v1/callMyFunction2", &testGETJSONCallback, userData); UT_ASSERT_EQUAL(status, UT_CONTROL_PLANE_STATUS_LIST_FULL); free(userData); //freeing the userData after registration UT_ControlPlane_Exit(pInstance); - UT_LOG("test_ut_control_l1_regsiterCallback\n"); + UT_LOG("test_ut_control_l1_regsiter_endpoint_Callback\n"); } /* L2 Testing functions */ @@ -328,18 +354,11 @@ static void test_ut_control_performInit( void ) static void test_ut_control_performStart() { - ut_control_rest_api_handler_t handler = { - .callbackFunctionGET = &testGETJSONCallback, - .callbackFunctionPOST = &testYAMLCallback, - .userData = NULL, - .restApiType = INVALID - }; - UT_LOG("UT_ControlPlane_RegisterCallbackOnMessage() client testYAMLCallback - Negative\n"); - UT_ControlPlane_RegisterCallbackOnMessage(gInstance, "test/yamlData", &testYAMLCallback, NULL, POST); + UT_ControlPlane_RegisterCallbackOnMessage(gInstance, "test/yamlData", &testYAMLCallback, NULL); - UT_LOG("UT_ControlPlane_RegisterAPIEndpointHandler() client testGETJSONCallback - Negative\n"); - UT_ControlPlane_RegisterAPIEndpointHandler(gInstance, "/v1/callMyFunction2", &handler); + UT_LOG("UT_ControlPlane_RegisterEndPointCallback() client testGETJSONCallback - Negative\n"); + UT_ControlPlane_RegisterEndPointCallback(gInstance, "/v1/callMyFunction2", NULL, NULL); if (read_file_into_memory(UT_CONTROL_YAML_FILE, &gUserDataYaml) == 0) { @@ -348,24 +367,14 @@ static void test_ut_control_performStart() printf("Original Yaml file\n%s", (char*)gUserDataYaml.buffer); } - handler.restApiType = POST; - handler.userData = (void *)gUserDataYaml.buffer; - handler.callbackFunctionPOST = &testYAMLCallback; - handler.callbackFunctionGET = NULL; - - UT_LOG("UT_ControlPlane_RegisterAPIEndpointHandler() client testYAMLCallback - Positive\n"); - UT_ControlPlane_RegisterAPIEndpointHandler(gInstance, "test/yamlData", &handler); + UT_LOG("UT_ControlPlane_RegisterCallbackOnMessage() client testYAMLCallback - Positive\n"); + UT_ControlPlane_RegisterCallbackOnMessage(gInstance, "test/yamlData", &testYAMLCallback, &gUserDataYaml.buffer); } gMessageRecievedYAML = false; - handler.restApiType = GET; - handler.userData = NULL; - handler.callbackFunctionPOST = NULL; - handler.callbackFunctionGET = &testGETJSONCallback; - - UT_LOG("UT_ControlPlane_RegisterAPIEndpointHandler() client testGETJSONCallback - Positive \n"); - UT_ControlPlane_RegisterAPIEndpointHandler(gInstance, "/v1/callMyFunction2", &handler); + UT_LOG("UT_ControlPlane_RegisterEndPointCallback() client testGETJSONCallback - Positive \n"); + UT_ControlPlane_RegisterEndPointCallback(gInstance, "/v1/callMyFunction2", &testGETJSONCallback, NULL); UT_ControlPlane_Start(gInstance); @@ -377,24 +386,14 @@ static void test_ut_control_performStart() printf("Original Json file\n%s", (char*)gUserDataJson.buffer); } - handler.restApiType = POST; - handler.userData = (void *)gUserDataJson.buffer; - handler.callbackFunctionPOST = &testJSONCallback; - handler.callbackFunctionGET = NULL; - - UT_LOG("UT_ControlPlane_RegisterAPIEndpointHandler() client testJSONCallback - Positive \n"); - UT_ControlPlane_RegisterAPIEndpointHandler(gInstance, "test2/jsonData1", &handler); + UT_LOG("UT_ControlPlane_RegisterCallbackOnMessage() client testJSONCallback - Positive \n"); + UT_ControlPlane_RegisterCallbackOnMessage(gInstance, "test2/jsonData1", &testJSONCallback, &gUserDataJson.buffer); } gMessageRecievedJSON = false; - handler.restApiType = GET; - handler.userData = NULL; - handler.callbackFunctionPOST = NULL; - handler.callbackFunctionGET = &testGETYamlCallback; - - UT_LOG("UT_ControlPlane_RegisterAPIEndpointHandler() client testGETYamlCallback - Positive \n"); - UT_ControlPlane_RegisterAPIEndpointHandler(gInstance, "/v1/callMyFunction", &handler); + UT_LOG("UT_ControlPlane_RegisterEndPointCallback() client testGETYamlCallback - Positive \n"); + UT_ControlPlane_RegisterEndPointCallback(gInstance, "/v1/callMyFunction", &testGETYamlCallback, NULL); } void run_client_function() @@ -477,9 +476,13 @@ void register_cp_function() gpAssertSuite1 = UT_add_suite("L1 - ut_control function tests", NULL, NULL); assert(gpAssertSuite1 != NULL); UT_add_test(gpAssertSuite1, "ut-cp Init Exit", test_ut_control_l1_testInitExit); - UT_add_test(gpAssertSuite1, "ut-cp register callback", test_ut_control_l1_regsiterCallback); + UT_add_test(gpAssertSuite1, "ut-cp register on message callback", test_ut_control_l1_regsiter_on_message_Callback); UT_add_test(gpAssertSuite1, "ut-cp websocket service", test_ut_control_l1_testStartStop); + gpAssertSuite4 = UT_add_suite("L1 - ut_control function tests for end point cb", (UT_InitialiseFunction_t) test_ut_control_l1_testInitExit, (UT_CleanupFunction_t) test_ut_control_l1_testStartStop); + assert(gpAssertSuite4 != NULL); + UT_add_test(gpAssertSuite4, "ut-cp register end point callback", test_ut_control_l1_regsiter_endpoint_Callback); + /* L2 - ut_control Module tests */ gpAssertSuite2 = UT_add_suite("L2 - ut_control Module tests", NULL, NULL); assert(gpAssertSuite2 != NULL);