From b96ba3a80e367f938be4f2c5613245ba5e15ac31 Mon Sep 17 00:00:00 2001 From: David Robson Date: Wed, 12 Apr 2017 09:43:35 -0700 Subject: [PATCH] Code for performance test. Contains simulator module, metrics module, main application, and sample gateway.json files. --- core/tests/CMakeLists.txt | 2 + core/tests/performance_e2e/CMakeLists.txt | 91 ++++ core/tests/performance_e2e/README.md | 2 +- core/tests/performance_e2e/inc/metrics.h | 20 + core/tests/performance_e2e/inc/simulator.h | 30 ++ core/tests/performance_e2e/src/main.cpp | 44 ++ core/tests/performance_e2e/src/metrics.cpp | 270 ++++++++++++ .../performance_e2e/src/performance_lin.json | 33 ++ .../performance_e2e/src/performance_win.json | 33 ++ core/tests/performance_e2e/src/simulator.cpp | 408 ++++++++++++++++++ samples/performance/Overview.png | Bin 16660 -> 0 bytes samples/performance/Overview.vsdx | Bin 28962 -> 0 bytes samples/performance/default_sample.png | Bin 4902 -> 0 bytes samples/performance/default_sample.vsdx | Bin 28009 -> 0 bytes 14 files changed, 932 insertions(+), 1 deletion(-) create mode 100644 core/tests/performance_e2e/CMakeLists.txt create mode 100644 core/tests/performance_e2e/inc/metrics.h create mode 100644 core/tests/performance_e2e/inc/simulator.h create mode 100644 core/tests/performance_e2e/src/main.cpp create mode 100644 core/tests/performance_e2e/src/metrics.cpp create mode 100644 core/tests/performance_e2e/src/performance_lin.json create mode 100644 core/tests/performance_e2e/src/performance_win.json create mode 100644 core/tests/performance_e2e/src/simulator.cpp delete mode 100644 samples/performance/Overview.png delete mode 100644 samples/performance/Overview.vsdx delete mode 100644 samples/performance/default_sample.png delete mode 100644 samples/performance/default_sample.vsdx diff --git a/core/tests/CMakeLists.txt b/core/tests/CMakeLists.txt index 459e9ce1..0c0f95d8 100644 --- a/core/tests/CMakeLists.txt +++ b/core/tests/CMakeLists.txt @@ -12,6 +12,7 @@ add_subdirectory(gwmessage_ut) add_subdirectory(message_q_ut) add_subdirectory(dynamic_loader_ut) add_subdirectory(module_loader_ut) + if(${enable_java_binding}) add_subdirectory(java_loader_ut) endif() @@ -34,5 +35,6 @@ endif() if(${run_e2e_tests}) add_subdirectory(gateway_e2e) + add_subdirectory(performance_e2e) endif() diff --git a/core/tests/performance_e2e/CMakeLists.txt b/core/tests/performance_e2e/CMakeLists.txt new file mode 100644 index 00000000..00cc9a35 --- /dev/null +++ b/core/tests/performance_e2e/CMakeLists.txt @@ -0,0 +1,91 @@ +#Copyright (c) Microsoft. All rights reserved. +#Licensed under the MIT license. See LICENSE file in the project root for full license information. + +cmake_minimum_required(VERSION 2.8.12) + +include_directories(./inc) +include_directories(${GW_INC}) + +set(simulator_sources + ./src/simulator.cpp +) + +set(simulator_headers + ./inc/simulator.h +) + + +#this builds the simulator module +add_library(simulator MODULE ${simulator_sources} ${simulator_headers}) +target_link_libraries(simulator gateway) + +add_library(simulator_static STATIC ${simulator_sources} ${simulator_headers}) +target_compile_definitions(simulator_static PRIVATE BUILD_MODULE_TYPE_STATIC) +target_link_libraries(simulator_static gateway) + +linkSharedUtil(simulator) +linkSharedUtil(simulator_static) + +add_module_to_solution(simulator) + +if(install_modules) + install(TARGETS simulator LIBRARY DESTINATION "${LIB_INSTALL_DIR}/modules") +endif() + + +set(metrics_sources + ./src/metrics.cpp +) + +set(metrics_headers + ./inc/metrics.h +) + + +#this builds the metrics module +add_library(metrics MODULE ${metrics_sources} ${metrics_headers}) +target_link_libraries(metrics gateway) + +add_library(metrics_static STATIC ${metrics_sources} ${metrics_headers}) +target_compile_definitions(metrics_static PRIVATE BUILD_MODULE_TYPE_STATIC) +target_link_libraries(metrics_static gateway) + +linkSharedUtil(metrics) +linkSharedUtil(metrics_static) + +add_module_to_solution(metrics) + +if(install_modules) + install(TARGETS metrics LIBRARY DESTINATION "${LIB_INSTALL_DIR}/modules") +endif() + + +set(performance_e2e_sources + ./src/main.cpp +) +if(WIN32) + set(performance_e2e_sources + ${performance_e2e_sources} + ./src/performance_win.json + ) + set_source_files_properties(./src/performance_win.json PROPERTIES HEADER_FILE_ONLY ON) +else() + set(performance_e2e_sources + ${performance_e2e_sources} + ./src/performance_lin.json + ) + set_source_files_properties(./src/performance_lin.json PROPERTIES HEADER_FILE_ONLY ON) +endif() + +add_executable(performance_e2e ${performance_e2e_sources}) + +add_dependencies(performance_e2e simulator metrics) + +target_link_libraries(performance_e2e gateway nanomsg) +linkSharedUtil(performance_e2e) +install_broker(performance_e2e ${CMAKE_CURRENT_BINARY_DIR}/$(Configuration) ) +copy_gateway_dll(performance_e2e ${CMAKE_CURRENT_BINARY_DIR}/$(Configuration) ) + +set_target_properties(performance_e2e + PROPERTIES + FOLDER "tests/E2ETests") diff --git a/core/tests/performance_e2e/README.md b/core/tests/performance_e2e/README.md index 65f64e76..7bba5af2 100644 --- a/core/tests/performance_e2e/README.md +++ b/core/tests/performance_e2e/README.md @@ -291,7 +291,7 @@ The information the metrics module produces is: | Maximum latency | Time (microseconds) | Maximum message latency | | Devices Discovered | Count | Number of deviceId names received in message. | -The metrics module also produces this information for each deviceId recognized: +The metrics module also produces this information for each deviceId recognized. | Metric | Measure | Description | | ------------------------ | ------------------- | ----------- | diff --git a/core/tests/performance_e2e/inc/metrics.h b/core/tests/performance_e2e/inc/metrics.h new file mode 100644 index 00000000..32015bab --- /dev/null +++ b/core/tests/performance_e2e/inc/metrics.h @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#ifndef METRICS_H +#define METRICS_H + +#include "module.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +MODULE_EXPORT const MODULE_API* MODULE_STATIC_GETAPI(METRICS_MODULE)(MODULE_API_VERSION gateway_api_version); + +#ifdef __cplusplus +} +#endif + +#endif /*METRICS_H*/ diff --git a/core/tests/performance_e2e/inc/simulator.h b/core/tests/performance_e2e/inc/simulator.h new file mode 100644 index 00000000..c4497967 --- /dev/null +++ b/core/tests/performance_e2e/inc/simulator.h @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#ifndef SIMULATOR_H +#define SIMULATOR_H + +#include "module.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct SIMULATOR_MODULE_CONFIG_TAG +{ + char * device_id; + size_t message_delay; + size_t properties_count; + size_t properties_size; + size_t message_size; +} SIMULATOR_MODULE_CONFIG; + + +MODULE_EXPORT const MODULE_API* MODULE_STATIC_GETAPI(SIMULATOR_MODULE)(MODULE_API_VERSION gateway_api_version); + +#ifdef __cplusplus +} +#endif + +#endif /*SIMULATOR_H*/ diff --git a/core/tests/performance_e2e/src/main.cpp b/core/tests/performance_e2e/src/main.cpp new file mode 100644 index 00000000..3342ae71 --- /dev/null +++ b/core/tests/performance_e2e/src/main.cpp @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#include +#include + +#include "gateway.h" +#include "azure_c_shared_utility/threadapi.h" +#include + +int main(int argc, char** argv) +{ + int sleep_in_ms = 5000; + GATEWAY_HANDLE gateway; + if (argc != 2 && argc != 3) + { + std::cout + << "usage: performance_sample configFile [duration]" << std::endl + << "where configFile is the name of the file that contains the gateway configuration" << std::endl + << "where duration is the length of time in seconds for the test to run" << std::endl; + } + else + { + if (argc==3) + { + sleep_in_ms = std::stoi(argv[2]) * 1000; + } + + if ((gateway = Gateway_CreateFromJson(argv[1])) == NULL) + { + std::cout << "failed to create the gateway from JSON" << std::endl; + } + else + { + + std::cout << "gateway successfully created from JSON" << std::endl; + std::cout << "gateway shall run for " << sleep_in_ms/1000 << " seconds" << std::endl; + ThreadAPI_Sleep(sleep_in_ms); + + Gateway_Destroy(gateway); + } + } + return 0; +} diff --git a/core/tests/performance_e2e/src/metrics.cpp b/core/tests/performance_e2e/src/metrics.cpp new file mode 100644 index 00000000..359244b1 --- /dev/null +++ b/core/tests/performance_e2e/src/metrics.cpp @@ -0,0 +1,270 @@ + +#include +#include +#include +#include +#include + +#include + +#include "azure_c_shared_utility/gballoc.h" +#include "azure_c_shared_utility/xlogging.h" +#include "azure_c_shared_utility/threadapi.h" +#include "azure_c_shared_utility/map.h" +#include "message.h" +#include "module.h" + +#include "simulator.h" + +using HrClock = std::chrono::high_resolution_clock; +using MicroSeconds = std::chrono::microseconds; +using HrTime = std::chrono::time_point; +using Counter = long long; + +template +struct SimpleAccumulator +{ + typedef ValueT result_type; + + ValueT accumulation; + ValueT max; + Counter accumulation_count; + + SimpleAccumulator() : accumulation(0), max(0), accumulation_count(0) + { + } + + result_type getSum() + { + return this->accumulation; + } + Counter getCount() + { + return this->accumulation_count; + } + result_type getMean() + { + ValueT mean(0); + if (accumulation_count != 0) + { + mean = accumulation / accumulation_count; + } + return mean; + } + void add(ValueT v) + { + this->accumulation += v; + this->accumulation_count++; + if (v > max) + { + max = v; + } + } +}; + +struct METRICS_PER_DEVICE +{ + Counter messages_received; + Counter seqence_number; + Counter out_of_sequence_messages; + Counter messages_lost; + METRICS_PER_DEVICE() : messages_received(0), seqence_number(0), out_of_sequence_messages(0), messages_lost(0) + { + } +} ; + +using PerDeviceMap = std::map; + +typedef struct METRICS_MODULE_HANDLE_TAG +{ + BROKER_HANDLE broker; + bool started; + HrTime start_time; + Counter all_messages_received; + Counter non_conforming_messages; + SimpleAccumulator latency; + PerDeviceMap *per_device_metrics; +} METRICS_MODULE_HANDLE; + + +static void* MetricsModule_ParseConfigurationFromJson(const char* configuration) +{ + (void)configuration; + return NULL; +} + +static void MetricsModule_FreeConfiguration(void* configuration) +{ + (void)configuration; +} + +static MODULE_HANDLE MetricsModule_Create(BROKER_HANDLE broker, const void* configuration) +{ + METRICS_MODULE_HANDLE * module; + + if (broker == NULL) + { + LogError(" had a null input. broker: [%p], configuration: [%p]", broker, configuration); + module = NULL; + } + else + { + module = (METRICS_MODULE_HANDLE*)malloc(sizeof(METRICS_MODULE_HANDLE)); + if (module == NULL) + { + LogError("Could not allocate memory for module handle"); + } + else + { + HrTime init_time; + Counter init_count(0); + SimpleAccumulator init_accumulator; + + module->broker = broker; + module->started = false; + module->start_time = init_time; + module->all_messages_received = init_count; + module->non_conforming_messages = init_count; + module->latency = init_accumulator; + module->per_device_metrics = new PerDeviceMap(); + } + } + return (MODULE_HANDLE)module; +} + +static void MetricsModule_Start(MODULE_HANDLE moduleHandle) +{ + if (moduleHandle != NULL) + { + METRICS_MODULE_HANDLE * module = (METRICS_MODULE_HANDLE *)moduleHandle; + module->start_time = std::chrono::time_point_cast(HrClock::now()); + module->started = true; + } +} + +static void MetricsModule_Receive(MODULE_HANDLE moduleHandle, MESSAGE_HANDLE messageHandle) +{ + if (moduleHandle != NULL && messageHandle != NULL) + { + HrTime received_time = std::chrono::time_point_cast(HrClock::now()); + METRICS_MODULE_HANDLE * module = (METRICS_MODULE_HANDLE *)moduleHandle; + module->all_messages_received++; + + CONSTMAP_HANDLE message_properties = Message_GetProperties(messageHandle); + if (message_properties == NULL) + { + module->non_conforming_messages++; + } + else + { + const char * timestamp_property = ConstMap_GetValue(message_properties, "timestamp"); + const char * seq_num_property = ConstMap_GetValue(message_properties, "sequence number"); + const char * deviceId_property = ConstMap_GetValue(message_properties, "deviceId"); + if ((timestamp_property == NULL) || (seq_num_property == NULL) || (deviceId_property == NULL)) + { + module->non_conforming_messages++; + } + else + { + try + { + MicroSeconds timestamp_duration(std::stoll(timestamp_property)); + HrTime timestamp(timestamp_duration); + MicroSeconds current_latency = received_time - timestamp; + module->latency.add(current_latency); + + if (deviceId_property == NULL) + { + module->non_conforming_messages++; + } + else + { + std::string deviceId(deviceId_property); + METRICS_PER_DEVICE& per_device = (*module->per_device_metrics)[deviceId]; + per_device.messages_received++; + per_device.seqence_number++; + + Counter sequence_number(std::stoll(seq_num_property)); + if (sequence_number != per_device.seqence_number) + { + per_device.out_of_sequence_messages++; + if (sequence_number > per_device.seqence_number) + { + per_device.messages_lost += (sequence_number - per_device.seqence_number); + } + per_device.seqence_number = sequence_number; + } + } + } + catch (std::exception & e) + { + LogError("non-conforming message: exception caught: %s", e.what()); + module->non_conforming_messages++; + } + } + + ConstMap_Destroy(message_properties); + } + } +} + +static void MetricsModule_Destroy(MODULE_HANDLE moduleHandle) +{ + if (moduleHandle == NULL) + { + LogError("Destroying a NULL module"); + } + else + { + METRICS_MODULE_HANDLE * module = (METRICS_MODULE_HANDLE *)moduleHandle; + if (module->started) + { + HrTime destroy_time = std::chrono::time_point_cast(HrClock::now()); + MicroSeconds duration = destroy_time - module->start_time; + std::cout + << "Module Metrics:" << std::endl + << "---------------" << std::endl + << "Duration (ms): " << duration.count() / 1000 << std::endl + << "Messages received: " << module->all_messages_received << std::endl + << "Non-Conforming Messages: " << module->non_conforming_messages << std::endl + << "Message Latency (average microseconds): " << module->latency.getMean().count() << std::endl + << "Message Latency (max microseconds): " << module->latency.max.count() << std::endl + << "Devices Discovered: " << module->per_device_metrics->size() << std::endl; + for (PerDeviceMap::iterator d = module->per_device_metrics->begin(); + d != module->per_device_metrics->end(); + d++) + { + std::cout + << "Device: " << (*d).first << std::endl + << "Message count: " << (*d).second.messages_received << std::endl + << "Out of Sequence Count: " << (*d).second.out_of_sequence_messages << std::endl + << "Messages Lost: " << (*d).second.messages_lost << std::endl; + } + } + free(module); + } +} + + + +static const MODULE_API_1 METRICS_APIS_all = +{ + {MODULE_API_VERSION_1}, + + MetricsModule_ParseConfigurationFromJson, + MetricsModule_FreeConfiguration, + MetricsModule_Create, + MetricsModule_Destroy, + MetricsModule_Receive, + MetricsModule_Start +}; + +#ifdef BUILD_MODULE_TYPE_STATIC +MODULE_EXPORT const MODULE_API* MODULE_STATIC_GETAPI(METRICS_MODULE)(MODULE_API_VERSION gateway_api_version) +#else +MODULE_EXPORT const MODULE_API* Module_GetApi(MODULE_API_VERSION gateway_api_version) +#endif +{ + (void)gateway_api_version; + return reinterpret_cast< const MODULE_API *>(&METRICS_APIS_all); +} diff --git a/core/tests/performance_e2e/src/performance_lin.json b/core/tests/performance_e2e/src/performance_lin.json new file mode 100644 index 00000000..3f267d4f --- /dev/null +++ b/core/tests/performance_e2e/src/performance_lin.json @@ -0,0 +1,33 @@ +{ + "modules": [ + { + "name": "metrics1", + "loader": { + "name": "native", + "entrypoint": { + "module.path": "libmetrics.so" + } + }, + "args": null + }, + { + "name": "simulator1", + "loader": { + "name": "native", + "entrypoint": { + "module.path": "libsimulator.so" + } + }, + "args": { + "deviceId": "device1", + "message.delay": 0 + } + } + ], + "links": [ + { + "source": "simulator1", + "sink": "metrics1" + } + ] +} diff --git a/core/tests/performance_e2e/src/performance_win.json b/core/tests/performance_e2e/src/performance_win.json new file mode 100644 index 00000000..2412451e --- /dev/null +++ b/core/tests/performance_e2e/src/performance_win.json @@ -0,0 +1,33 @@ +{ + "modules": [ + { + "name": "metrics1", + "loader": { + "name": "native", + "entrypoint": { + "module.path": "Debug\\metrics.dll" + } + }, + "args": null + }, + { + "name": "simulator1", + "loader": { + "name": "native", + "entrypoint": { + "module.path": "Debug\\simulator.dll" + } + }, + "args": { + "deviceId": "device1", + "message.delay": 0 + } + } + ], + "links": [ + { + "source": "simulator1", + "sink": "metrics1" + } + ] +} diff --git a/core/tests/performance_e2e/src/simulator.cpp b/core/tests/performance_e2e/src/simulator.cpp new file mode 100644 index 00000000..763a7e60 --- /dev/null +++ b/core/tests/performance_e2e/src/simulator.cpp @@ -0,0 +1,408 @@ + +#include +#include +#include +#include +#include +#include + +#include + +#include "azure_c_shared_utility/gballoc.h" +#include "azure_c_shared_utility/xlogging.h" +#include "azure_c_shared_utility/threadapi.h" +#include "azure_c_shared_utility/map.h" +#include "message.h" +#include "module.h" + +#include "simulator.h" + + +typedef struct SIMULATOR_MODULE_HANDLE_TAG +{ + BROKER_HANDLE broker; + char * device_id; + size_t message_delay; + size_t properties_count; + size_t properties_size; + size_t message_size; + char * psuedo_random_buffer; + bool thread_flag; + THREAD_HANDLE main_thread; +} SIMULATOR_MODULE_HANDLE; + + +static void* SimulatorModule_ParseConfigurationFromJson(const char* configuration) +{ + SIMULATOR_MODULE_CONFIG * result; + if (configuration == NULL) + { + LogError("Simulator module expects configuration"); + result = NULL; + } + else + { + JSON_Value* json = json_parse_string((const char*)configuration); + if (json == NULL) + { + LogError("unable to json_parse_string"); + result = NULL; + } + else + { + JSON_Object* obj = json_value_get_object(json); + if (obj == NULL) + { + LogError("unable to json_value_get_object"); + result = NULL; + } + else + { + const char* deviceIdValue = json_object_get_string(obj, "deviceId"); + if (deviceIdValue == NULL) + { + LogError("deviceId is a required field in configuration"); + result = NULL; + } + else + { + result = (SIMULATOR_MODULE_CONFIG *)malloc(sizeof(SIMULATOR_MODULE_CONFIG)); + if (result == NULL) + { + LogError("Could not allocated Module data"); + } + else + { + if (mallocAndStrcpy_s(&(result->device_id), deviceIdValue) != 0) + { + LogError("could not allocate memory for deviceID string"); + free(result); + result = NULL; + } + else + { + result->message_delay = 0; + result->message_size = 256; + result->properties_count = 2; + result->properties_size = 16; + + if (json_object_has_value_of_type(obj, "message.delay", JSONNumber)) + { + result->message_delay = static_cast(json_object_get_number(obj, "message.delay")); + } + double message_size_value = json_object_get_number(obj, "message.size"); + if (message_size_value > 0) + { + result->message_size = static_cast(message_size_value); + } + double properties_count_value = json_object_get_number(obj, "properties.count"); + if (properties_count_value > 0) + { + result->properties_count = static_cast(properties_count_value); + } + double properties_size_value = json_object_get_number(obj, "properties.size"); + if (properties_size_value > 0) + { + result->properties_size = static_cast(properties_size_value); + } + } + } + } + } + json_value_free(json); + } + } + return result; +} + +static void SimulatorModule_FreeConfiguration(void* configuration) +{ + if (configuration != NULL) + { + SIMULATOR_MODULE_CONFIG * conf = (SIMULATOR_MODULE_CONFIG*)configuration; + free(conf->device_id); + free(conf); + } +} + +static MODULE_HANDLE SimulatorModule_Create(BROKER_HANDLE broker, const void* configuration) +{ + SIMULATOR_MODULE_HANDLE * module; + + if ((broker == NULL) || + (configuration == NULL)) + { + LogError("Simulator had a null input. broker: [%p], configuration: [%p]", broker, configuration); + module = NULL; + } + else + { + SIMULATOR_MODULE_CONFIG * conf = (SIMULATOR_MODULE_CONFIG *)configuration; + module = (SIMULATOR_MODULE_HANDLE*)malloc(sizeof(SIMULATOR_MODULE_HANDLE)); + if (module == NULL) + { + LogError("Could not allocate memory for module handle"); + } + else + { + if (mallocAndStrcpy_s(&(module->device_id), conf->device_id) != 0) + { + LogError("could not allocate memory for deviceID string"); + free(module); + module = NULL; + } + else + { + module->broker = broker; + module->message_delay = conf->message_delay; + module->message_size = conf->message_size; + module->properties_count = conf->properties_count; + module->properties_size = conf->properties_size; + size_t max_buffer = std::max(module->properties_size, module->message_size); + module->psuedo_random_buffer = (char*)malloc(max_buffer + 1); + if (module->psuedo_random_buffer == NULL) + { + LogError("could not allocate memory for deviceID string"); + free(module->device_id); + free(module); + module = NULL; + } + else + { + std::default_random_engine generator; + std::uniform_int_distribution distribution(' ', 'z'); + for (size_t i = 0; i < max_buffer; i++) + { + (module->psuedo_random_buffer)[i] = distribution(generator); + } + (module->psuedo_random_buffer)[max_buffer] = '\0'; + } + } + } + } + return (MODULE_HANDLE)module; +} + +static int SimulatorModule_create_message(SIMULATOR_MODULE_HANDLE * module, MESSAGE_CONFIG* message) +{ + int thread_result; + MAP_HANDLE property_map = Map_Create(NULL); + if (property_map == NULL) + { + LogError("Allocation of properties map failed."); + thread_result = -__LINE__; + } + else + { + std::string property_string(module->psuedo_random_buffer, module->properties_size); + std::string property_count_string = std::to_string(module->properties_count); + + if (property_string.empty() || property_count_string.empty()) + { + LogError("Allocation of properties string failed."); + Map_Destroy(property_map); + thread_result = -__LINE__; + } + else + { + if (Map_Add(property_map, "deviceId", module->device_id) != MAP_OK) + { + Map_Destroy(property_map); + thread_result = -__LINE__; + } + else if (Map_Add(property_map, "property count", property_count_string.c_str()) != MAP_OK) + { + Map_Destroy(property_map); + thread_result = -__LINE__; + } + else + { + thread_result = 0; + for (size_t p = 0; p < module->properties_count; p++) + { + std::ostringstream property_n; + property_n << "property" << p; + if (Map_Add(property_map, property_n.str().c_str(), property_string.c_str())) + { + thread_result = -__LINE__; + break; + } + } + if (thread_result != 0) + { + Map_Destroy(property_map); + thread_result = -__LINE__; + } + else + { + message->source = (const unsigned char*)malloc(module->message_size); + if (message->source == NULL) + { + LogError("unable to allocate message buffer"); + Map_Destroy(property_map); + thread_result = -__LINE__; + } + else + { + message->sourceProperties = property_map; + message->size = module->message_size; + if (module->message_size == 0) + { + message->source = NULL; + } + else + { + memcpy((void*)message->source, module->psuedo_random_buffer, message->size - 1); + ((char*)(message->source))[message->size - 1] = '\0'; + } + thread_result = 0; + } + + } + } + } + } + return thread_result; +} + +static int SimulatorModule_thread(void * context) +{ + int thread_result; + SIMULATOR_MODULE_HANDLE * module = (SIMULATOR_MODULE_HANDLE *)context; + MESSAGE_CONFIG message_to_send; + + thread_result = SimulatorModule_create_message(module, &message_to_send); + if (thread_result != 0) + { + LogError("unable to continue with simulation"); + } + else + { + using HrClock = std::chrono::high_resolution_clock; + using MicroSeconds = std::chrono::microseconds; + long long time_to_wait = module->message_delay * 1000; + + size_t messages_produced = 0; + thread_result = 0; + while (module->thread_flag) + { + std::chrono::time_point t1 = std::chrono::time_point_cast(HrClock::now()); + auto t1_as_int = t1.time_since_epoch().count(); + std::string t1_as_string = std::to_string(t1_as_int); + messages_produced++; + std::string messages_produced_as_string = std::to_string(messages_produced); + if (Map_AddOrUpdate(message_to_send.sourceProperties, "timestamp", t1_as_string.c_str()) != MAP_OK) + { + LogError("Unable to update timestamp in message"); + module->thread_flag = false; + thread_result = -__LINE__; + break; + } + else if (Map_AddOrUpdate(message_to_send.sourceProperties, "sequence number", messages_produced_as_string.c_str()) != MAP_OK) + { + LogError("Unable to update sequence number in message"); + module->thread_flag = false; + thread_result = -__LINE__; + break; + } + else + { + MESSAGE_HANDLE next_message = Message_Create(&message_to_send); + if (next_message == NULL) + { + LogError("Unable to create next message"); + module->thread_flag = false; + thread_result = -__LINE__; + break; + } + else + { + if (Broker_Publish(module->broker, module, next_message) != BROKER_OK) + { + LogError("Unable to publish message"); + module->thread_flag = false; + thread_result = -__LINE__; + break; + } + else + { + Message_Destroy(next_message); + std::chrono::time_point t2 = std::chrono::time_point_cast(HrClock::now()); + auto time_to_publish = t2.time_since_epoch().count() - t1_as_int; + if (time_to_publish < time_to_wait) + { + unsigned int remaining_time = static_cast((time_to_wait - time_to_publish)/1000); + ThreadAPI_Sleep(remaining_time); + } + } + } + } + } + } + return thread_result; +} + +static void SimulatorModule_Start(MODULE_HANDLE moduleHandle) +{ + if (moduleHandle != NULL) + { + SIMULATOR_MODULE_HANDLE * module = (SIMULATOR_MODULE_HANDLE *)moduleHandle; + + module->thread_flag = true; + if (ThreadAPI_Create(&(module->main_thread), SimulatorModule_thread, module) != 0) + { + LogError("Thread Creation failed"); + module->main_thread = NULL; + } + } +} + +static void SimulatorModule_Destroy(MODULE_HANDLE moduleHandle) +{ + if (moduleHandle == NULL) + { + LogError("Destroying a NULL module"); + } + else + { + SIMULATOR_MODULE_HANDLE * module = (SIMULATOR_MODULE_HANDLE *)moduleHandle; + module->thread_flag = false; + int thread_result; + (void)ThreadAPI_Join(module->main_thread, &thread_result); + if (thread_result != 0) + { + LogInfo("Thread ended with non-zero result: %d", thread_result); + } + free(module->device_id); + free(module->psuedo_random_buffer); + free(module); + } +} + +static void SimulatorModule_Receive(MODULE_HANDLE moduleHandle, MESSAGE_HANDLE messageHandle) +{ + (void)moduleHandle; + (void)messageHandle; +} + +static const MODULE_API_1 SIMULATOR_APIS_all = +{ + {MODULE_API_VERSION_1}, + + SimulatorModule_ParseConfigurationFromJson, + SimulatorModule_FreeConfiguration, + SimulatorModule_Create, + SimulatorModule_Destroy, + SimulatorModule_Receive, + SimulatorModule_Start +}; + +#ifdef BUILD_MODULE_TYPE_STATIC +MODULE_EXPORT const MODULE_API* MODULE_STATIC_GETAPI(SIMULATOR_MODULE)(MODULE_API_VERSION gateway_api_version) +#else +MODULE_EXPORT const MODULE_API* Module_GetApi(MODULE_API_VERSION gateway_api_version) +#endif +{ + (void)gateway_api_version; + return reinterpret_cast< const MODULE_API *>(&SIMULATOR_APIS_all); +} diff --git a/samples/performance/Overview.png b/samples/performance/Overview.png deleted file mode 100644 index 54f53e9da742c337346fa30c73c0b6c68daedf73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16660 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 MnHSO}Qbzv&4VR>0761SM diff --git a/samples/performance/Overview.vsdx b/samples/performance/Overview.vsdx deleted file mode 100644 index 239d2eb41b930f1e5e6c41bb4d817f8cc7bdcb1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28962 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 BeY^kw