Skip to content

Commit

Permalink
config: allow overriding rpc and pub/sub labels (#87)
Browse files Browse the repository at this point in the history
Co-authored-by: Konrad Breitsprecher <[email protected]>
  • Loading branch information
VDanielEdwards and KonradBkd authored Oct 31, 2024
1 parent f3d05c2 commit 7e7ae71
Show file tree
Hide file tree
Showing 19 changed files with 537 additions and 52 deletions.
54 changes: 54 additions & 0 deletions SilKit/IntegrationTests/ITest_Internals_DataPubSub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,60 @@ TEST_F(ITest_Internals_DataPubSub, test_1pub_1sub_sync_mixed_labels)
RunSyncTest(pubsubs);
}

// Matching mandatory labels provided by a participant configuration
TEST_F(ITest_Internals_DataPubSub, test_1pub_1sub_sync_label_override)
{
const uint32_t numMsgToPublish = defaultNumMsgToPublish;
const uint32_t numMsgToReceive = numMsgToPublish;

auto pub1Config = SilKit::Config::ParticipantConfigurationFromStringImpl(R"(
DataPublishers:
- Name: PubCtrl1
Labels:
- Key: OverrideKeyA
Value: OverrideValueA
Kind: Optional
- Key: OverrideKeyB
Value: OverrideValueB
Kind: Mandatory
)");

auto sub1Config = SilKit::Config::ParticipantConfigurationFromStringImpl(R"(
DataSubscribers:
- Name: SubCtrl1
Labels:
- Key: OverrideKeyA
Value: OverrideValueA
Kind: Mandatory
- Key: OverrideKeyB
Value: OverrideValueB
Kind: Optional
)");

std::vector<PubSubParticipant> pubsubs;
pubsubs.push_back({"Pub1",
{{"PubCtrl1",
"TopicA",
{"A"},
{{"kA", "vA", MatchingLabel::Kind::Mandatory}, {"kB", "vB", MatchingLabel::Kind::Mandatory}},
0,
defaultMsgSize,
numMsgToPublish}},
{},
pub1Config});
pubsubs.push_back({"Sub1",
{},
{{"SubCtrl1",
"TopicA",
{"A"},
{{"kA", "NOT vA", MatchingLabel::Kind::Mandatory}},
defaultMsgSize,
numMsgToReceive,
1}},
sub1Config});

RunSyncTest(pubsubs);
}

