Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ ThisBuild / organization := "app.softnetwork"

name := "scheduler"

ThisBuild / version := "0.8.0"
ThisBuild / version := "0.8-SNAPSHOT"

ThisBuild / scalaVersion := scala212

Expand Down
6 changes: 6 additions & 0 deletions common/src/main/protobuf/event/schedule.proto
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,13 @@ message ScheduleAddedEvent {
message ScheduleTriggeredEvent {
option (scalapb.message).extends = "ProtobufEvent";
option (scalapb.message).extends = "SchedulerEvent";
// Story 13.7 — AuditableEvent (resolves via the file-level import of
// app.softnetwork.persistence.message._). The event carries the correlation id for the scheduler's
// own journal/audit; the durable hop to the consumer is the id on `schedule` (model #9), since
// Scheduler2EntityProcessorStream forwards only evt.schedule.
option (scalapb.message).extends = "AuditableEvent";
required app.softnetwork.scheduler.model.Schedule schedule = 1;
optional string correlation_id = 2;
}

message ScheduleRemovedEvent {
Expand Down
6 changes: 6 additions & 0 deletions common/src/main/protobuf/model/schedule.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ message Schedule {
optional google.protobuf.Timestamp scheduledDate = 6 [(scalapb.field).type = "java.util.Date"];
optional google.protobuf.Timestamp lastTriggered = 7 [(scalapb.field).type = "java.util.Date"];
optional string cronTab = 8;
// Story 13.7 — cross-service correlation id. Set when the schedule is added (e.g. a license
// renewal scheduled at issuance carries the checkout's id); preserved through copy /
// withLastTriggered and onto ScheduleTriggeredEvent so the base consumer (which forwards only
// evt.schedule) reaches the triggered action with the originating id. ScalaPB → correlationId:
// Option[String] + withCorrelationId.
optional string correlation_id = 9;
}

// CronTab
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,11 @@ private[scheduler] trait SchedulerBehavior
.persist(
List(
ScheduleAddedEvent(updatedSchedule), // update schedule
// Story 13.7 — carry the correlation id onto the triggered event: the schedule
// (model #9) is the durable hop to the consumer; the event's own #2 field is for
// the scheduler's journal/audit.
ScheduleTriggeredEvent(updatedSchedule)
.copy(correlationId = updatedSchedule.correlationId)
)
)
.thenRun(_ => {
Expand Down
2 changes: 1 addition & 1 deletion project/Versions.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
object Versions {

val genericPersistence = "0.8.1"
val genericPersistence = "0.9-SNAPSHOT"

val scalatest = "3.2.16"
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,20 @@ class SchedulerHandlerSpec
case other => fail(other.getClass)
}
}
"preserve the correlation id through add and trigger (Story 13.7)" in {
val cid = "corr-13-7"
// a schedule carrying a cross-service correlation id (e.g. a license renewal scheduled at
// issuance) must keep it through add -> state -> trigger, so the base consumer (which forwards
// only evt.schedule) reaches the triggered action with the originating id.
val schedule = Schedule("p", "corr", "add", 1).withCorrelationId(cid)
this !? AddSchedule(schedule) assert {
case r: ScheduleAdded => assert(r.schedule.correlationId.contains(cid))
case other => fail(other.getClass)
}
this !? TriggerSchedule(schedule.persistenceId, schedule.entityId, schedule.key) assert {
case r: ScheduleTriggered => assert(r.schedule.correlationId.contains(cid))
case other => fail(other.getClass)
}
}
}
}
Loading