Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions score/mw/com/gateway/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

package(
default_visibility = ["//score/mw/com:__subpackages__"],
)
56 changes: 56 additions & 0 deletions score/mw/com/gateway/gateway_application/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

load("@rules_cc//cc:defs.bzl", "cc_library")
load("//quality/unit_testing:unit_testing.bzl", "cc_unit_test")
load("//score/mw:common_features.bzl", "COMPILER_WARNING_FEATURES")

package(
default_visibility = ["//score/mw/com/gateway:__subpackages__"],
)

cc_library(
name = "gateway_core",
hdrs = ["gateway_core.h"],
features = COMPILER_WARNING_FEATURES,
visibility = [
"//score/mw/com/gateway:__subpackages__",
],
deps = [
"//score/mw/com/gateway/transport_layer:transport",
"//score/mw/com/impl:instance_specifier",
"//score/mw/com/impl:service_element_type",
"@score_baselibs//score/result",
],
)

cc_library(
name = "gateway_error",
srcs = ["gateway_error.cpp"],
hdrs = ["gateway_error.h"],
features = COMPILER_WARNING_FEATURES,
visibility = [
"//score/mw/com/gateway:__subpackages__",
],
deps = ["@score_baselibs//score/result"],
)

cc_unit_test(
name = "gateway_error_test",
srcs = ["gateway_error_test.cpp"],
features = COMPILER_WARNING_FEATURES,
deps = [
":gateway_error",
"@score_baselibs//score/result",
],
)
93 changes: 93 additions & 0 deletions score/mw/com/gateway/gateway_application/gateway_core.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/********************************************************************************
* Copyright (c) 2026 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
#ifndef SCORE_MW_COM_GATEWAY_GATEWAY_APPLICATION_GATEWAY_CORE_H
#define SCORE_MW_COM_GATEWAY_GATEWAY_APPLICATION_GATEWAY_CORE_H

#include "score/mw/com/gateway/transport_layer/transport.h"
#include "score/mw/com/impl/instance_specifier.h"
#include "score/mw/com/impl/service_element_type.h"
#include "score/result/result.h"

#include <string>
#include <vector>

namespace score::mw::com::gateway
{

class GatewayCore
{
public:
virtual ~GatewayCore() = default;

/// \brief Provide the given service instance locally.
/// \details This API is expected to be called by the transport layer implementation, when the transport layer
/// receives a request from the remote gateway to provide a service instance. It shall provide/create the given
/// service instance locally (e.g. by creating a GenericSkeleton) and offer it.
///
/// \param service_instance_specifier instance specifier of the service instance to provide. It is expected, that
/// this specifier is configured/existent in the mw_com_config.json at the local gateway side.
/// \param service_elements description of the service elements (events, fields, methods) which should be provided
/// for the service instance, which will be realized as a GenericSkeleton.
/// \return result indicating success or failure.
virtual score::Result<void> ProvideService(impl::InstanceSpecifier service_instance_specifier,
std::vector<ServiceElementConfiguration> service_elements) = 0;

/// \brief Stop providing the given service instance locally.
/// \param service_instance_specifier instance specifier of the service instance to stop offering. It is expected,
/// that this specifier is configured/existent in the mw_com_config.json at the local gateway side.
virtual void StopOfferService(impl::InstanceSpecifier service_instance_specifier) = 0;

/// \brief Offer the given service instance locally.
/// \param service_instance_specifier instance specifier of the service instance to offer. It is expected, that
/// this specifier is configured/existent in the mw_com_config.json at the local gateway side.
/// \return result indicating success or failure.
virtual score::Result<void> OfferService(impl::InstanceSpecifier service_instance_specifier) = 0;

/// \brief Register an event-update notification for the given service instance and element locally.
/// \param service_instance_specifier instance specifier of the service instance, for which registration takes
/// place. It is expected, that this specifier is configured/existent in the mw_com_config.json at the local
/// gateway side.
/// \param element_type type of the service element (event, field, method). Currently only EVENT is supported.
/// \param element_name name of the service element for which update notifications shall be registered.
/// \return result indicating success or failure.
virtual score::Result<void> RegisterUpdateNotification(impl::InstanceSpecifier service_instance_specifier,
impl::ServiceElementType element_type,
std::string element_name) = 0;

/// \brief Unregister an event-update notification for the given service instance and element locally.
/// \param service_instance_specifier instance specifier of the service instance, for which unregistration takes
/// place. It is expected, that this specifier is configured/existent in the mw_com_config.json at the local
/// gateway side.
/// \param element_type type of the service element (event, field, method). Currently only EVENT is supported.
/// \param element_name name of the service element for which update notifications shall be unregistered.
/// \return result indicating success or failure.
virtual score::Result<void> UnregisterUpdateNotification(impl::InstanceSpecifier service_instance_specifier,
impl::ServiceElementType element_type,
std::string element_name) = 0;

/// \brief Notify an event update for the given service instance and element locally.
/// \param service_instance_specifier instance specifier of the service instance, for which notification takes
/// place. It is expected, that this specifier is configured/existent in the mw_com_config.json at the local
/// gateway side.
/// \param updated_element_type type of the element (currently only events supported) for which an update shall be
/// notified.
/// \param updated_element_name name of the element (e.g. event name) for which an update shall be notified.
/// \return result indicating success or failure.
virtual score::Result<void> NotifyUpdate(impl::InstanceSpecifier service_instance_specifier,
impl::ServiceElementType updated_element_type,
std::string updated_element_name) = 0;
};

} // namespace score::mw::com::gateway

#endif // SCORE_MW_COM_GATEWAY_GATEWAY_APPLICATION_GATEWAY_CORE_H
23 changes: 23 additions & 0 deletions score/mw/com/gateway/gateway_application/gateway_error.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/********************************************************************************
* Copyright (c) 2026 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
#include "score/mw/com/gateway/gateway_application/gateway_error.h"

namespace
{
constexpr score::mw::com::gateway::GatewayErrorDomain g_gateway_error_domain;
} // namespace

score::result::Error score::mw::com::gateway::MakeError(const GatewayErrorc code, const std::string_view message)
{
return {static_cast<score::result::ErrorCode>(code), g_gateway_error_domain, message};
}
64 changes: 64 additions & 0 deletions score/mw/com/gateway/gateway_application/gateway_error.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/********************************************************************************
* Copyright (c) 2026 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
#ifndef SCORE_MW_COM_GATEWAY_GATEWAY_APPLICATION_GATEWAY_ERROR_H
#define SCORE_MW_COM_GATEWAY_GATEWAY_APPLICATION_GATEWAY_ERROR_H

#include "score/result/result.h"

#include <string_view>

namespace score::mw::com::gateway
{

enum class GatewayErrorc : score::result::ErrorCode
{
kSkeletonCreationFailed = 1,
kSkeletonOfferFailed,
kSkeletonStopOfferFailed,
kUnknownServiceInstance,
kUnknownServiceElement,
kReceiveHandlerRegistrationFailed,
kNonWhitelistedService,
};

score::result::Error MakeError(const GatewayErrorc code, const std::string_view message = "");

class GatewayErrorDomain final : public score::result::ErrorDomain
{
public:
std::string_view MessageFor(const score::result::ErrorCode& code) const noexcept override final
{
switch (code)
{
case static_cast<score::result::ErrorCode>(GatewayErrorc::kSkeletonCreationFailed):
return "Creation of generic skeleton on destination gateway failed.";
case static_cast<score::result::ErrorCode>(GatewayErrorc::kSkeletonOfferFailed):
return "Offering of generic skeleton on destination gateway failed.";
case static_cast<score::result::ErrorCode>(GatewayErrorc::kUnknownServiceInstance):
return "Gateway received an API call for an unknown service instance identifier.";
case static_cast<score::result::ErrorCode>(GatewayErrorc::kUnknownServiceElement):
return "Gateway received an API call for an unknown service element within an instance identifier.";
case static_cast<score::result::ErrorCode>(GatewayErrorc::kReceiveHandlerRegistrationFailed):
return "Gateway couldn't register event-receive-handler at its generic proxy to forward event update "
"notifications.";
case static_cast<score::result::ErrorCode>(GatewayErrorc::kNonWhitelistedService):
return "Gateway received request to provide a non-whitelised service.";
default:
return "unknown gateway error";
}
}
};

} // namespace score::mw::com::gateway

#endif // SCORE_MW_COM_GATEWAY_GATEWAY_APPLICATION_GATEWAY_ERROR_H
98 changes: 98 additions & 0 deletions score/mw/com/gateway/gateway_application/gateway_error_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/********************************************************************************
* Copyright (c) 2026 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
#include "score/mw/com/gateway/gateway_application/gateway_error.h"

#include <gtest/gtest.h>

namespace score::mw::com::gateway
{
namespace
{

class GatewayErrorTest : public ::testing::Test
{
protected:
void TestErrorMessage(const GatewayErrorc error_code, const std::string_view expected_error_output)
{
const auto error_code_test =
gateway_error_domain_dummy_.MessageFor(static_cast<score::result::ErrorCode>(error_code));
ASSERT_EQ(error_code_test, expected_error_output);
}

GatewayErrorDomain gateway_error_domain_dummy_{};
};

TEST_F(GatewayErrorTest, MessageForSkeletonCreationFailed)
{
TestErrorMessage(GatewayErrorc::kSkeletonCreationFailed,
"Creation of generic skeleton on destination gateway failed.");
}

TEST_F(GatewayErrorTest, MessageForSkeletonOfferFailed)
{
TestErrorMessage(GatewayErrorc::kSkeletonOfferFailed,
"Offering of generic skeleton on destination gateway failed.");
}

TEST_F(GatewayErrorTest, MessageForSkeletonStopOfferFailedFallsBackToDefault)
{
TestErrorMessage(GatewayErrorc::kSkeletonStopOfferFailed, "unknown gateway error");
}

TEST_F(GatewayErrorTest, MessageForUnknownServiceInstance)
{
TestErrorMessage(GatewayErrorc::kUnknownServiceInstance,
"Gateway received an API call for an unknown service instance identifier.");
}

TEST_F(GatewayErrorTest, MessageForUnknownServiceElement)
{
TestErrorMessage(GatewayErrorc::kUnknownServiceElement,
"Gateway received an API call for an unknown service element within an instance identifier.");
}

TEST_F(GatewayErrorTest, MessageForReceiveHandlerRegistrationFailed)
{
TestErrorMessage(
GatewayErrorc::kReceiveHandlerRegistrationFailed,
"Gateway couldn't register event-receive-handler at its generic proxy to forward event update notifications.");
}

TEST_F(GatewayErrorTest, MessageForNonWhitelistedService)
{
TestErrorMessage(GatewayErrorc::kNonWhitelistedService,
"Gateway received request to provide a non-whitelised service.");
}

TEST_F(GatewayErrorTest, MessageForDefault)
{
TestErrorMessage(static_cast<GatewayErrorc>(-1), "unknown gateway error");
}

TEST(GatewayError, MakeErrorExpectedError)
{
const score::result::Error err{MakeError(GatewayErrorc::kUnknownServiceInstance)};
EXPECT_EQ(*err, static_cast<int>(GatewayErrorc::kUnknownServiceInstance));
EXPECT_TRUE(err.UserMessage().empty());
}

TEST(GatewayError, MakeErrorExpectedErrorWithUserMessage)
{
constexpr std::string_view kUserMessage{"test user message"};
const score::result::Error err{MakeError(GatewayErrorc::kSkeletonOfferFailed, kUserMessage)};
EXPECT_EQ(*err, static_cast<int>(GatewayErrorc::kSkeletonOfferFailed));
EXPECT_EQ(err.UserMessage(), kUserMessage);
}

} // namespace
} // namespace score::mw::com::gateway
Loading