Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add middleware abstraction #62

Merged
merged 17 commits into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from 16 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
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
"typeinfo": "cpp",
"valarray": "cpp",
"variant": "cpp",
"*.inc": "cpp"
"*.inc": "cpp",
"regex": "cpp",
"shared_mutex": "cpp"
}
}
4 changes: 2 additions & 2 deletions NOTICE-3RD-PARTY-CONTENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
|identify|2.5.24|MIT|
|idna|3.4|BSD|
|Jinja2|3.1.2|New BSD|
|lxml|4.9.2|New BSD|
|lxml|4.9.3|New BSD|
|MarkupSafe|2.1.3|New BSD|
|node-semver|0.6.1|MIT|
|nodeenv|1.8.0|BSD|
|patch-ng|1.17.4|MIT|
|platformdirs|3.8.0|MIT|
|platformdirs|3.8.1|MIT|
|pluginbase|1.0.1|BSD|
|pre-commit|2.20.0|MIT|
|Pygments|2.15.1|Simplified BSD|
Expand Down
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ With the runtime running in the background, you can run the app.
Open the `Run Task` view in VSCode and select `Local - VehicleApp (Dapr run)`.

### With debugging
You can simply launch the example in the Debugging Tab. Make sure the `VehicleApp - Debug (dapr run)` is selected at the top. After the selection is done, you can also simply hit `F5`, to start the debugging session.
You can simply launch the example in the Debugging Tab. Make sure the `Example - <example of your choice>` is selected at the top. After the selection is done, you can also simply hit `F5`, to start the debugging session.

*Note: This launch task will also make sure to re-build the app if it has been modified!*

