MINIFICPP-2816 Add controller_service::api_implementations to C api#2176
MINIFICPP-2816 Add controller_service::api_implementations to C api#2176martinzink wants to merge 7 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the C extension API for MiNiFi C++ to let C-based controller services declare and expose multiple "provided interfaces" (additional C++ APIs they implement). The agent surfaces these as api_implementations in class descriptions, and MinifiProcessContextGetControllerService now uses a new get_interface callback to cast a controller service implementation to a requested API type. A new stable-api-sandbox test extension exercises the feature with Dog/Duck controller services that both implement CanFlyControllerApi and NumberOfLegsControllerApi, consumed by a ZooProcessor.
Changes:
- Added
provided_interfaces_*and aget_interfacecallback to the C controller-service ABI, plumbed throughuseControllerServiceClassDefinitionanduseCControllerServiceClassDescriptionintoClassDescription::api_implementations. - Introduced a C++-side
ProvidedInterface/createProvidedInterfacehelper and aControllerServiceType::minifiSystemControllerServiceTypefactory. - Added a new
stable-api-sandboxextension (controller services, processor, init, tests, CMake) demonstrating and testing the multi-interface controller service flow.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| minifi-api/include/minifi-c/minifi-c.h | Adds provided_interfaces_* fields and get_interface callback to controller-service C ABI structs. |
| minifi-api/include/minifi-cpp/core/ControllerServiceType.h | Adds minifiSystemControllerServiceType factory and tightens reformatting; private ctor for raw fields. |
| minifi-api/common/include/minifi-cpp/core/ProvidedControllerServiceInterface.h | New header defining ProvidedInterface and the createProvidedInterface helper template. |
| extension-framework/cpp-extension-lib/include/api/core/Resource.h | Wires Class::ProvidedInterfaces into the C definition and implements the get_interface lambda. |
| libminifi/src/minifi-c.cpp | Builds api_implementations from C-side interface names; uses get_interface in MinifiProcessContextGetControllerService. |
| extensions/stable-api-sandbox/AnimalControllerServiceApis.h | Defines two abstract controller-service APIs used by the sandbox tests. |
| extensions/stable-api-sandbox/AnimalControllerServices.{h,cpp} | DogController/DuckController implementing both APIs and declaring ProvidedInterfaces. |
| extensions/stable-api-sandbox/ZooProcessor.{h,cpp} | Test processor that fetches both interfaces from configured controller services. |
| extensions/stable-api-sandbox/ExtensionInitializer.cpp | Registers the new processor and controller services as a C extension. |
| extensions/stable-api-sandbox/CMakeLists.txt | New CMake module building the sandbox extension. |
| extensions/stable-api-sandbox/tests/CMakeLists.txt | Builds the sandbox extension's tests. |
| extensions/stable-api-sandbox/tests/ZooTests.cpp | End-to-end test exercising multi-interface lookup via the C API. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
615a1aa to
8a61732
Compare
e37d114 to
3f19d56
Compare
3f19d56 to
4df654c
Compare
a663671 to
b607c29
Compare
75dec07 to
6fc9e41
Compare
2cac27e to
97b90aa
Compare
7d06f20 to
e727372
Compare
|
|
||
| explicit ControllerServiceFactoryImpl(std::string group_name) | ||
| : group_name_(std::move(group_name)), | ||
| explicit ControllerServiceFactoryImpl(std::string module_name) |
There was a problem hiding this comment.
Ive renamed it from group_name to module_name, because this groupname was not the groupname in C2 but rather the artifact name
62b57f8 to
1311c86
Compare
1311c86 to
9175793
Compare
9175793 to
5955a53
Compare
6321c43 to
4429809
Compare
5955a53 to
c13b5b4
Compare
There was a problem hiding this comment.
I'm thinking we should call this stable-api-tests or something like that, so even at first glance it's clear that this is a test-only extension.
| EXTENSIONAPI static constexpr auto CanFlyService = core::PropertyDefinitionBuilder<>::createProperty("Can fly service") | ||
| .withDescription("Test CanFlyService") | ||
| .isRequired(true) | ||
| .withAllowedTypes<CanFlyControllerApi>() | ||
| .build(); |
There was a problem hiding this comment.
Continuation indentation should be 4 spaces deeper. I'm against trying to maintain alignments, because we get right-heavy lines like these, plus renames and similar changes break alignment.
| { | ||
| LogTestController::getInstance().clear(); | ||
| CHECK(controller.getProcessor()->setProperty(ZooProcessor::CanFlyService.name, "duck")); | ||
| CHECK(controller.getProcessor()->setProperty(ZooProcessor::NumberOfLegsService.name, "invalid")); |
There was a problem hiding this comment.
no we dont validate here, thats only done on C2 side, we theoratically could so its might be a good feature
| void initialize() override {} | ||
| void onEnable() override {} | ||
|
|
||
| [[nodiscard]] ControllerServiceHandle* getControllerServiceHandle() override { return this; } |
There was a problem hiding this comment.
Maybe this should be added to the macro ADD_COMMON_VIRTUAL_FUNCTIONS_FOR_CONTROLLER_SERVICES, tho it doesn't strictly belong in the scope of this change, so you decide
| constexpr auto system_allowed_types = std::to_array<std::string_view>({ | ||
| controllers::SSLContextServiceInterface::ProvidesApi.type, | ||
| core::RecordSetWriter::ProvidesApi.type, | ||
| core::RecordSetReader::ProvidesApi.type, | ||
| controllers::ProxyConfigurationServiceInterface::ProvidesApi.type, | ||
| controllers::AttributeProviderService::ProvidesApi.type}); | ||
| return ranges::contains(system_allowed_types, allowed_type); |
There was a problem hiding this comment.
I like the old version with inline comparisons better. No need to introduce an STL container and ranges when it doesn't have a benefit, and line patterns are easily readable, even if they are somewhat repetitive.
There was a problem hiding this comment.
I just noticed that @lordgamez suggested the change, so CC.
There was a problem hiding this comment.
It's not really what I suggested, but we discussed that the originally suggested improvement should be a separate PR. Until that is implemented the same issue persists that when any new system allowed type is introduced it needs to be manually inserted here which is not trivial to find and easily missed, does not really matter if it's inlined or extracted to a container. My original intent to alternatively extract the constants was to move them to a more accessible and discoverable place when introducing a new option, but there's not really a viable place for it now, so it can be reverted.
There was a problem hiding this comment.
ah okay. If it's a temporary solution, I don't insist on changing it, but I would still prefer the simpler version.
Co-authored-by: Márton Szász <szaszm@apache.org>
Thank you for submitting a contribution to Apache NiFi - MiNiFi C++.
In order to streamline the review of the contribution we ask you
to ensure the following steps have been taken:
For all changes:
Is there a JIRA ticket associated with this PR? Is it referenced
in the commit message?
Does your PR title start with MINIFICPP-XXXX where XXXX is the JIRA number you are trying to resolve? Pay particular attention to the hyphen "-" character.
Has your PR been rebased against the latest commit within the target branch (typically main)?
Is your initial contribution a single, squashed commit?
For code changes:
For documentation related changes:
Note:
Please ensure that once the PR is submitted, you check GitHub Actions CI results for build issues and submit an update to your PR as soon as possible.