// Wrong mandatory label value -> Expect no reception
TEST_F(ITest_Internals_DataPubSub, test_1pub_1sub_sync_wrong_mandatory_label_value)
Expand Down
14 changes: 7 additions & 7 deletions SilKit/IntegrationTests/ITest_Internals_DataPubSub.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,27 +184,27 @@ class ITest_Internals_DataPubSub : public testing::Test
struct PubSubParticipant
{
PubSubParticipant(const std::string& newName)
: PubSubParticipant(newName, {}, {})
{
name = newName;
}
PubSubParticipant(const std::string& newName, const std::vector<DataPublisherInfo>& newDataPublishers,
const std::vector<DataSubscriberInfo>& newDataSubscribers,
std::shared_ptr<SilKit::Config::IParticipantConfiguration> newConfig =
SilKit::Config::MakeEmptyParticipantConfigurationImpl())
: config{std::move(newConfig)}
, name{newName}
, dataSubscribers{newDataSubscribers}
, dataPublishers{newDataPublishers}
{
config = newConfig;
name = newName;
dataSubscribers = newDataSubscribers;
dataPublishers = newDataPublishers;
}

std::shared_ptr<SilKit::Config::IParticipantConfiguration> config = MakeEmptyParticipantConfigurationImpl();
std::shared_ptr<SilKit::Config::IParticipantConfiguration> config;
bool delayedDefaultDataHandler = false;
std::string name;
std::vector<DataSubscriberInfo> dataSubscribers;
std::vector<DataPublisherInfo> dataPublishers;
std::unique_ptr<SilKit::IParticipant> participant;
SilKit::Core::IParticipantInternal* participantImpl;
SilKit::Core::IParticipantInternal* participantImpl = nullptr;

// Common
std::promise<void> participantCreatedPromise;
Expand Down
59 changes: 59 additions & 0 deletions SilKit/IntegrationTests/ITest_Internals_Rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */

#include "ITest_Internals_Rpc.hpp"

#include "ParticipantConfigurationFromXImpl.hpp"

namespace {

//--------------------------------------
Expand Down Expand Up @@ -295,6 +297,63 @@ TEST_F(ITest_Internals_Rpc, test_1client_1server_sync_labels)
RunSyncTest(rpcs);
}

// Matching mandatory and optional labels on both sides provided by a participant configuration
TEST_F(ITest_Internals_Rpc, test_1client_1server_sync_label_override)
{
const uint32_t numCallsToReceive = defaultNumCalls;
const uint32_t numCallsToReturn = defaultNumCalls;

auto client1Config = SilKit::Config::ParticipantConfigurationFromStringImpl(R"(
RpcClients:
- Name: ClientCtrl1
Labels:
- Key: OverrideKeyA
Value: OverrideValueA
Kind: Mandatory
- Key: OverrideKeyB
Value: OverrideValueB
Kind: Optional
)");

auto server1Config = SilKit::Config::ParticipantConfigurationFromStringImpl(R"(
RpcServers:
- Name: ServerCtrl1
Labels:
- Key: OverrideKeyA
Value: OverrideValueA
Kind: Optional
- Key: OverrideKeyB
Value: OverrideValueB
Kind: Mandatory
)");

std::vector<RpcParticipant> rpcs;
rpcs.push_back({"Client1",
{},
{{"ClientCtrl1",
"TestFuncA",
"A",
{{"KeyA", "ValA", SilKit::Services::MatchingLabel::Kind::Mandatory},
{"KeyB", "ValB", SilKit::Services::MatchingLabel::Kind::Mandatory}},
defaultMsgSize,
defaultNumCalls,
numCallsToReturn}},
{"TestFuncA"},
client1Config});
rpcs.push_back({"Server1",
{{"ServerCtrl1",
"TestFuncA",
"A",
{{"KeyA", "ValA2", SilKit::Services::MatchingLabel::Kind::Optional}},
defaultMsgSize,
numCallsToReceive}},
{},
{},
server1Config});

RunSyncTest(rpcs);
}

// No communication with server2 (missing mandatory label on client)
TEST_F(ITest_Internals_Rpc, test_1client_2server_sync_wrong_mandatory_label)
{
Expand Down
18 changes: 9 additions & 9 deletions SilKit/IntegrationTests/ITest_Internals_Rpc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,22 +260,24 @@ class ITest_Internals_Rpc : public testing::Test
struct RpcParticipant
{
RpcParticipant(const std::string& newName, const std::vector<std::string>& newExpectedFunctionNames)
: RpcParticipant(newName, {}, {}, newExpectedFunctionNames)
{
name = newName;
expectedFunctionNames = newExpectedFunctionNames;
}

RpcParticipant(const std::string& newName, std::vector<RpcServerInfo> newRpcServers,
std::vector<RpcClientInfo> newRpcClients, std::vector<std::string> newExpectedFunctionNames)
: expectedFunctionNames{std::move(newExpectedFunctionNames)}
std::vector<RpcClientInfo> newRpcClients, std::vector<std::string> newExpectedFunctionNames,
std::shared_ptr<SilKit::Config::IParticipantConfiguration> newConfig =
SilKit::Config::MakeEmptyParticipantConfigurationImpl())
: config{std::move(newConfig)}
, name{newName}
, expectedFunctionNames{std::move(newExpectedFunctionNames)}
{
name = newName;

std::for_each(newRpcServers.begin(), newRpcServers.end(), [this](const auto& info) { AddRpcServer(info); });

std::for_each(newRpcClients.begin(), newRpcClients.end(), [this](const auto& info) { AddRpcClient(info); });
}

std::shared_ptr<SilKit::Config::IParticipantConfiguration> config;
std::string name;
std::vector<std::unique_ptr<RpcClientState>> rpcClients;
std::vector<std::unique_ptr<RpcServerState>> rpcServers;
Expand Down Expand Up @@ -395,9 +397,7 @@ class ITest_Internals_Rpc : public testing::Test
{
try
{
participant.participant = SilKit::CreateParticipantImpl(
SilKit::Config::MakeParticipantConfigurationWithLoggingImpl(SilKit::Services::Logging::Level::Warn),
participant.name, registryUri);
participant.participant = SilKit::CreateParticipantImpl(participant.config, participant.name, registryUri);
participant.participantImpl =
dynamic_cast<SilKit::Core::IParticipantInternal*>(participant.participant.get());

Expand Down
70 changes: 70 additions & 0 deletions SilKit/source/config/ParticipantConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,73 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */

#include "ParticipantConfiguration.hpp"

#include <string>
#include <type_traits>

namespace SilKit {
namespace Config {
namespace v1 {

auto Label::ToPublicApi() const -> SilKit::Services::MatchingLabel
{
SilKit::Services::MatchingLabel result;

result.key = key;
result.value = value;

switch (kind)
{
case Kind::Mandatory:
result.kind = SilKit::Services::MatchingLabel::Kind::Mandatory;
break;
case Kind::Optional:
result.kind = SilKit::Services::MatchingLabel::Kind::Optional;
break;
default:
throw SilKit::ConfigurationError{
"Invalid SilKit::Config::v1::MatchingLabel::Kind("
+ std::to_string(static_cast<std::underlying_type_t<Label::Kind>>(kind)) + ")"};
}

return result;
}


auto Label::FromPublicApi(const SilKit::Services::MatchingLabel& label) -> Label
{
Label result;

result.key = label.key;
result.value = label.value;

switch (label.kind)
{
case SilKit::Services::MatchingLabel::Kind::Mandatory:
result.kind = Label::Kind::Mandatory;
break;
case SilKit::Services::MatchingLabel::Kind::Optional:
result.kind = Label::Kind::Optional;
break;
default:
throw SilKit::ConfigurationError{
"Invalid SilKit::Services::MatchingLabel::Kind("
+ std::to_string(static_cast<std::underlying_type_t<SilKit::Services::MatchingLabel::Kind>>(label.kind))
+ ")"};
}

return result;
}


auto Label::VectorFromPublicApi(const std::vector<SilKit::Services::MatchingLabel>& labels) -> std::vector<Label>
{
std::vector<SilKit::Config::v1::Label> result;
std::transform(labels.begin(), labels.end(), std::back_inserter(result), Label::FromPublicApi);
return result;
}


} // namespace v1
} // namespace Config
} // namespace SilKit
31 changes: 31 additions & 0 deletions SilKit/source/config/ParticipantConfiguration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include <array>
#include <chrono>
#include <iostream>
#include <ostream>
#include <string>
#include <vector>

Expand All @@ -32,6 +33,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "silkit/services/logging/LoggingDatatypes.hpp"
#include "silkit/services/pubsub/PubSubDatatypes.hpp"
#include "silkit/services/rpc/RpcDatatypes.hpp"
#include "silkit/services/datatypes.hpp"

#include "Configuration.hpp"
#include "Optional.hpp"
Expand Down Expand Up @@ -136,6 +138,27 @@ struct FlexrayController
Replay replay;
};

// ================================================================================
// Labels for Data Publisher/Subscriber and Rpc Servcer/Client service
// ================================================================================

struct Label
{
enum struct Kind
{
Optional,
Mandatory,
};

std::string key;
std::string value;
Kind kind;

auto ToPublicApi() const -> SilKit::Services::MatchingLabel;
static auto FromPublicApi(const SilKit::Services::MatchingLabel& label) -> Label;
static auto VectorFromPublicApi(const std::vector<SilKit::Services::MatchingLabel>& labels) -> std::vector<Label>;
};

// ================================================================================
// Data Publisher/Subscriber service
// ================================================================================
Expand All @@ -150,6 +173,7 @@ struct DataPublisher

std::string name;
SilKit::Util::Optional<std::string> topic;
SilKit::Util::Optional<std::vector<Label>> labels;

//! \brief History length of a DataPublisher.
SilKit::Util::Optional<size_t> history{0};
Expand All @@ -168,6 +192,7 @@ struct DataSubscriber

std::string name;
SilKit::Util::Optional<std::string> topic;
SilKit::Util::Optional<std::vector<Label>> labels;

std::vector<std::string> useTraceSinks;
Replay replay;
Expand All @@ -187,6 +212,7 @@ struct RpcServer

std::string name;
SilKit::Util::Optional<std::string> functionName;
SilKit::Util::Optional<std::vector<Label>> labels;

std::vector<std::string> useTraceSinks;
Replay replay;
Expand All @@ -202,6 +228,7 @@ struct RpcClient

std::string name;
SilKit::Util::Optional<std::string> functionName;
SilKit::Util::Optional<std::vector<Label>> labels;

std::vector<std::string> useTraceSinks;
Replay replay;
Expand Down Expand Up @@ -368,6 +395,10 @@ bool operator==(const Middleware& lhs, const Middleware& rhs);
bool operator==(const ParticipantConfiguration& lhs, const ParticipantConfiguration& rhs);
bool operator==(const TimeSynchronization& lhs, const TimeSynchronization& rhs);
bool operator==(const Experimental& lhs, const Experimental& rhs);
bool operator==(const Label& lhs, const Label& rhs);

auto operator<<(std::ostream& out, const Label::Kind& kind) -> std::ostream&;
auto operator<<(std::ostream& out, const Label& label) -> std::ostream&;

bool operator<(const MetricsSink& lhs, const MetricsSink& rhs);
bool operator>(const MetricsSink& lhs, const MetricsSink& rhs);
Expand Down
Loading

0 comments on commit 7e7ae71

Please sign in to comment.