MINIFICPP-2845 - Monotonic provenance event identifiers, iterations support, refactor - #2209
MINIFICPP-2845 - Monotonic provenance event identifiers, iterations support, refactor#2209adamdebreceni wants to merge 4 commits into
Conversation
| class SchedulingAgent { | ||
| public: | ||
| SchedulingAgent(const gsl::not_null<core::controller::ControllerServiceProvider*> controller_service_provider, std::shared_ptr<core::Repository> repo, std::shared_ptr<core::Repository> flow_repo, | ||
| SchedulingAgent(const gsl::not_null<core::controller::ControllerServiceProvider*> controller_service_provider, std::shared_ptr<provenance::ProvenanceRepository> repo, std::shared_ptr<core::Repository> flow_repo, |
There was a problem hiding this comment.
I believe the "repo" naming of identifiers that have to be provenance repo was a mistake. I'm glad the type makes it clearer now, but I'd change the parameter and member names too. provenance_repo or prov_repo seem like good options to me.
| Identifier& operator++(); | ||
| Identifier operator++(int); | ||
|
|
There was a problem hiding this comment.
why do we need these UUID increments? I believe the Identified class is not meant to represent integer auto-increment keys.
There was a problem hiding this comment.
currently the RocksDbProvenanceRepository uses the event_uuid for key, we could either bring back the retired SequentialIdGenerator, we could replace the increment operators with a next() method to not cause confusion, or we could use an uint64_t (event ordinal) as key, which one do you prefer?
a5b3ee2 to
af3f98a
Compare
7797653 to
82815c6
Compare
af3f98a to
f1b2dcd
Compare
There was a problem hiding this comment.
Pull request overview
Introduces a dedicated provenance repository API with monotonic event identifiers and cursor-based reporting.
Changes:
- Adds provenance-specific append and iteration APIs.
- Implements persistent monotonic identifiers in RocksDB.
- Refactors reporting, runtime wiring, and tests to use the new API.
Reviewed changes
Copilot reviewed 43 out of 43 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
minifi-api/include/minifi-cpp/provenance/ProvenanceRepository.h |
Adds provenance repository interface. |
minifi-api/include/minifi-cpp/provenance/Provenance.h |
Adds event ordinals and vector-backed reporting. |
minifi-api/include/minifi-cpp/core/Repository.h |
Removes generic provenance operations. |
minifi-api/include/minifi-cpp/core/ProcessContext.h |
Returns typed provenance repositories. |
minifi-api/common/include/minifi-cpp/utils/Id.h |
Declares identifier increment operators. |
minifi_main/MiNiFiMain.cpp |
Casts configured repository to the provenance API. |
libminifi/test/unit/SchedulingAgentTests.cpp |
Updates test repository typing. |
libminifi/test/persistence-tests/PersistenceTests.cpp |
Updates persistence fixtures. |
libminifi/test/libtest/unit/TestControllerWithFlow.cpp |
Updates test flow setup. |
libminifi/test/libtest/unit/TestBase.h |
Updates test plan provenance types. |
libminifi/test/libtest/unit/TestBase.cpp |
Implements updated test plan API. |
libminifi/test/libtest/unit/ProvenanceTestHelper.h |
Implements test provenance repository operations. |
libminifi/test/libtest/integration/IntegrationBase.cpp |
Updates integration repository setup. |
libminifi/test/integration/ControllerServiceIntegrationTests.cpp |
Updates repository inference. |
libminifi/test/integration/C2PauseResumeTest.cpp |
Updates repository inference. |
libminifi/test/flow-tests/SessionTests.cpp |
Casts the no-op repository. |
libminifi/src/provenance/Provenance.cpp |
Uses batched provenance appends. |
libminifi/src/FlowController.cpp |
Accepts the typed repository. |
libminifi/src/core/reporting/SiteToSiteProvenanceReportingTask.cpp |
Adds cursor-based reporting and ordinals. |
libminifi/src/core/ProcessContextImpl.cpp |
Stores the typed repository. |
libminifi/src/core/flow/StructuredConfiguration.cpp |
Assigns reporting-task UUIDs. |
libminifi/include/TimerDrivenSchedulingAgent.h |
Updates repository type. |
libminifi/include/ThreadedSchedulingAgent.h |
Updates repository type. |
libminifi/include/SchedulingAgent.h |
Stores the typed repository. |
libminifi/include/provenance/Provenance.h |
Implements ordinals and vector-backed events. |
libminifi/include/FlowController.h |
Exposes the typed repository. |
libminifi/include/EventDrivenSchedulingAgent.h |
Updates repository type. |
libminifi/include/CronDrivenSchedulingAgent.h |
Updates repository type. |
libminifi/include/core/repository/VolatileProvenanceRepository.h |
Implements volatile event appends. |
libminifi/include/core/repository/NoOpThreadedRepository.h |
Implements no-op provenance operations. |
libminifi/include/core/reporting/SiteToSiteProvenanceReportingTask.h |
Uses typed event records. |
libminifi/include/core/ProcessContextImpl.h |
Updates context repository types. |
extensions/standard-processors/tests/unit/ProcessorTests.cpp |
Adapts reporting tests to getEvents. |
extensions/standard-processors/tests/integration/VerifyInvokeHTTP.h |
Updates test repository inference. |
extensions/rocksdb-repos/tests/RepoTests.cpp |
Uses renamed RocksDB repository. |
extensions/rocksdb-repos/tests/ProvenanceTests.cpp |
Tests the append API. |
extensions/rocksdb-repos/tests/DBProvenanceRepositoryTests.cpp |
Adds cursor and monotonicity tests. |
extensions/rocksdb-repos/RocksDbProvenanceRepository.h |
Defines the renamed RocksDB implementation. |
extensions/rocksdb-repos/RocksDbProvenanceRepository.cpp |
Implements counters, cursors, and iteration. |
extensions/rocksdb-repos/ProvenanceRepository.cpp |
Removes the previous implementation. |
core-framework/src/core/Repository.cpp |
Removes generic element storage. |
core-framework/include/core/Repository.h |
Removes generic provenance defaults. |
core-framework/common/src/utils/Id.cpp |
Implements identifier incrementing. |
Suppressed comments (4)
extensions/rocksdb-repos/RocksDbProvenanceRepository.cpp:131
- A persisted cursor is expected to be parsed so the reporting task can fall back when it is invalid, but every string is currently accepted. A malformed/high-valued state such as
zzzzwill seek past every UUID and make provenance reporting return no records forever; validate it as anIdentifierand returnnullptron failure.
std::unique_ptr<ProvenanceRepository::Cursor> RocksDbProvenanceRepository::cursorFromString(std::optional<std::string> cursor_str) {
if (cursor_str.has_value()) {
return std::make_unique<EventCursor>(cursor_str.value());
}
return std::make_unique<EventCursor>("");
}
extensions/rocksdb-repos/RocksDbProvenanceRepository.cpp:174
- The iterator status is never checked after traversal, so a RocksDB read error is returned as a successful partial result and the reporting task can persist its cursor. Check
it->status()before updating the cursor and returnstd::unexpectedon failure, consistent withRocksDbStateStorageiteration.
if (event_cursor) {
event_cursor->event_id_ = last_event_id;
}
return records;
libminifi/src/core/reporting/SiteToSiteProvenanceReportingTask.cpp:224
- A
falsereturn fromtransmitPayloadonly yields and then reaches this cursor update, marking records as consumed even though they were not transmitted. Return from the trigger on the false path, just as the exception path does, so the same cursor batch is retried.
if (cursor) {
// no need to delete just update the state
std::unordered_map<std::string, std::string> state_map;
state_map["cursor"] = cursor->toString();
if (!state_manager->set(state_map)) {
extensions/rocksdb-repos/RocksDbProvenanceRepository.cpp:169
- Failed deserialization is silently skipped while
last_event_idstill advances. Once a later valid record is returned, the reporting task persists that advanced cursor, permanently losing the malformed record from the reporting stream. Return an error instead of advancing past an event that could not be decoded.
if (eventRead->deserialize(stream)) {
records.push_back(eventRead);
if (--max_size == 0) {
break;
}
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| MultiPut(data); | ||
|
|
||
| return {}; |
| if (open_state_db->Get(options, NEXT_EVENT_UUID_KEY, &next_event_uuid_str).ok()) { | ||
| next_event_id_ = next_event_uuid_str; | ||
| } else { | ||
| logger_->log_error("Could not find '{}'", NEXT_EVENT_UUID_KEY); | ||
| next_event_id_ = utils::IdGenerator::getIdGenerator()->generate(); |
| if (auto event_ordinal = record->getEventOrdinal()) { | ||
| recordJson.AddMember("eventOrdinal", event_ordinal.value(), alloc); | ||
| } |
Co-authored-by: Márton Szász <szaszm@apache.org>
f1b2dcd to
d6fac89
Compare
Depends on #2195
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.