From 7a300fba34da7b930cd81005c45fbcd5daac9842 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Fri, 21 Oct 2022 11:02:39 -0700 Subject: [PATCH] C api aliases (#2454) * add C api for addAlias * add test cases for C alias methods * add alias operations to C++98 API * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Apply suggestions from code review Co-authored-by: Ryan Mast <3969255+nightlark@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ryan Mast <3969255+nightlark@users.noreply.github.com> --- src/helics/application_api/Federate.hpp | 5 +- src/helics/cpp98/Broker.hpp | 8 ++ src/helics/cpp98/Core.hpp | 9 ++ src/helics/cpp98/Federate.hpp | 9 ++ .../shared_api_library/FederateExport.cpp | 27 ++++++ .../shared_api_library/backup/helics/helics.h | 45 ++++++++-- .../backup/helics/helics_api.h | 3 + src/helics/shared_api_library/helicsCore.h | 33 ++++++++ .../shared_api_library/helicsExport.cpp | 51 ++++++++++++ .../shared_library/test-value-federate2.cpp | 83 +++++++++++++++++++ 10 files changed, 266 insertions(+), 7 deletions(-) diff --git a/src/helics/application_api/Federate.hpp b/src/helics/application_api/Federate.hpp index 0e7fd3813a..9f0222c5ed 100644 --- a/src/helics/application_api/Federate.hpp +++ b/src/helics/application_api/Federate.hpp @@ -518,7 +518,10 @@ class HELICS_CXX_EXPORT Federate { @param value the value of the global */ void setGlobal(std::string_view valueName, std::string_view value); - /** add a global alias for an interface */ + /** add a global alias for an interface + @param interfaceName the given name of the interface + @param alias the new name by which the interface can be referenced + */ void addAlias(std::string_view interfaceName, std::string_view alias); /** send a command to another core or federate @param target the target of the command can be "federation", "federate", "broker", "core", or a diff --git a/src/helics/cpp98/Broker.hpp b/src/helics/cpp98/Broker.hpp index 6efee49278..b9dac8f9cf 100644 --- a/src/helics/cpp98/Broker.hpp +++ b/src/helics/cpp98/Broker.hpp @@ -126,6 +126,14 @@ class Broker { { helicsBrokerSetGlobal(broker, valueName.c_str(), value.c_str(), hThrowOnError()); } + /** add a global alias for an interface + @param interfaceName the given name of the interface + @param alias the new name by which the interface can be referenced + */ + void addAlias(const std::string& interfaceName, const std::string& alias) + { + helicsBrokerAddAlias(broker, interfaceName.c_str(), alias.c_str(), hThrowOnError()); + } /** create a data link between a named publication and a named input @param source the name of the publication @param target the name of the input*/ diff --git a/src/helics/cpp98/Core.hpp b/src/helics/cpp98/Core.hpp index 42985ac963..9ca7084907 100644 --- a/src/helics/cpp98/Core.hpp +++ b/src/helics/cpp98/Core.hpp @@ -131,6 +131,15 @@ class Core { helicsCoreSetGlobal(core, valueName.c_str(), value.c_str(), hThrowOnError()); } + /** add a global alias for an interface + @param interfaceName the given name of the interface + @param alias the new name by which the interface can be referenced + */ + void addAlias(const std::string& interfaceName, const std::string& alias) + { + helicsCoreAddAlias(core, interfaceName.c_str(), alias.c_str(), hThrowOnError()); + } + void globalError(int errorCode, const std::string& errorString) { helicsCoreGlobalError(core, errorCode, errorString.c_str(), HELICS_IGNORE_ERROR); diff --git a/src/helics/cpp98/Federate.hpp b/src/helics/cpp98/Federate.hpp index b9ccf05380..307a0ab4c1 100644 --- a/src/helics/cpp98/Federate.hpp +++ b/src/helics/cpp98/Federate.hpp @@ -865,6 +865,15 @@ class Federate { helicsFederateSetGlobal(fed, valueName.c_str(), value.c_str(), hThrowOnError()); } + /** add a global alias for an interface + @param interfaceName the given name of the interface + @param alias the new name by which the interface can be referenced + */ + void addAlias(const std::string& interfaceName, const std::string& alias) + { + helicsFederateAddAlias(fed, interfaceName.c_str(), alias.c_str(), hThrowOnError()); + } + /** set a tag (key-value pair) for a federate @details the tag is an arbitrary user defined string and value; the tags for a federate are queryable through a "tags" query or "tag/" diff --git a/src/helics/shared_api_library/FederateExport.cpp b/src/helics/shared_api_library/FederateExport.cpp index b1748f9307..773e4280fa 100644 --- a/src/helics/shared_api_library/FederateExport.cpp +++ b/src/helics/shared_api_library/FederateExport.cpp @@ -1646,6 +1646,33 @@ void helicsFederateSetGlobal(HelicsFederate fed, const char* valueName, const ch // LCOV_EXCL_STOP } +static constexpr char invalidInterfaceName[] = "Interface name cannot be empty"; +static constexpr char invalidAliasName[] = "Alias cannot be empty"; + +void helicsFederateAddAlias(HelicsFederate fed, const char* interfaceName, const char* alias, HelicsError* err) +{ + auto* fedObj = getFed(fed, err); + if (fedObj == nullptr) { + return; + } + if (interfaceName == nullptr || strlen(interfaceName) == 0) { + assignError(err, HELICS_ERROR_INVALID_ARGUMENT, invalidInterfaceName); + return; + } + if (alias == nullptr || strlen(alias) == 0) { + assignError(err, HELICS_ERROR_INVALID_ARGUMENT, invalidAliasName); + return; + } + try { + fedObj->addAlias(interfaceName, alias); + } + // LCOV_EXCL_START + catch (...) { + helicsErrorHandler(err); + } + // LCOV_EXCL_STOP +} + static constexpr char invalidTagString[] = "Tag name cannot be null"; void helicsFederateSetTag(HelicsFederate fed, const char* tagName, const char* value, HelicsError* err) { diff --git a/src/helics/shared_api_library/backup/helics/helics.h b/src/helics/shared_api_library/backup/helics/helics.h index f519e43a18..61b6669510 100644 --- a/src/helics/shared_api_library/backup/helics/helics.h +++ b/src/helics/shared_api_library/backup/helics/helics.h @@ -1733,10 +1733,10 @@ HELICS_EXPORT void helicsFederateEnterInitializingModeAsync(HelicsFederate fed, HELICS_EXPORT void helicsFederateEnterInitializingModeComplete(HelicsFederate fed, HelicsError* err); /** - * Trigger a blocking call and return to created state after all federates have either triggered an iteration or waiting to enter - * initializing mode + * Trigger a blocking call and return to created state after all federates have either triggered an iteration or are waiting to enter + * initializing mode. * - * @details this call will return the federate to the created state to allow additional setup to occur with federates either iterating in + * @details This call will return the federate to the created state to allow additional setup to occur with federates either iterating in * the mode or waiting. * * @param fed The federate to operate on. @@ -1757,10 +1757,10 @@ HELICS_EXPORT void helicsFederateEnterInitializingModeIterative(HelicsFederate f HELICS_EXPORT void helicsFederateEnterInitializingModeIterativeAsync(HelicsFederate fed, HelicsError* err); /** - * Complete the call to initialize mode that was initiated with /ref heliceEnterInitializingModeIterativeAsync. The federate will be in - * startup or error mode on return + * Complete the call to enter initializing mode Iterative that was initiated with /ref heliceEnterInitializingModeIterativeAsync. The + * federate will be in created or error mode on return * - * @param fed The federate desiring to iterate to the startup mode again + * @param fed The federate used in the corresponding async call * * @param[in,out] err An error object that will contain an error code and string if any error occurred during the execution of the function. */ @@ -2097,6 +2097,17 @@ HELICS_EXPORT int helicsFederateGetIntegerProperty(HelicsFederate fed, int intPr */ HELICS_EXPORT HelicsTime helicsFederateGetCurrentTime(HelicsFederate fed, HelicsError* err); +/** + * create an alias for an interface + * + * @param fed The federate to use to set the alias + * @param interfaceName The current name of an interface + * @param alias the additional name to use for the given interface + * + * @param[in,out] err A pointer to an error object for catching errors. + */ +HELICS_EXPORT void helicsFederateAddAlias(HelicsFederate fed, const char* interfaceName, const char* alias, HelicsError* err); + /** * Set a federation global value through a federate. * @@ -2271,6 +2282,28 @@ HELICS_EXPORT void helicsCoreSetGlobal(HelicsCore core, const char* valueName, c */ HELICS_EXPORT void helicsBrokerSetGlobal(HelicsBroker broker, const char* valueName, const char* value, HelicsError* err); +/** + * create an alias for an interface + * + * @param core The core to use to set the alias + * @param interfaceName The current name of an interface + * @param alias the additional name to use for the given interface + * + * @param[in,out] err A pointer to an error object for catching errors. + */ +HELICS_EXPORT void helicsCoreAddAlias(HelicsCore core, const char* interfaceName, const char* alias, HelicsError* err); + +/** + * create an alias for an interface + * + * @param broker The broker to use to set the alias + * @param interfaceName The current name of an interface + * @param alias the additional name to use for the given interface + * + * @param[in,out] err A pointer to an error object for catching errors. + */ +HELICS_EXPORT void helicsBrokerAddAlias(HelicsBroker broker, const char* interfaceName, const char* alias, HelicsError* err); + /** * Send a command to another helics object though a core using asynchronous(fast) operations. * diff --git a/src/helics/shared_api_library/backup/helics/helics_api.h b/src/helics/shared_api_library/backup/helics/helics_api.h index 563ae7a6df..f47107200a 100644 --- a/src/helics/shared_api_library/backup/helics/helics_api.h +++ b/src/helics/shared_api_library/backup/helics/helics_api.h @@ -459,6 +459,7 @@ HelicsTime helicsFederateGetTimeProperty(HelicsFederate fed, int timeProperty, H HelicsBool helicsFederateGetFlagOption(HelicsFederate fed, int flag, HelicsError* err); int helicsFederateGetIntegerProperty(HelicsFederate fed, int intProperty, HelicsError* err); HelicsTime helicsFederateGetCurrentTime(HelicsFederate fed, HelicsError* err); +void helicsFederateAddAlias(HelicsFederate fed, const char* interfaceName, const char* alias, HelicsError* err); void helicsFederateSetGlobal(HelicsFederate fed, const char* valueName, const char* value, HelicsError* err); void helicsFederateSetTag(HelicsFederate fed, const char* tagName, const char* value, HelicsError* err); const char* helicsFederateGetTag(HelicsFederate fed, const char* tagName, HelicsError* err); @@ -475,6 +476,8 @@ const char* helicsFederateGetCommandSource(HelicsFederate fed, HelicsError* err) const char* helicsFederateWaitCommand(HelicsFederate fed, HelicsError* err); void helicsCoreSetGlobal(HelicsCore core, const char* valueName, const char* value, HelicsError* err); void helicsBrokerSetGlobal(HelicsBroker broker, const char* valueName, const char* value, HelicsError* err); +void helicsCoreAddAlias(HelicsCore core, const char* interfaceName, const char* alias, HelicsError* err); +void helicsBrokerAddAlias(HelicsBroker broker, const char* interfaceName, const char* alias, HelicsError* err); void helicsCoreSendCommand(HelicsCore core, const char* target, const char* command, HelicsError* err); void helicsCoreSendOrderedCommand(HelicsCore core, const char* target, const char* command, HelicsError* err); void helicsBrokerSendCommand(HelicsBroker broker, const char* target, const char* command, HelicsError* err); diff --git a/src/helics/shared_api_library/helicsCore.h b/src/helics/shared_api_library/helicsCore.h index 02317f3672..10d303d4b8 100644 --- a/src/helics/shared_api_library/helicsCore.h +++ b/src/helics/shared_api_library/helicsCore.h @@ -1380,6 +1380,17 @@ HELICS_EXPORT int helicsFederateGetIntegerProperty(HelicsFederate fed, int intPr */ HELICS_EXPORT HelicsTime helicsFederateGetCurrentTime(HelicsFederate fed, HelicsError* err); +/** + * Create an alias for an interface. + * + * @param fed The federate to use to set the alias. + * @param interfaceName The current name of an interface. + * @param alias The additional name to use for the given interface. + * + * @param[in,out] err A pointer to an error object for catching errors. + */ +HELICS_EXPORT void helicsFederateAddAlias(HelicsFederate fed, const char* interfaceName, const char* alias, HelicsError* err); + /** * Set a federation global value through a federate. * @@ -1554,6 +1565,28 @@ HELICS_EXPORT void helicsCoreSetGlobal(HelicsCore core, const char* valueName, c */ HELICS_EXPORT void helicsBrokerSetGlobal(HelicsBroker broker, const char* valueName, const char* value, HelicsError* err); +/** + * Create an alias for an interface. + * + * @param core The core to use to set the alias. + * @param interfaceName The current name of an interface. + * @param alias The additional name to use for the given interface. + * + * @param[in,out] err A pointer to an error object for catching errors. + */ +HELICS_EXPORT void helicsCoreAddAlias(HelicsCore core, const char* interfaceName, const char* alias, HelicsError* err); + +/** + * Create an alias for an interface. + * + * @param broker The broker to use to set the alias. + * @param interfaceName The current name of an interface. + * @param alias The additional name to use for the given interface. + * + * @param[in,out] err A pointer to an error object for catching errors. + */ +HELICS_EXPORT void helicsBrokerAddAlias(HelicsBroker broker, const char* interfaceName, const char* alias, HelicsError* err); + /** * Send a command to another helics object though a core using asynchronous(fast) operations. * diff --git a/src/helics/shared_api_library/helicsExport.cpp b/src/helics/shared_api_library/helicsExport.cpp index 9a157cee4a..099f4f5619 100644 --- a/src/helics/shared_api_library/helicsExport.cpp +++ b/src/helics/shared_api_library/helicsExport.cpp @@ -588,6 +588,57 @@ void helicsBrokerSetGlobal(HelicsBroker broker, const char* valueName, const cha brk->setGlobal(valueName, AS_STRING_VIEW(value)); } +static constexpr char invalidInterfaceName[] = "Interface name cannot be empty"; +static constexpr char invalidAliasName[] = "Alias cannot be empty"; + +void helicsCoreAddAlias(HelicsCore core, const char* interfaceName, const char* alias, HelicsError* err) +{ + auto* cr = getCore(core, err); + if (cr == nullptr) { + return; + } + if (interfaceName == nullptr || strlen(interfaceName) == 0) { + assignError(err, HELICS_ERROR_INVALID_ARGUMENT, invalidInterfaceName); + return; + } + if (alias == nullptr || strlen(alias) == 0) { + assignError(err, HELICS_ERROR_INVALID_ARGUMENT, invalidAliasName); + return; + } + try { + cr->addAlias(interfaceName, alias); + } + // LCOV_EXCL_START + catch (...) { + helicsErrorHandler(err); + } + // LCOV_EXCL_STOP +} + +void helicsBrokerAddAlias(HelicsBroker broker, const char* interfaceName, const char* alias, HelicsError* err) +{ + auto* brk = getBroker(broker, err); + if (brk == nullptr) { + return; + } + if (interfaceName == nullptr || strlen(interfaceName) == 0) { + assignError(err, HELICS_ERROR_INVALID_ARGUMENT, invalidInterfaceName); + return; + } + if (alias == nullptr || strlen(alias) == 0) { + assignError(err, HELICS_ERROR_INVALID_ARGUMENT, invalidAliasName); + return; + } + try { + brk->addAlias(interfaceName, alias); + } + // LCOV_EXCL_START + catch (...) { + helicsErrorHandler(err); + } + // LCOV_EXCL_STOP +} + void helicsBrokerSendCommand(HelicsBroker broker, const char* target, const char* command, HelicsError* err) { auto* brk = getBroker(broker, err); diff --git a/tests/helics/shared_library/test-value-federate2.cpp b/tests/helics/shared_library/test-value-federate2.cpp index 7078916918..ca977cb5f7 100644 --- a/tests/helics/shared_library/test-value-federate2.cpp +++ b/tests/helics/shared_library/test-value-federate2.cpp @@ -152,6 +152,89 @@ TEST_F(vfed2_tests, file_load) helicsFederateFree(vFed); } +TEST(valuefederate, fedAlias) +{ + auto fi = helicsCreateFederateInfo(); + helicsFederateInfoSetCoreType(fi, HELICS_CORE_TYPE_TEST, nullptr); + helicsFederateInfoSetCoreName(fi, "core_alias", nullptr); + helicsFederateInfoSetCoreInitString(fi, "-f 1 --autobroker", nullptr); + helicsFederateInfoSetFlagOption(fi, + HELICS_HANDLE_OPTION_CONNECTION_REQUIRED, + HELICS_TRUE, + nullptr); + auto Fed1 = helicsCreateValueFederate("vfed1", fi, nullptr); + helicsFederateInfoFree(fi); + helicsFederateRegisterGlobalPublication( + Fed1, "pub1", HELICS_DATA_TYPE_DOUBLE, "parsecs", nullptr); + + helicsFederateAddAlias(Fed1, "pub1", "theBigPub", nullptr); + + helicsFederateRegisterSubscription(Fed1, "theBigPub", nullptr, nullptr); + + auto err = helicsErrorInitialize(); + helicsFederateEnterExecutingMode(Fed1, &err); + EXPECT_EQ(err.error_code, 0); + helicsFederateDestroy(Fed1); +} + +TEST(valuefederate, coreAlias) +{ + auto fi = helicsCreateFederateInfo(); + helicsFederateInfoSetCoreType(fi, HELICS_CORE_TYPE_TEST, nullptr); + helicsFederateInfoSetCoreName(fi, "core_alias", nullptr); + helicsFederateInfoSetCoreInitString(fi, "-f 1 --autobroker", nullptr); + helicsFederateInfoSetFlagOption(fi, + HELICS_HANDLE_OPTION_CONNECTION_REQUIRED, + HELICS_TRUE, + nullptr); + auto Fed1 = helicsCreateValueFederate("vfed1", fi, nullptr); + auto cr = helicsFederateGetCore(Fed1, nullptr); + helicsFederateInfoFree(fi); + helicsFederateRegisterGlobalPublication( + Fed1, "pub1", HELICS_DATA_TYPE_DOUBLE, "parsecs", nullptr); + + helicsCoreAddAlias(cr, "pub1", "theBigPub", nullptr); + + helicsFederateRegisterSubscription(Fed1, "theBigPub", nullptr, nullptr); + + auto err = helicsErrorInitialize(); + helicsFederateEnterExecutingMode(Fed1, &err); + EXPECT_EQ(err.error_code, 0); + helicsFederateDestroy(Fed1); + helicsCoreDestroy(cr); +} + +TEST(valuefederate, brokerAlias) +{ + auto brk = helicsCreateBroker("test", "alias_broker", "-f1", nullptr); + auto fi = helicsCreateFederateInfo(); + helicsFederateInfoSetCoreType(fi, HELICS_CORE_TYPE_TEST, nullptr); + helicsFederateInfoSetCoreName(fi, "core_alias", nullptr); + helicsFederateInfoSetCoreInitString(fi, "-f 1 --broker=alias_broker", nullptr); + helicsFederateInfoSetFlagOption(fi, + HELICS_HANDLE_OPTION_CONNECTION_REQUIRED, + HELICS_TRUE, + nullptr); + auto Fed1 = helicsCreateValueFederate("vfed1", fi, nullptr); + + helicsFederateInfoFree(fi); + helicsFederateRegisterGlobalPublication( + Fed1, "pub1", HELICS_DATA_TYPE_DOUBLE, "parsecs", nullptr); + + helicsBrokerAddAlias(brk, "pub1", "theBigPub", nullptr); + + helicsFederateRegisterSubscription(Fed1, "theBigPub", nullptr, nullptr); + + auto err = helicsErrorInitialize(); + helicsFederateEnterExecutingMode(Fed1, &err); + EXPECT_EQ(err.error_code, 0); + helicsFederateDestroy(Fed1); + auto res = helicsBrokerWaitForDisconnect(brk, 1000, &err); + EXPECT_EQ(err.error_code, 0); + EXPECT_EQ(res, HELICS_TRUE); + helicsBrokerDestroy(brk); +} + static void stateChangeCallback(HelicsFederateState newState, HelicsFederateState /*oldState*/, void* userData)