Expand All @@ -69,6 +69,24 @@ docker run --net="host" --mount type=bind,source="$(pwd)"/.dapr,target=/.dapr da
docker run --rm -it --net="host" -e DAPR_GRPC_PORT=50001 -e DAPR_HTTP_PORT=3500 localhost:12345/vehicleapp:local
```

### Middleware configuration for the example apps

You can configure the middleware to be used (i.e. either `dapr` or `native`) via environment variables of the app processs.

| Middleware | Environment Variable | Default | Meaning
|------------|---------------------------------|---------------------|------------------------------------
| | `SDV_MIDDLEWARE_TYPE` | `dapr` | Defines the middleware to be used by the app (either `dapr` or `native`)
|
| Dapr | `SDV_MQTT_ADDRESS` | `localhost:1883` | Address of the MQTT broker - needs to be set explicitly as the C++ SDK does not support Dapr PubSub, yet
| | `SEATSERVICE_DAPR_APP_ID` | `seatservice` | Application id used by Dapr to discover the application providing the seat service
| | `VEHICLEDATABROKER_DAPR_APP_ID` | `vehicledatabroker` | Application id used by Dapr to discover the application providing the Kuksa (Vehicle) Data Broker
| | (`DAPR_GRPC_PORT`) | - | Usually, `DAPR_GRPC_PORT` and `DAPR_HTTP_PORT` don't need to be configured manually. They are set by `dapr run` when starting the app and its sidecar.
| | (`DAPR_HTTP_PORT`) | - | If you need to start your app separately, please make sure these environment variables are equally available to both the app and its sidecar with identical values (see above).
| |
| native | `SDV_MQTT_ADDRESS` | `localhost:1883` | Address of the MQTT broker
| | `SDV_SEATSERVICE_ADDRESS` | - | Address of the seat service
| | `SDV_VEHICLEDATABROKER_ADDRESS` | `localhost:55555` | Address of the Kuksa (Vehicle) Data Broker

## Documentation
* [Velocitas Development Model](https://eclipse.dev/velocitas/docs/concepts/development_model/)
* [Vehicle App SDK Overview](https://eclipse.dev/velocitas/docs/concepts/development_model/vehicle_app_sdk/)
Expand Down
2 changes: 1 addition & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

class VehicleAppCppSdkConan(ConanFile):
name = "vehicle-app-sdk"
version = "0.3.2"
version = "0.3.3"
license = "Apache-2.0"
url = "https://github.com/eclipse-velocitas/vehicle-app-cpp-sdk"
description = "The Vehicle App SDK for c++ allows to create Vehicle Apps from the Velocitas development model in the c++ programming language."
Expand Down
4 changes: 2 additions & 2 deletions examples/seat-adjuster/src/SeatAdjusterApp.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2022 Robert Bosch GmbH
* Copyright (c) 2022-2023 Robert Bosch GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
Expand Down Expand Up @@ -40,7 +40,7 @@ const auto STATUS_FAIL = 1;

SeatAdjusterApp::SeatAdjusterApp()
: VehicleApp(velocitas::IVehicleDataBrokerClient::createInstance("vehicledatabroker"),
velocitas::IPubSubClient::createInstance("localhost:1883", "SeatAdjusterApp"))
velocitas::IPubSubClient::createInstance("SeatAdjusterApp"))
, m_vehicleModel(std::make_shared<velocitas::Vehicle>()) {}

void SeatAdjusterApp::onStart() {
Expand Down
48 changes: 34 additions & 14 deletions examples/set-data-points/src/SetDataPointsApp.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2022 Robert Bosch GmbH
* Copyright (c) 2022-2023 Robert Bosch GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
Expand Down Expand Up @@ -30,25 +30,45 @@ namespace example {
class SetDataPointsApp : public velocitas::VehicleApp {
public:
SetDataPointsApp()
: VehicleApp(
velocitas::IVehicleDataBrokerClient::createInstance("vehicledatabroker"),
velocitas::IPubSubClient::createInstance("localhost:1883", "SetDataPointsApp")) {}
: VehicleApp(velocitas::IVehicleDataBrokerClient::createInstance("vehicledatabroker"),
velocitas::IPubSubClient::createInstance("SetDataPointsApp")) {}

void onStart() override {
velocitas::logger().info("Setting data points!");
// set a single data point
try {
velocitas::logger().info("Setting single data point ...");

Vehicle.Speed.set(100.0F)->await();

velocitas::logger().info("Setting single data point successfully done.");
} catch (velocitas::AsyncException& e) {
velocitas::logger().error("Error on setting single data point: {}", e.what());
}

// set multiple data points at the same time
Vehicle.setMany()
.add(Vehicle.Cabin.Seat.Row1.Pos1.Position, 1000)
.add(Vehicle.Cabin.Seat.Row1.Pos2.Position, 1000)
.apply()
->await();
try {
velocitas::logger().info("Setting batch of data points ...");

// set a single data point
Vehicle.Speed.set(100.0F)->await();
auto result = Vehicle.setMany()
.add(Vehicle.Cabin.Seat.Row1.Pos1.Position, 1000)
.add(Vehicle.Cabin.Seat.Row1.Pos2.Position, 1000)
.apply()
->await();

if (result.empty()) {
velocitas::logger().info("Setting batch of data points successfully done.");
} else {
velocitas::logger().error("Some data points of batch could not be set:");
for (auto datapointError : result) {
velocitas::logger().error(" '{}' -> {}", datapointError.first,
datapointError.second);
}
}
} catch (velocitas::AsyncException& e) {
velocitas::logger().error("Error on setting batch of data points: {}", e.what());
}

// get a single data point
Vehicle.Cabin.Seat.Row1.Pos1.Position.get()->await();
velocitas::logger().info("Done. (Press Ctrl+C to terminate the app.)");
}

private:
Expand Down
14 changes: 9 additions & 5 deletions examples/vehicle_model/Cabin/SeatService/SeatService.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2022 Robert Bosch GmbH
* Copyright (c) 2022-2023 Robert Bosch GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
Expand Down Expand Up @@ -81,11 +81,15 @@ Status toInternalStatus(grpc::Status status) {
}

SeatService::SeatService(Model* parent)
: Service("VehicleService", parent) {
: Service("SeatService", parent) {
m_asyncGrpcFacade = std::make_shared<SeatServiceAsyncGrpcFacade>(
grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()));
m_asyncGrpcFacade->setContextModifier(
[this](auto& context) { context.AddMetadata("dapr-app-id", getName()); });
grpc::CreateChannel(getLocation(), grpc::InsecureChannelCredentials()));
Middleware::Metadata metadata = getMiddlewareMetadata();
m_asyncGrpcFacade->setContextModifier([metadata](auto& context) {
for (auto metadatum : metadata) {
context.AddMetadata(metadatum.first, metadatum.second);
}
});
}

AsyncResultPtr_t<VoidResult> SeatService::move(const SeatService::Seat& seat) {
Expand Down
18 changes: 17 additions & 1 deletion sdk/include/sdk/IPubSubClient.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2022 Robert Bosch GmbH
* Copyright (c) 2022-2023 Robert Bosch GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
Expand Down Expand Up @@ -30,6 +30,22 @@ namespace velocitas {
*/
class IPubSubClient {
public:
/**
* @brief Create an instance of a pub/sub client according to the defined middleware
* configuration
*
* @param clientId used to identify the client at the pub/sub server
* @return std::shared_ptr<IPubSubClient> reference to the created pub/sub client
*/
static std::shared_ptr<IPubSubClient> createInstance(const std::string& clientId);
BjoernAtBosch marked this conversation as resolved.
Show resolved Hide resolved

/**
* @brief Create a new instance of a MQTT client connecting to a broker at the specified address
BjoernAtBosch marked this conversation as resolved.
Show resolved Hide resolved
*
* @param brokerUri address of the MQTT broker to connect to
* @param clientId used to identify the client at the MQTT broker
* @return std::shared_ptr<IPubSubClient> reference to the created MQTT client
*/
static std::shared_ptr<IPubSubClient> createInstance(const std::string& brokerUri,
const std::string& clientId);

Expand Down
6 changes: 5 additions & 1 deletion sdk/include/sdk/Model.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2022 Robert Bosch GmbH
* Copyright (c) 2022-2023 Robert Bosch GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
Expand All @@ -19,6 +19,7 @@

#include "sdk/DataPointBatch.h"
#include "sdk/Node.h"
#include "sdk/middleware/Middleware.h"

#include <string>

Expand All @@ -43,6 +44,9 @@ class Model : public Node {
class Service : public Node {
public:
using Node::Node;

std::string getLocation() const;
Middleware::Metadata getMiddlewareMetadata() const;
};

} // namespace velocitas
Expand Down
48 changes: 46 additions & 2 deletions sdk/include/sdk/Utils.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2022 Robert Bosch GmbH
* Copyright (c) 2022-2023 Robert Bosch GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
Expand All @@ -22,17 +22,61 @@

namespace velocitas {

/**
* @brief Get the value of the specified environment variable
*
* @param varName Name of the environment variable
* @param defaultValue Default if variable is not set
* @return std::string containing the value of the variable or the default value
*/
std::string getEnvVar(const std::string& varName, const std::string& defaultValue = "");

/**
* @brief Provides utility methods for handling strings.
*
*/
class StringUtils final {
public:
/**
* @brief Convert the passed string to lowercase
BjoernAtBosch marked this conversation as resolved.
Show resolved Hide resolved
*
* @param str string to be converted
* @return std::string having all uppercase letters contained in the passed string converted to
* lowercase
*/
static std::string toLower(const std::string& str);
BjoernAtBosch marked this conversation as resolved.
Show resolved Hide resolved

/**
* @brief Convert the passed string to uppercase
BjoernAtBosch marked this conversation as resolved.
Show resolved Hide resolved
*
* @param str string to be converted
* @return std::string having all lowercase letters contained in the passed string converted to
* uppercase
*/
static std::string toUpper(const std::string& str);

/**
* @brief Concatenate the strings of the passed vector by adding the passed separator between
* each two of the array elements.
*
* Examples:
*
* stringVector | separator | result
* -------------------------|------------|--------------------
* [] (empty vector) | don't care | ""
* ["hello"] | don't care | "hello"
* ["hello", "world", "eh"] | ", " | "hello, world, eh"
* ["single", "ton"] | "" | "singleton"
*
* @param stringVector vector of strings to be concatenated
* @param separator string to be put between each two vector elements
* @return std::string containing the joined contents
*/
static std::string join(const std::vector<std::string>& stringVector,
const std::string& separator);

private:
StringUtils() = default;
StringUtils() = delete;
};

} // namespace velocitas
Expand Down
3 changes: 2 additions & 1 deletion sdk/include/sdk/dapr/DaprSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace velocitas::dapr {
* @brief Wait for the dapr sidecar to become available.
*
*/
void waitForSidecar();
[[deprecated("Don't call - this is handled by middleware internally. Will be removed soon!")]] void
waitForSidecar();

} // namespace velocitas::dapr
11 changes: 5 additions & 6 deletions sdk/include/sdk/grpc/VehicleDataBrokerClient.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2022 Robert Bosch GmbH
* Copyright (c) 2022-2023 Robert Bosch GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
Expand All @@ -20,6 +20,7 @@
#include "sdk/vdb/IVehicleDataBrokerClient.h"

#include <memory>
#include <string>
#include <vector>

namespace velocitas {
Expand All @@ -33,8 +34,8 @@ class BrokerAsyncGrpcFacade;
*/
class VehicleDataBrokerClient : public IVehicleDataBrokerClient {
public:
explicit VehicleDataBrokerClient(const std::string& vdbAddress, std::string vdbAppId);
explicit VehicleDataBrokerClient(const std::string& vdbAppId);
explicit VehicleDataBrokerClient(const std::string& vdbAddress, std::string vdbServiceName);
explicit VehicleDataBrokerClient(const std::string& vdbserviceName);

~VehicleDataBrokerClient() override;

Expand All @@ -52,11 +53,9 @@ class VehicleDataBrokerClient : public IVehicleDataBrokerClient {
AsyncSubscriptionPtr_t<DataPointReply> subscribe(const std::string& query) override;

private:
static std::string getVdbEndpointAddress();

std::shared_ptr<BrokerAsyncGrpcFacade> m_asyncBrokerFacade;
std::string m_vdbAppId;
};

} // namespace velocitas

#endif // VEHICLE_APP_SDK_VEHICLEDATABROKERCLIENT_H
Loading