Copilot commented on code in PR #2205:
URL: https://github.com/apache/nifi-minifi-cpp/pull/2205#discussion_r3472950663
##########
extension-framework/cpp-extension-lib/src/core/logging/Logger.cpp:
##########
@@ -33,36 +33,22 @@ MinifiLogLevel toCLogLevel(minifi::core::logging::LOG_LEVEL
lvl) {
}
gsl_FailFast();
}
-
-minifi::core::logging::LOG_LEVEL toLogLevel(MinifiLogLevel level) {
- switch (level) {
- case MINIFI_LOG_LEVEL_TRACE: return minifi::core::logging::trace;
- case MINIFI_LOG_LEVEL_DEBUG: return minifi::core::logging::debug;
- case MINIFI_LOG_LEVEL_INFO: return minifi::core::logging::info;
- case MINIFI_LOG_LEVEL_WARNING: return minifi::core::logging::warn;
- case MINIFI_LOG_LEVEL_ERROR: return minifi::core::logging::err;
- case MINIFI_LOG_LEVEL_CRITICAL: return minifi::core::logging::critical;
- case MINIFI_LOG_LEVEL_OFF: return minifi::core::logging::off;
- }
- gsl_FailFast();
-}
-
} // namespace
-void CffiLogger::set_max_log_size(const int size) {
- MinifiLoggerSetMaxLogSize(impl_, size);
+void CffiLogger::set_max_log_size(const int) {
+ throw std::runtime_error("Unimplemented C Api");
}
Review Comment:
`CffiLogger::set_max_log_size()` currently throws unconditionally, which can
crash extensions that call `logger_->set_max_log_size(...)`. Even if the
underlying C API no longer supports it, this should be a safe no-op to preserve
runtime stability of extension code using the C++ API wrapper.
##########
extension-framework/cpp-extension-lib/src/core/ProcessContext.cpp:
##########
@@ -62,23 +58,20 @@ std::expected<MinifiControllerService*, std::error_code>
CffiProcessContext::get
std::map<std::string, std::string>
CffiProcessContext::getDynamicProperties(const FlowFile* flow_file) const {
std::map<std::string, std::string> result;
- MinifiProcessContextGetDynamicProperties(
+ minifi_process_context_get_dynamic_properties(
impl_,
- flow_file ? flow_file->get() : MINIFI_NULL,
- [](void* user_ctx, const MinifiStringView key, const MinifiStringView
value) {
+ flow_file ? flow_file->get() : nullptr,
+ [](void* user_ctx, const minifi_string_view key, const
minifi_string_view value) {
static_cast<std::map<std::string,
std::string>*>(user_ctx)->emplace(utils::toString(key), utils::toString(value));
},
&result);
return result;
}
std::expected<std::optional<utils::net::SslData>, std::error_code>
CffiProcessContext::getSslData(const minifi::core::PropertyReference& prop)
const {
- const auto controller_name = getProperty(prop, nullptr);
- if (!controller_name) { return std::nullopt; }
-
auto ssl_data = utils::net::SslData{};
- if (const auto status = MinifiProcessContextGetSslDataFromProperty(impl_,
utils::minifiStringView(prop.name), [](void* data, const MinifiSslData*
minifi_ssl_data) {
+ if (const auto status =
minifi_process_context_get_ssl_data_from_property(impl_,
utils::minifiStringView(prop.name), [](void* data, const minifi_ssl_data*
minifi_ssl_data) {
auto* my_ssl_data = static_cast<utils::net::SslData*>(data);
Review Comment:
`getSslData()` returns `std::expected<std::optional<SslData>, ...>`, but it
currently treats `MINIFI_STATUS_PROPERTY_NOT_SET` as an error. This breaks the
optional semantics and is inconsistent with
`getProxyData()`/`getControllerService()`, which map `PROPERTY_NOT_SET` to
`std::nullopt`/`nullptr`.
##########
extension-framework/cpp-extension-lib/src/core/logging/Logger.cpp:
##########
@@ -33,36 +33,22 @@ MinifiLogLevel toCLogLevel(minifi::core::logging::LOG_LEVEL
lvl) {
}
gsl_FailFast();
}
-
-minifi::core::logging::LOG_LEVEL toLogLevel(MinifiLogLevel level) {
- switch (level) {
- case MINIFI_LOG_LEVEL_TRACE: return minifi::core::logging::trace;
- case MINIFI_LOG_LEVEL_DEBUG: return minifi::core::logging::debug;
- case MINIFI_LOG_LEVEL_INFO: return minifi::core::logging::info;
- case MINIFI_LOG_LEVEL_WARNING: return minifi::core::logging::warn;
- case MINIFI_LOG_LEVEL_ERROR: return minifi::core::logging::err;
- case MINIFI_LOG_LEVEL_CRITICAL: return minifi::core::logging::critical;
- case MINIFI_LOG_LEVEL_OFF: return minifi::core::logging::off;
- }
- gsl_FailFast();
-}
-
} // namespace
-void CffiLogger::set_max_log_size(const int size) {
- MinifiLoggerSetMaxLogSize(impl_, size);
+void CffiLogger::set_max_log_size(const int) {
+ throw std::runtime_error("Unimplemented C Api");
}
void CffiLogger::log_string(const minifi::core::logging::LOG_LEVEL level,
const std::string str) {
- MinifiLoggerLogString(impl_, toCLogLevel(level), MinifiStringView{.data =
str.data(), .length = str.length()});
+ minifi_logger_log_string(impl_, toCLogLevel(level), minifi_string_view{.data
= str.data(), .length = str.length()});
}
bool CffiLogger::should_log(const minifi::core::logging::LOG_LEVEL level) {
- return MinifiLoggerShouldLog(impl_, toCLogLevel(level));
+ return minifi_logger_should_log(impl_, toCLogLevel(level));
}
[[nodiscard]] minifi::core::logging::LOG_LEVEL CffiLogger::level() const {
- return toLogLevel(MinifiLoggerLevel(impl_));
+ throw std::runtime_error("Unimplemented C API");
}
Review Comment:
`CffiLogger::level()` currently throws unconditionally, which can crash
extensions that query the logger level. This can be implemented without a
dedicated C API by probing `minifi_logger_should_log` (assuming monotonic level
thresholds).
##########
Extensions.md:
##########
@@ -21,33 +21,33 @@ Extensions are dynamic libraries loaded at runtime by the
agent.
## C extensions
You can build shared libraries using the API defined in `minifi-c.h`
-For the shared library to be considered a valid extension, it must export a
global symbol with the name `MinifiApiVersion`
+For the shared library to be considered a valid extension, it must export a
global symbol with the name `minifi_api_version`
with its value equal to the uint32_t constant `MINIFI_API_VERSION` from
`minifi-c.h`.
### Resource Lifetime
-Unless otherwise specified, the following lifetime rules apply to all
functions called by the agent (e.g., `MinifiInitExtension`,
`MinifiProcessorCallbacks::onTrigger`, or other callbacks):
+Unless otherwise specified, the following lifetime rules apply to all
functions called by the agent (e.g., `minifi_init_extension`,
`MinifiProcessorCallbacks::onTrigger`, or other callbacks):
Review Comment:
This sentence still references the old callback/type names (e.g.,
`MinifiProcessorCallbacks::onTrigger`). In this PR the C API callback
struct/fields were renamed (`minifi_processor_callbacks::trigger`, `schedule`,
`unschedule`), so the docs should match the new API surface.
##########
Extensions.md:
##########
@@ -21,33 +21,33 @@ Extensions are dynamic libraries loaded at runtime by the
agent.
## C extensions
You can build shared libraries using the API defined in `minifi-c.h`
-For the shared library to be considered a valid extension, it must export a
global symbol with the name `MinifiApiVersion`
+For the shared library to be considered a valid extension, it must export a
global symbol with the name `minifi_api_version`
with its value equal to the uint32_t constant `MINIFI_API_VERSION` from
`minifi-c.h`.
### Resource Lifetime
-Unless otherwise specified, the following lifetime rules apply to all
functions called by the agent (e.g., `MinifiInitExtension`,
`MinifiProcessorCallbacks::onTrigger`, or other callbacks):
+Unless otherwise specified, the following lifetime rules apply to all
functions called by the agent (e.g., `minifi_init_extension`,
`MinifiProcessorCallbacks::onTrigger`, or other callbacks):
* Arguments: The lifetime of any resource provided as a function argument is
limited to the duration of that function call.
* Created Resources: The lifetime of resources created within these functions
(e.g., a handle returned by `MinifiProcessSessionGet` inside
`MinifiProcessorCallbacks::onTrigger`)
is limited to the scope of the innermost callback.
-(the return value of `MinifiRegisterExtension` is only valid during the
execution of `MinifiInitExtension`).
+(the return value of `minifi_register_extension` is only valid during the
execution of `minifi_init_extension`).
-Because of these scoping rules, all processor and controller service
registrations must occur within the `MinifiInitExtension` call.
+Because of these scoping rules, all processor and controller service
registrations must occur within the `minifi_init_extension` call.
One possible example of this is:
```C++
-extern "C" const uint32_t MinifiApiVersion = MINIFI_API_VERSION;
+extern "C" const uint32_t minifi_api_version = MINIFI_API_VERSION;
-extern "C" void MinifiInitExtension(MinifiExtensionContext* extension_context)
{
+extern "C" void minifi_init_extension(MinifiExtensionContext*
extension_context) {
MinifiExtensionDefinition extension_definition{
.name = minifi::api::utils::toStringView(MAKESTRING(EXTENSION_NAME)),
.version = minifi::api::utils::toStringView(MAKESTRING(EXTENSION_VERSION)),
.deinit = nullptr,
Review Comment:
The C-extension example still uses the pre-rename types/functions
(`MinifiExtensionContext`, `MinifiExtensionDefinition`,
`MinifiProcessorClassDefinition`, `MinifiRegisterProcessor`). After the rename
to `minifi_*` these identifiers are no longer correct, so the example as
written won't compile against the new headers.
##########
libminifi/src/utils/CProcessor.cpp:
##########
@@ -20,11 +20,7 @@
namespace org::apache::nifi::minifi::utils {
std::vector<minifi::state::PublishedMetric> CProcessor::getCustomMetrics()
const {
- if (class_description_.callbacks.calculateMetrics == nullptr) {
- return {};
- }
- std::unique_ptr<std::vector<minifi::state::PublishedMetric>>
metrics{reinterpret_cast<std::vector<minifi::state::PublishedMetric>*>(class_description_.callbacks.calculateMetrics(impl_))};
- return *metrics;
+ return reported_metrics_;
}
Review Comment:
`getCustomMetrics()` returns `reported_metrics_` by value while
`reportMetrics()` can concurrently replace/move-assign that vector. Without
synchronization this is a data race and can lead to undefined behavior
(including crashes) under concurrent metrics polling.
##########
libminifi/include/utils/CProcessor.h:
##########
@@ -115,12 +115,16 @@ class CProcessor : public minifi::core::ProcessorApi {
}
bool getTriggerWhenEmpty() const override {
- return
static_cast<bool>(class_description_.callbacks.getTriggerWhenEmpty(impl_));
+ return trigger_when_empty_;
+ }
+
+ void setTriggerWhenEmpty(bool set_trigger_when_empty) override {
+ trigger_when_empty_ = set_trigger_when_empty;
}
Review Comment:
`reportMetrics()` updates `reported_metrics_` and `getCustomMetrics()` reads
it without any synchronization. Since metrics collection/reporting can run
concurrently with processor triggering, this introduces a data race (vector
read while another thread assigns/moves). Similarly, `trigger_when_empty_` is a
plain `bool` but is mutated via `setTriggerWhenEmpty()` and read via
`getTriggerWhenEmpty()`, which can also race.
##########
minifi-api/minifi-api.def:
##########
@@ -0,0 +1,33 @@
+LIBRARY core-minifi.dll
+EXPORTS
+ minifi_config_get
+ minifi_controller_service_context_get_property
+ minifi_input_stream_read
+ minifi_input_stream_size
+ minifi_logger_log_string
+ minifi_logger_should_log
+ minifi_output_stream_write
+ minifi_process_context_get_controller_service_from_property
+ minifi_process_context_get_dynamic_properties
+ minifi_process_context_get_property
+ minifi_process_context_get_proxy_data_from_property
+ minifi_process_context_get_ssl_data_from_property
+ minifi_process_context_has_non_empty_property
+ minifi_process_context_report_metrics
+ minifi_process_context_set_trigger_when_empty
+ minifi_process_session_create
+ minifi_process_session_get
+ minifi_process_session_get_flow_file_attribute
+ minifi_process_session_get_flow_file_attributes
+ minifi_process_session_get_flow_file_id
+ minifi_process_session_get_flow_file_size
+ minifi_process_session_penalize
+ minifi_process_session_read
+ minifi_process_session_remove
+ minifi_process_session_set_flow_file_attribute
+ minifi_process_session_transfer
+ minifi_process_session_write
+ minifi_published_metrics_create
Review Comment:
`minifi_published_metrics_create` is listed as an exported symbol, but there
is no declaration/definition for it in the new API (the old
`MinifiPublishedMetricsCreate`/metrics callback path was removed in favor of
`minifi_process_context_report_metrics`). Exporting a non-existent symbol will
break the Windows import lib / DLL export consistency.
##########
minifi-api/include/minifi-c/minifi-api.h:
##########
@@ -0,0 +1,313 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MINIFI_API_INCLUDE_MINIFI_C_MINIFI_API_H_
+#define MINIFI_API_INCLUDE_MINIFI_C_MINIFI_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+#if __STDC_VERSION__ < 202311l
+#include <stdbool.h>
+#endif // < C23
+
+#define MINIFI_PRIVATE_STRINGIFY_HELPER(X) #X
+#define MINIFI_PRIVATE_STRINGIFY(X) MINIFI_PRIVATE_STRINGIFY_HELPER(X)
+
+#define MINIFI_PRIVATE_JOIN_HELPER(X, Y) X##_##Y
+#define MINIFI_PRIVATE_JOIN(X, Y) MINIFI_PRIVATE_JOIN_HELPER(X, Y)
+
+#define MINIFI_OWNED
+#define MINIFI_NULLABLE
+
+#ifndef MINIFI_REGISTER_EXTENSION_FN
+#define MINIFI_REGISTER_EXTENSION_FN minifi_register_extension
+#endif
+
+/// To declare a processor property that expects an SSLContextService,
+/// use MINIFI_SSL_CONTEXT_SERVICE_PROPERTY_TYPE in the type field of the
property definition (minifi_property_definition::type)
+#define MINIFI_SSL_CONTEXT_SERVICE_PROPERTY_TYPE
"org.apache.nifi.minifi.controllers.SSLContextServiceInterface"
Review Comment:
This comment still references `minifi_property_definition::type`, but the
field was renamed to `allowed_type` in this PR. Keeping the old name makes the
header misleading for API consumers.
##########
Extensions.md:
##########
@@ -21,33 +21,33 @@ Extensions are dynamic libraries loaded at runtime by the
agent.
## C extensions
You can build shared libraries using the API defined in `minifi-c.h`
-For the shared library to be considered a valid extension, it must export a
global symbol with the name `MinifiApiVersion`
+For the shared library to be considered a valid extension, it must export a
global symbol with the name `minifi_api_version`
with its value equal to the uint32_t constant `MINIFI_API_VERSION` from
`minifi-c.h`.
Review Comment:
This section still refers to the old header name `minifi-c.h`, but the API
header was renamed to `minifi-api.h` in this PR. Keeping the old name makes the
docs inaccurate for extension authors.
##########
Extensions.md:
##########
@@ -73,10 +73,10 @@ REGISTER_RESOURCE(RESTSender, DescriptionOnly);
```
Some extensions (e.g. `Python`) require initialization before use.
-You need to define an `MinifiInitCppExtension` function of type
`MinifiExtension*(MinifiExtensionContext*)` to be called.
+You need to define an `minifi_init_cpp_extension` function of type
`MinifiExtension*(MinifiExtensionContext*)` to be called.
Review Comment:
This sentence documents `minifi_init_cpp_extension` as having type
`MinifiExtension*(MinifiExtensionContext*)`, but the extensions in this PR
implement it as `void minifi_init_cpp_extension(minifi_extension_context*)`
(and the C API types were renamed). The documentation should reflect the actual
required signature.
##########
minifi-api/include/minifi-c/minifi-api.h:
##########
@@ -0,0 +1,313 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MINIFI_API_INCLUDE_MINIFI_C_MINIFI_API_H_
+#define MINIFI_API_INCLUDE_MINIFI_C_MINIFI_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+#if __STDC_VERSION__ < 202311l
+#include <stdbool.h>
+#endif // < C23
+
+#define MINIFI_PRIVATE_STRINGIFY_HELPER(X) #X
+#define MINIFI_PRIVATE_STRINGIFY(X) MINIFI_PRIVATE_STRINGIFY_HELPER(X)
+
+#define MINIFI_PRIVATE_JOIN_HELPER(X, Y) X##_##Y
+#define MINIFI_PRIVATE_JOIN(X, Y) MINIFI_PRIVATE_JOIN_HELPER(X, Y)
+
+#define MINIFI_OWNED
+#define MINIFI_NULLABLE
+
+#ifndef MINIFI_REGISTER_EXTENSION_FN
+#define MINIFI_REGISTER_EXTENSION_FN minifi_register_extension
+#endif
+
+/// To declare a processor property that expects an SSLContextService,
+/// use MINIFI_SSL_CONTEXT_SERVICE_PROPERTY_TYPE in the type field of the
property definition (minifi_property_definition::type)
+#define MINIFI_SSL_CONTEXT_SERVICE_PROPERTY_TYPE
"org.apache.nifi.minifi.controllers.SSLContextServiceInterface"
+
+/// To declare a processor property that expects an ProxyConfigurationService,
+/// use MINIFI_PROXY_CONFIGURATION_SERVICE_PROPERTY_TYPE in the type field of
the property definition (minifi_property_definition::type)
+#define MINIFI_PROXY_CONFIGURATION_SERVICE_PROPERTY_TYPE
"org.apache.nifi.minifi.controllers.ProxyConfigurationServiceInterface"
+
+enum : uint32_t {
+ MINIFI_API_VERSION = 1
+};
+
+enum minifi_io_status : int64_t {
+ MINIFI_IO_ERROR = -1,
+ MINIFI_IO_CANCEL = -125
+};
+
+enum minifi_input_requirement : uint32_t {
+ MINIFI_INPUT_REQUIRED = 0,
+ MINIFI_INPUT_ALLOWED = 1,
+ MINIFI_INPUT_FORBIDDEN = 2
+};
+
+/// Represents a non-owning read-only view to a sized, not necessarily
null-terminated string.
+/// invariant: [data, data + length) is a valid range
+struct minifi_string_view {
+ /// nullable, non-owning pointer to the beginning of a continuous character
sequence
+ const char* data;
+ /// the length of the buffer pointed-to by data
+ size_t length;
+};
+
+/// Represents an output relationship of a processor, part of the processor
metadata
+struct minifi_relationship_definition {
+ /// Name, processors use this to transfer flow files to the connections
connected to this relationship using MinifiProcessSessionTransfer.
+ struct minifi_string_view name;
+ /// Human-readable description of what flow files get routed to this
relationship. Included in C2 manifest and generated processor docs.
+ struct minifi_string_view description;
+};
+
+struct minifi_output_attribute_definition {
+ struct minifi_string_view name;
+ size_t relationships_count;
+ const struct minifi_string_view* relationships_ptr;
+ struct minifi_string_view description;
+};
+
+/// Describes what the dynamic properties can be used for
+struct minifi_dynamic_property_definition {
+ struct minifi_string_view name;
+ struct minifi_string_view value;
+ struct minifi_string_view description;
+ bool supports_expression_language;
+};
+
+struct minifi_flow_file;
+struct minifi_logger;
+struct minifi_process_context;
+struct minifi_process_session;
+struct minifi_controller_service;
+struct minifi_controller_service_context;
+struct minifi_input_stream;
+struct minifi_output_stream;
+struct minifi_extension;
+struct minifi_extension_context;
+
+enum minifi_status : uint32_t {
+ MINIFI_STATUS_SUCCESS = 0,
+ MINIFI_STATUS_UNKNOWN_ERROR = 1,
+ MINIFI_STATUS_NOT_SUPPORTED_PROPERTY = 2,
+ MINIFI_STATUS_DYNAMIC_PROPERTIES_NOT_SUPPORTED = 3,
+ MINIFI_STATUS_PROPERTY_NOT_SET = 4,
+ MINIFI_STATUS_VALIDATION_FAILED = 5,
+ MINIFI_STATUS_PROCESSOR_YIELD = 6,
+};
+
+enum minifi_validator : uint32_t {
+ MINIFI_VALIDATOR_ALWAYS_VALID = 0,
+ MINIFI_VALIDATOR_NON_BLANK = 1,
+ MINIFI_VALIDATOR_TIME_PERIOD = 2,
+ MINIFI_VALIDATOR_BOOLEAN = 3,
+ MINIFI_VALIDATOR_INTEGER = 4,
+ MINIFI_VALIDATOR_UNSIGNED_INTEGER = 5,
+ MINIFI_VALIDATOR_DATA_SIZE = 6,
+ MINIFI_VALIDATOR_PORT = 7,
+};
+
+struct minifi_property_definition {
+ struct minifi_string_view name;
+ struct minifi_string_view display_name;
+ struct minifi_string_view description;
+ bool is_required;
+ bool is_sensitive;
+
+ const struct minifi_string_view* default_value;
+ size_t allowed_values_count;
+ const struct minifi_string_view* allowed_values_ptr;
+ enum minifi_validator validator;
+
+ const struct minifi_string_view* allowed_type;
+ bool supports_expression_language;
+};
+
+enum minifi_log_level : uint32_t {
+ MINIFI_LOG_LEVEL_TRACE = 0,
+ MINIFI_LOG_LEVEL_DEBUG = 1,
+ MINIFI_LOG_LEVEL_INFO = 2,
+ MINIFI_LOG_LEVEL_WARNING = 3,
+ MINIFI_LOG_LEVEL_ERROR = 4,
+ MINIFI_LOG_LEVEL_CRITICAL = 5,
+ MINIFI_LOG_LEVEL_OFF = 6
+};
+
+struct minifi_processor_metadata {
+ struct minifi_string_view uuid;
+ struct minifi_string_view name;
+ struct minifi_logger* logger; // borrowed non-null reference, live until
the processor is live
+};
+
+struct minifi_controller_service_metadata {
+ struct minifi_string_view uuid;
+ struct minifi_string_view name;
+ struct minifi_logger* logger; // borrowed non-null reference, live until
the controller service is live
+};
+
+struct minifi_processor_callbacks {
+ MINIFI_OWNED void* (*create)(struct minifi_processor_metadata);
+ void (*destroy)(MINIFI_OWNED void*);
+ enum minifi_status (*trigger)(void*, struct minifi_process_context*, struct
minifi_process_session*);
+ enum minifi_status (*schedule)(void*, struct minifi_process_context*);
+ void (*unschedule)(void*);
+};
+
+struct minifi_controller_service_callbacks {
+ MINIFI_OWNED void* (*create)(struct minifi_controller_service_metadata);
+ void (*destroy)(MINIFI_OWNED void*);
+ enum minifi_status (*enable)(void*, struct
minifi_controller_service_context*);
+ void (*disable)(void*);
+ void* (*get_interface)(void* ctx, struct minifi_string_view interface_type);
+};
+
+struct minifi_processor_class_definition {
+ struct minifi_string_view full_name; // '::'-delimited fully qualified name
e.g. 'org::apache::nifi::minifi::GenerateFlowFile'
+ struct minifi_string_view description;
+ size_t properties_count;
+ const struct minifi_property_definition* properties_ptr;
+ size_t dynamic_properties_count;
+ const struct minifi_dynamic_property_definition* dynamic_properties_ptr;
+ size_t relationships_count;
+ const struct minifi_relationship_definition* relationships_ptr;
+ size_t output_attributes_count;
+ const struct minifi_output_attribute_definition* output_attributes_ptr;
+ bool supports_dynamic_properties;
+ bool supports_dynamic_relationships;
+ enum minifi_input_requirement input_requirement;
+ bool is_single_threaded;
+
+ struct minifi_processor_callbacks callbacks;
+};
+
+struct minifi_controller_service_class_definition {
+ struct minifi_string_view full_name; // '::'-delimited fully qualified name
e.g.
'org::apache::nifi::minifi::extensions::gcp::GCPCredentialsControllerService
+ struct minifi_string_view description;
+ size_t properties_count;
+ const struct minifi_property_definition* properties_ptr;
+ size_t provided_interfaces_count;
+ const struct minifi_string_view* provided_interfaces_ptr;
+
+ struct minifi_controller_service_callbacks callbacks;
+};
+
+struct minifi_extension_definition {
+ struct minifi_string_view name;
+ struct minifi_string_view version;
+ void (*deinit)(void* user_data);
+ void* user_data;
+};
+
+// When directly linking against the agent library (legacy c++ extension)
this declares a build identifier dependent function
+// which prevents loading extensions from different builds (e.g. the agent
provides MinifiRegisterCppExtension_123 but the extension
+// expects MinifiRegisterCppExtension_567). Otherwise, it declares
minifi_register_extension.
+struct minifi_extension* MINIFI_REGISTER_EXTENSION_FN(struct
minifi_extension_context* extension_context,
+ const struct minifi_extension_definition* extension_definition);
+
+enum minifi_status minifi_register_processor(struct minifi_extension*
extension, const struct minifi_processor_class_definition* processor);
+enum minifi_status minifi_register_controller_service(struct minifi_extension*
extension,
+ const struct minifi_controller_service_class_definition*
controller_service);
+
+enum minifi_status minifi_process_context_set_trigger_when_empty(struct
minifi_process_context*, bool);
+enum minifi_status minifi_process_context_report_metrics(struct
minifi_process_context*, size_t count, const struct minifi_string_view*
metric_names,
+ const double* metric_values);
+
+enum minifi_status minifi_process_context_get_property(struct
minifi_process_context* context, struct minifi_string_view property_name,
+ MINIFI_NULLABLE struct minifi_flow_file* flowfile, void (*cb)(void*
user_ctx, struct minifi_string_view property_value), void* user_ctx);
+
Review Comment:
`minifi_process_context_has_non_empty_property` is exported (see
`minifi-api.def`) and implemented in `libminifi/src/minifi-api.cpp`, but it is
not declared in this public header. That makes it unusable for C API consumers
and risks implicit-declaration errors in C builds.
##########
minifi-api/include/minifi-c/minifi-api.h:
##########
@@ -0,0 +1,313 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MINIFI_API_INCLUDE_MINIFI_C_MINIFI_API_H_
+#define MINIFI_API_INCLUDE_MINIFI_C_MINIFI_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+#if __STDC_VERSION__ < 202311l
+#include <stdbool.h>
+#endif // < C23
+
+#define MINIFI_PRIVATE_STRINGIFY_HELPER(X) #X
+#define MINIFI_PRIVATE_STRINGIFY(X) MINIFI_PRIVATE_STRINGIFY_HELPER(X)
+
+#define MINIFI_PRIVATE_JOIN_HELPER(X, Y) X##_##Y
+#define MINIFI_PRIVATE_JOIN(X, Y) MINIFI_PRIVATE_JOIN_HELPER(X, Y)
+
+#define MINIFI_OWNED
+#define MINIFI_NULLABLE
+
+#ifndef MINIFI_REGISTER_EXTENSION_FN
+#define MINIFI_REGISTER_EXTENSION_FN minifi_register_extension
+#endif
+
+/// To declare a processor property that expects an SSLContextService,
+/// use MINIFI_SSL_CONTEXT_SERVICE_PROPERTY_TYPE in the type field of the
property definition (minifi_property_definition::type)
+#define MINIFI_SSL_CONTEXT_SERVICE_PROPERTY_TYPE
"org.apache.nifi.minifi.controllers.SSLContextServiceInterface"
+
+/// To declare a processor property that expects an ProxyConfigurationService,
+/// use MINIFI_PROXY_CONFIGURATION_SERVICE_PROPERTY_TYPE in the type field of
the property definition (minifi_property_definition::type)
+#define MINIFI_PROXY_CONFIGURATION_SERVICE_PROPERTY_TYPE
"org.apache.nifi.minifi.controllers.ProxyConfigurationServiceInterface"
Review Comment:
This comment still references `minifi_property_definition::type`, but the
field was renamed to `allowed_type` in this PR. The docs should point users to
`minifi_property_definition::allowed_type`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]