Skip to content

feat(history): migrate C7 async-before/after job logs to C8#1018

Draft
Copilot wants to merge 7 commits intomainfrom
copilot/migrate-async-jobs-history
Draft

feat(history): migrate C7 async-before/after job logs to C8#1018
Copilot wants to merge 7 commits intomainfrom
copilot/migrate-async-jobs-history

Conversation

Copy link
Contributor

Copilot AI commented Feb 19, 2026

Migrates Camunda 7 HistoricJobLog entries (async-before/after continuations) to C8 JobDbModel, and wires the resulting C8 job key into failedJob incidents.

Core Design

  • Tracking key = C7 job ID (not log entry ID): multiple HistoricJobLog entries per job are deduplicated — only the first log entry encountered creates a C8 job record.
  • Migration order: migrateJobs() runs before migrateIncidents() so the C8 job key is available for FK resolution.
  • Incident FK: for failedJob incidents, IncidentMigrator.resolveJobKey() looks up the C8 job key from the HISTORY_JOB tracking table. If the job was explicitly skipped (null c8Key), the incident is skipped too (SKIP_REASON_MISSING_JOB_REFERENCE).

Changes

New production code:

  • JobMigrator — batch migrates HistoricJobLog entries; deduplicates by getJobId()
  • JobTransformerEntityInterceptor<HistoricJobLog, JobDbModel.Builder> mapping state, retries, error message, deadline, timing, tenant, partition, element ID
  • C7ClientfetchAndHandleHistoricJobLogs() (batch) + getHistoricJobLog(jobId) (retry mode)
  • C8Client.insertJob() via existing JobMapper
  • C7Entity.of(HistoricJobLog) using getJobId() as tracking key
  • EntitySkippedException(HistoricJobLog, msg) constructor
  • IncidentMigrator.resolveJobKey() + isFailedJobIncident()

Updated:

  • HistoryMigrator.migrate() — adds migrateJobs() step
  • IdKeyMapper.TYPE.HISTORY_JOBHistoricJobLogEventEntity.class
  • HistoryMigratorLogsSKIP_REASON_MISSING_JOB_REFERENCE, logMigratingJob()

Tests:

  • HistoryJobTest — 3 integration tests: async-before migration, incident FK population, deduplication by job ID
  • Enabled shouldNotMigrateIncidentsWhenJobIsSkipped (was @Disabled; fixed tracking type from HISTORY_FLOW_NODEHISTORY_JOB, fixed job execution to 3× to trigger incident)
  • asyncBeforeUserTaskProcess.bpmn — test resource for successfully-completing async-before job

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Test-only changes (no production code changes)

Testing Checklist

Black-Box Testing Requirements

  • Tests follow black-box testing approach: verify behavior through observable outputs (logs, C8 API queries, real-world skip scenarios)
  • Tests DO NOT access implementation details (DbClient, IdKeyMapper, ..impl.. packages except logging constants)
  • Architecture tests pass (ArchitectureTest validates these rules)

Test Coverage

  • Added tests for new functionality
  • Updated tests for modified functionality
  • All tests pass locally

Architecture Compliance

Run architecture tests to ensure compliance:

mvn test -Dtest=ArchitectureTest

If architecture tests fail, refactor your tests to use:

  • LogCapturer for log assertions
  • camundaClient.new*SearchRequest() for C8 queries
  • Real-World skip scenarios (e.g., migrate children without parents)

Documentation

  • Updated TESTING_GUIDELINES.md if adding new test patterns
  • Added Javadoc comments for public APIs
  • Updated README if user-facing changes

Checklist

  • Code follows project style guidelines
  • Self-reviewed the code
  • Added comments for complex logic
  • No new compiler warnings
  • Dependent changes have been merged

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • artifacts.camunda.com
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 (dns block)
  • docs.camunda.org
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (dns block)
  • repository.sonatype.org
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --enable-native-access=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED -classpath /usr/share/apache-maven-3.9.12/boot/plexus-classworlds-2.9.0.jar -Dclassworlds.conf=/usr/share/apache-maven-3.9.12/bin/m2.conf -Dmaven.home=/usr/share/apache-maven-3.9.12 (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>(Optional) In Data Migrator History, async-before/after jobs are migrated</issue_title>
<issue_description>### User Story (Required on creation)

  • As a process engineer, I want to be migrate C7 async-before/after jobs history to C8 so that I can maintain a complete audit trail for compliance purposes.

Functional Requirements (Required before implementation)

Technical Requirements (Required before implementation)

  • Plan: Migrate the async-before/async-after job logs per BPMN element
  • Create new mapping (HistoricJobLog (C7) -> JobDbModel (C8)) and add minimal test coverage
    • Create JobMigrator, JobTransformer
  • FK constrain, populate jobKey in Incident - skip incident if the job is not migrated
  • Populate jobKey, type, worker, state, kind, listenerEventType, retries, hasFailedWithRetriesLeft, errorMessage, deadline, endTime, processDefinitionId, processDefinitionKey, processInstanceKey, elementId, elementInstanceKey, tenantId, partitionId
  • Document limitations

Limitations of Scope

Hints

This come up during PR review, comment: #150 (comment)

Links

Breakdown

Pull Requests

Dev2QA handover

  • Does this ticket need a QA test and the testing goals are not clear from the description? Add a Dev2QA handover comment</issue_description>

Comments on the Issue (you are @copilot in this section)

@tasso94 C7 Jobs don't map 1:1 to C8 Jobs. Let's explore this further and decide what C7 job types might be useful to migrate.

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Copilot AI changed the title [WIP] Migrate async-before/after job logs to C8 feat(history): migrate C7 async-before/after job logs to C8 Feb 19, 2026
Copilot AI requested a review from yanavasileva February 19, 2026 15:15
Copilot AI and others added 3 commits February 26, 2026 14:42
feat(history): migrate async-before/after job logs from C7 to C8

related to #5331

- Add HISTORY_JOB type to IdKeyMapper.TYPE with HistoricJobLogEventEntity class mapping
- Create JobMigrator: migrates C7 HistoricJobLog entries tracked by job ID (deduplicates multiple log entries per job)
- Create JobTransformer: EntityInterceptor mapping C7 job log fields to C8 JobDbModel (state, retries, error, timing, etc.)
- Add fetchAndHandleHistoricJobLogs() and getHistoricJobLog() to C7Client
- Add insertJob() to C8Client
- Add of(HistoricJobLog) factory method to C7Entity using getJobId() as tracking key
- Add HistoricJobLog constructor to EntitySkippedException
- Update IncidentMigrator: resolve jobKey for failedJob incidents from HISTORY_JOB tracking table; skip incident if the referenced job was explicitly skipped
- Update HistoryMigrator: call migrateJobs() before migrateIncidents()
- Enable previously-disabled test shouldNotMigrateIncidentsWhenJobIsSkipped (changed HISTORY_FLOW_NODE to HISTORY_JOB)
- Add HistoryJobTest integration tests covering deduplication and incident FK population
- Add asyncBeforeUserTaskProcess.bpmn for testing successfully-completed async-before jobs

Co-authored-by: yanavasileva <26868499+yanavasileva@users.noreply.github.com>

fix(history): update IncidentMigrator Javadoc to reflect job key validation

Co-authored-by: yanavasileva <26868499+yanavasileva@users.noreply.github.com>
@yanavasileva yanavasileva force-pushed the copilot/migrate-async-jobs-history branch from 1f91dec to 2daf6cf Compare February 26, 2026 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(Optional) In Data Migrator History, async-before/after jobs are migrated

2 participants