Skip to content

Commit 3f19d56

Browse files
committed
MINIFICPP-2816 Add controller_service::api_implementations to C api
1 parent 1e0824e commit 3f19d56

14 files changed

Lines changed: 515 additions & 11 deletions

File tree

extension-framework/cpp-extension-lib/include/api/core/Resource.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,22 @@ void useControllerServiceClassDefinition(Fn&& fn) {
154154
const auto full_name = minifi::core::className<Class>();
155155

156156
std::vector<MinifiPropertyDefinition> class_properties = utils::toProperties(Class::Properties, string_vector_cache);
157+
std::vector<MinifiStringView> provided_interfaces;
158+
if constexpr (requires { Class::ProvidedInterfaces; }) {
159+
provided_interfaces.reserve(Class::ProvidedInterfaces.size());
160+
for (const auto& iface : Class::ProvidedInterfaces) {
161+
provided_interfaces.push_back(utils::minifiStringView(iface.name));
162+
}
163+
}
157164

158165
MinifiControllerServiceClassDefinition definition{.full_name = utils::minifiStringView(full_name),
159166
.description = utils::minifiStringView(Class::Description),
160167
.class_properties_count = gsl::narrow<uint32_t>(class_properties.size()),
161168
.class_properties_ptr = class_properties.data(),
162169

170+
.provided_interfaces_count = gsl::narrow<uint32_t>(provided_interfaces.size()),
171+
.provided_interfaces_ptr = provided_interfaces.data(),
172+
163173
.callbacks = MinifiControllerServiceCallbacks{
164174
.create = [](MinifiControllerServiceMetadata metadata) -> MINIFI_OWNED void* {
165175
try {
@@ -181,6 +191,20 @@ void useControllerServiceClassDefinition(Fn&& fn) {
181191
static_cast<Class*>(self)->disable();
182192
} catch (...) {}
183193
},
194+
.get_interface = [](void* self, MinifiStringView interface_name) -> void* {
195+
try {
196+
const std::string_view name_view{interface_name.data, interface_name.length};
197+
198+
if constexpr (requires { Class::ProvidedInterfaces; }) {
199+
for (const auto& iface : Class::ProvidedInterfaces) {
200+
if (iface.name == name_view) {
201+
return iface.cast(self);
202+
}
203+
}
204+
}
205+
return nullptr;
206+
} catch (...) { return nullptr; }
207+
}
184208
}};
185209

186210
fn(definition);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#pragma once
19+
20+
#include <cinttypes>
21+
22+
namespace org::apache::nifi::minifi::api_sandbox {
23+
class NumberOfLegsControllerApi {
24+
public:
25+
virtual ~NumberOfLegsControllerApi() = default;
26+
virtual uint8_t numberOfLegs() const = 0;
27+
};
28+
29+
class CanFlyControllerApi {
30+
public:
31+
virtual ~CanFlyControllerApi() = default;
32+
virtual bool canFly() const = 0;
33+
};
34+
35+
} // namespace org::apache::nifi::minifi::api_sandbox
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "AnimalControllerServices.h"
19+
20+
#include "api/utils/ProcessorConfigUtils.h"
21+
namespace org::apache::nifi::minifi::api_sandbox {
22+
23+
MinifiStatus DogController::enableImpl(api::core::ControllerServiceContext& ctx) {
24+
this->has_jetpack_ = ctx.getProperty(HasJetpack) | minifi::utils::andThen(parsing::parseBool) |
25+
minifi::utils::orThrow(fmt::format("Expected parsable bool from \"{}\"", HasJetpack.name));
26+
27+
return MINIFI_STATUS_SUCCESS;
28+
}
29+
30+
} // namespace org::apache::nifi::minifi::api_sandbox
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#pragma once
19+
20+
#include "AnimalControllerServiceApis.h"
21+
#include "api/core/ControllerServiceImpl.h"
22+
#include "api/utils/Export.h"
23+
#include "core/PropertyDefinitionBuilder.h"
24+
#include "minifi-cpp/core/ProvidedControllerServiceInterface.h"
25+
26+
namespace org::apache::nifi::minifi::api_sandbox {
27+
class DogController : public api::core::ControllerServiceImpl, public CanFlyControllerApi, public NumberOfLegsControllerApi {
28+
public:
29+
EXTENSIONAPI static constexpr const char* Description = "Test DogController";
30+
EXTENSIONAPI static constexpr auto HasJetpack = core::PropertyDefinitionBuilder<>::createProperty("Has Jetpack")
31+
.withDescription("Whether or not the dog has a jetpack")
32+
.withDefaultValue("false")
33+
.withValidator(core::StandardPropertyValidators::BOOLEAN_VALIDATOR)
34+
.build();
35+
36+
EXTENSIONAPI static constexpr auto Properties = std::to_array<core::PropertyReference>({
37+
HasJetpack,
38+
});
39+
EXTENSIONAPI static constexpr auto ProvidedInterfaces =
40+
std::to_array<core::ProvidedInterface>({core::createProvidedInterface<CanFlyControllerApi, DogController>(),
41+
core::createProvidedInterface<NumberOfLegsControllerApi, DogController>()});
42+
43+
using ControllerServiceImpl::ControllerServiceImpl;
44+
MinifiStatus enableImpl(api::core::ControllerServiceContext& ctx) override;
45+
46+
uint8_t numberOfLegs() const override { return 4; }
47+
bool canFly() const override { return has_jetpack_; }
48+
49+
private:
50+
bool has_jetpack_ = false;
51+
};
52+
53+
class DuckController : public api::core::ControllerServiceImpl, public CanFlyControllerApi, public NumberOfLegsControllerApi {
54+
public:
55+
EXTENSIONAPI static constexpr const char* Description = "Test DuckController";
56+
57+
EXTENSIONAPI static constexpr std::array<core::PropertyReference, 0> Properties = {};
58+
EXTENSIONAPI static constexpr auto ProvidedInterfaces =
59+
std::to_array<core::ProvidedInterface>({core::createProvidedInterface<CanFlyControllerApi, DuckController>(),
60+
core::createProvidedInterface<NumberOfLegsControllerApi, DuckController>()});
61+
using ControllerServiceImpl::ControllerServiceImpl;
62+
MinifiStatus enableImpl(api::core::ControllerServiceContext&) override { return MINIFI_STATUS_SUCCESS; }
63+
64+
uint8_t numberOfLegs() const override { return 2; }
65+
bool canFly() const override { return true; }
66+
};
67+
} // namespace org::apache::nifi::minifi::api_sandbox
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
#
19+
20+
if (NOT ENABLE_TEST_PROCESSORS)
21+
return()
22+
endif ()
23+
24+
include(${CMAKE_SOURCE_DIR}/extensions/ExtensionHeader.txt)
25+
file(GLOB SOURCES "*.cpp")
26+
27+
add_minifi_library(minifi-stable-api-sandbox SHARED ${SOURCES})
28+
29+
target_link_libraries(minifi-stable-api-sandbox minifi-cpp-extension-lib)
30+
31+
register_c_api_extension(minifi-stable-api-sandbox "Stable API Sandbox" SANDBOX-EXTENSION "Stable API Sandbox" "extensions/stable-api-sandbox/tests")
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "AnimalControllerServices.h"
19+
#include "ZooProcessor.h"
20+
#include "api/core/Resource.h"
21+
#include "api/utils/minifi-c-utils.h"
22+
23+
#define MKSOC(x) #x
24+
#define MAKESTRING(x) MKSOC(x) // NOLINT(cppcoreguidelines-macro-usage)
25+
26+
namespace minifi = org::apache::nifi::minifi;
27+
28+
CEXTENSIONAPI const uint32_t MinifiApiVersion = MINIFI_API_VERSION;
29+
30+
CEXTENSIONAPI void MinifiInitExtension(MinifiExtensionContext* extension_context) {
31+
const MinifiExtensionDefinition extension_definition{.name = minifi::api::utils::minifiStringView(MAKESTRING(EXTENSION_NAME)),
32+
.version = minifi::api::utils::minifiStringView(MAKESTRING(EXTENSION_VERSION)),
33+
.deinit = nullptr,
34+
.user_data = nullptr};
35+
auto* extension = MinifiRegisterExtension(extension_context, &extension_definition);
36+
minifi::api::core::registerProcessors<minifi::api_sandbox::ZooProcessor>(extension);
37+
minifi::api::core::registerControllerServices<minifi::api_sandbox::DogController, minifi::api_sandbox::DuckController>(extension);
38+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "ZooProcessor.h"
19+
20+
#include "AnimalControllerServices.h"
21+
#include "api/core/ProcessContext.h"
22+
23+
namespace org::apache::nifi::minifi::api_sandbox {
24+
25+
MinifiStatus ZooProcessor::onTriggerImpl(api::core::ProcessContext& process_context, api::core::ProcessSession&) {
26+
if (const auto can_fly_opaque = process_context.getControllerService(CanFlyService)) {
27+
if (*can_fly_opaque) {
28+
const auto can_fly_controller_name = process_context.getProperty(CanFlyService, nullptr) | utils::orThrow("Should be here");
29+
const CanFlyControllerApi* can_fly = reinterpret_cast<CanFlyControllerApi*>(*can_fly_opaque);
30+
logger_->log_critical("Can {} fly? {}", can_fly_controller_name, can_fly->canFly());
31+
}
32+
}
33+
if (const auto num_of_legs_opaque = process_context.getControllerService(NumberOfLegsService)) {
34+
if (*num_of_legs_opaque) {
35+
const auto num_of_legs_name = process_context.getProperty(NumberOfLegsService, nullptr) | utils::orThrow("Should be here");
36+
const NumberOfLegsControllerApi* num_legs = reinterpret_cast<NumberOfLegsControllerApi*>(*num_of_legs_opaque);
37+
logger_->log_critical("{} has {} legs", num_of_legs_name, num_legs->numberOfLegs());
38+
}
39+
}
40+
return MINIFI_STATUS_SUCCESS;
41+
}
42+
43+
MinifiStatus ZooProcessor::onScheduleImpl(api::core::ProcessContext& process_context) {
44+
return ProcessorImpl::onScheduleImpl(process_context);
45+
}
46+
} // namespace org::apache::nifi::minifi::api_sandbox
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#pragma once
19+
20+
#include "AnimalControllerServiceApis.h"
21+
#include "api/core/ProcessorImpl.h"
22+
#include "api/utils/Export.h"
23+
#include "core/PropertyDefinitionBuilder.h"
24+
#include "minifi-cpp/core/Annotation.h"
25+
26+
namespace org::apache::nifi::minifi::api_sandbox {
27+
28+
class ZooProcessor : public api::core::ProcessorImpl {
29+
public:
30+
EXTENSIONAPI static constexpr const char* Description = "Test ZooProcessor";
31+
32+
EXTENSIONAPI static constexpr auto CanFlyService = core::PropertyDefinitionBuilder<>::createProperty("Can fly service")
33+
.withDescription("Test CanFlyService")
34+
.isRequired(true)
35+
.withAllowedTypes<CanFlyControllerApi>()
36+
.build();
37+
38+
EXTENSIONAPI static constexpr auto NumberOfLegsService = core::PropertyDefinitionBuilder<>::createProperty("Number of legs service")
39+
.withDescription("Test NumberOfLegsService")
40+
.isRequired(true)
41+
.withAllowedTypes<NumberOfLegsControllerApi>()
42+
.build();
43+
44+
EXTENSIONAPI static constexpr auto Properties = std::to_array<core::PropertyReference>({
45+
CanFlyService,
46+
NumberOfLegsService,
47+
});
48+
EXTENSIONAPI static constexpr auto Success = core::RelationshipDefinition{"success", "success"};
49+
EXTENSIONAPI static constexpr auto Failure = core::RelationshipDefinition{"failure", "failure"};
50+
EXTENSIONAPI static constexpr auto Relationships = std::array{Success, Failure};
51+
EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false;
52+
EXTENSIONAPI static constexpr bool SupportsDynamicRelationships = false;
53+
EXTENSIONAPI static constexpr core::annotation::Input InputRequirement = core::annotation::Input::INPUT_FORBIDDEN;
54+
EXTENSIONAPI static constexpr bool IsSingleThreaded = true;
55+
56+
using ProcessorImpl::ProcessorImpl;
57+
58+
protected:
59+
MinifiStatus onTriggerImpl(api::core::ProcessContext&, api::core::ProcessSession&) override;
60+
MinifiStatus onScheduleImpl(api::core::ProcessContext&) override;
61+
};
62+
63+
} // namespace org::apache::nifi::minifi::api_sandbox
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
#
19+
20+
file(GLOB SOURCES "*.cpp")
21+
22+
SET(EXTENSIONS_TEST_COUNT 0)
23+
FOREACH (testfile ${SOURCES})
24+
get_filename_component(testfilename "${testfile}" NAME_WE)
25+
add_minifi_executable(${testfilename} "${testfile}")
26+
target_include_directories(${testfilename} BEFORE PRIVATE "${CMAKE_SOURCE_DIR}/libminifi/include")
27+
target_include_directories(${testfilename} BEFORE PRIVATE "${CMAKE_SOURCE_DIR}/extensions/stable-api-sandbox")
28+
createTests(${testfilename})
29+
target_link_libraries(${testfilename} Catch2WithMain)
30+
target_link_libraries(${testfilename} minifi-stable-api-sandbox)
31+
target_link_libraries(${testfilename} libminifi-c-unittest)
32+
33+
MATH(EXPR EXTENSIONS_TEST_COUNT "${EXTENSIONS_TEST_COUNT}+1")
34+
add_test(NAME ${testfilename} COMMAND ${testfilename} WORKING_DIRECTORY ${TEST_DIR})
35+
ENDFOREACH ()

0 commit comments

Comments
 (0)