Skip to content

Commit 41b4ab9

Browse files
rodrigogdeamosaic-rodrigo-gomez
authored andcommitted
Adding created timestamp and updated for crud plugin.
1 parent 66b2f56 commit 41b4ab9

File tree

7 files changed

+52
-42
lines changed

7 files changed

+52
-42
lines changed

Diff for: build.sbt

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
lazy val scala213 = "2.13.6"
1+
lazy val scala213 = "2.13.11"
22
lazy val scala300 = "3.0.0"
33
lazy val supportedScalaVersions = List(scala213)
4-
lazy val akkaVersion = "2.6.17"
5-
lazy val rxmongoVersion = "1.0.7"
4+
lazy val akkaVersion = "2.6.20"
5+
lazy val rxmongoVersion = "1.0.10"
66

77
publishArtifact := false
88
publish := {}
@@ -11,13 +11,14 @@ publishLocal := {}
1111
lazy val commonSettings = Seq(
1212
name := "akka-reactivemongo-plugin",
1313
organization := "null-vector",
14-
version := s"1.6.0",
14+
version := s"1.6.2",
1515
scalaVersion := scala213,
1616
crossScalaVersions := supportedScalaVersions,
1717
scalacOptions := Seq(
18+
"-Xsource:3",
1819
"-encoding",
1920
"UTF-8",
20-
"-target:12",
21+
"-release:17",
2122
"-deprecation",
2223
"-language:experimental.macros",
2324
// "-Ymacro-annotations",
@@ -55,7 +56,6 @@ lazy val commonSettings = Seq(
5556
).mkString(";"),
5657
Test / fork := true,
5758
Test / javaOptions += "-Xmx4G",
58-
Test / javaOptions += "-XX:+CMSClassUnloadingEnabled",
5959
Test / javaOptions += "-Dfile.encoding=UTF-8"
6060
)
6161

@@ -65,9 +65,9 @@ lazy val core = (project in file("core"))
6565
commonSettings,
6666
publishTo := Some(
6767
"nullvector" at (if (isSnapshot.value)
68-
"https://nullvector.jfrog.io/artifactory/snapshots"
68+
"https://nullvectormirror.jfrog.io/artifactory/libs-snapshots"
6969
else
70-
"https://nullvector.jfrog.io/artifactory/releases")
70+
"https://nullvectormirror.jfrog.io/artifactory/libs-release")
7171
),
7272
credentials += Credentials(Path.userHome / ".jfrog" / "credentials"),
7373
Compile / packageDoc / publishArtifact := false,

Diff for: core/src/main/scala/org/nullvector/crud/ReactiveMongoCrud.scala

+19-6
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import akka.persistence.state.scaladsl.{DurableStateStore, DurableStateUpdateSto
77
import org.nullvector.ReactiveMongoDriver
88
import org.nullvector.crud.ReactiveMongoCrud.Schema
99
import org.nullvector.typed.ReactiveMongoEventSerializer
10-
import reactivemongo.api.bson.BSONDocument
10+
import reactivemongo.api.bson.{BSONDateTime, BSONDocument}
1111

12+
import java.time.{Clock, Instant}
1213
import scala.concurrent.{ExecutionContext, Future}
1314

1415
object ReactiveMongoCrud {
@@ -18,15 +19,18 @@ object ReactiveMongoCrud {
1819
val payload = "payload"
1920
val manifest = "manifest"
2021
val revision = "revision"
22+
val created = "created"
23+
val updated = "updated"
2124
val tags = "tags"
2225
}
2326
}
2427

25-
class ReactiveMongoCrud(system: ActorSystem[_]) extends DurableStateStore[Any] with DurableStateUpdateStore[Any] {
28+
class ReactiveMongoCrud(system: ActorSystem[?]) extends DurableStateStore[Any] with DurableStateUpdateStore[Any] {
2629
private implicit lazy val dispatcher: ExecutionContext =
2730
system.dispatchers.lookup(DispatcherSelector.fromConfig("akka-persistence-reactivemongo-dispatcher"))
2831
private val driver: ReactiveMongoDriver = ReactiveMongoDriver(system)
2932
private val serializer: ReactiveMongoEventSerializer = ReactiveMongoEventSerializer(system)
33+
private val utcClock: Clock = Clock.systemUTC()
3034

3135
override def getObject(persistenceId: String): Future[GetObjectResult[Any]] = {
3236
for {
@@ -39,24 +43,26 @@ class ReactiveMongoCrud(system: ActorSystem[_]) extends DurableStateStore[Any] w
3943
serializer
4044
.deserialize(PersistentRepr(payload = payload, manifest = manifest))
4145
.map(rep => Some(rep.payload) -> revision)
42-
case None => Future.successful(None, 1L)
46+
case None => Future.successful(None, 0L)
4347
}
4448
} yield GetObjectResult(found, revision)
4549
}
4650
override def upsertObject(persistenceId: String, revision: Long, value: Any, tag: String): Future[Done] = {
51+
val nowBsonDateTime = BSONDateTime(Instant.now(utcClock).toEpochMilli)
4752
for {
4853
coll <- driver.crudCollection(persistenceId)
4954
rep <- serializer.serialize(PersistentRepr(value))
5055
_ <- coll
5156
.findAndUpdate(
5257
BSONDocument(Schema.persistenceId -> persistenceId, Schema.revision -> (revision - 1)),
5358
BSONDocument(
54-
"$set" -> BSONDocument(
59+
"$set" -> (BSONDocument(
5560
Schema.payload -> rep._1.payload.asInstanceOf[BSONDocument],
5661
Schema.manifest -> rep._1.manifest,
5762
Schema.revision -> revision,
58-
Schema.tags -> rep._2
59-
)
63+
Schema.tags -> rep._2,
64+
Schema.updated -> nowBsonDateTime
65+
) ++ (if (revision == 1) BSONDocument(Schema.created -> nowBsonDateTime) else BSONDocument()))
6066
),
6167
upsert = true
6268
)
@@ -68,4 +74,11 @@ class ReactiveMongoCrud(system: ActorSystem[_]) extends DurableStateStore[Any] w
6874
_ <- coll.findAndRemove(BSONDocument(Schema.persistenceId -> persistenceId))
6975
} yield Done
7076
}
77+
78+
override def deleteObject(persistenceId: String, revision: Long): Future[Done] = {
79+
for {
80+
coll <- driver.crudCollection(persistenceId)
81+
_ <- coll.findAndRemove(BSONDocument(Schema.persistenceId -> persistenceId, Schema.revision -> revision))
82+
} yield Done
83+
}
7184
}

Diff for: core/src/main/scala/org/nullvector/journal/InMemoryAsyncWriteJournal.scala

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@ import akka.actor.ActorSystem
44
import akka.persistence.{AtomicWrite, PersistentRepr}
55
import akka.stream.Materializer
66
import akka.stream.scaladsl.{Sink, Source}
7+
import org.nullvector.PersistInMemory
78
import org.nullvector.PersistInMemory.EventEntry
89
import org.nullvector.typed.ReactiveMongoEventSerializer
9-
import org.nullvector.{PersistInMemory}
1010
import reactivemongo.api.bson.BSONDocument
1111

1212
import scala.collection.immutable
13-
import scala.concurrent.Future
14-
import scala.util.{Success, Try}
13+
import scala.concurrent.{ExecutionContextExecutor, Future}
14+
import scala.util.Try
1515

1616
class InMemoryAsyncWriteJournal(val system: ActorSystem) extends AsyncWriteJournalOps {
1717

18-
import akka.actor.typed.scaladsl.adapter._
18+
import akka.actor.typed.scaladsl.adapter.*
1919

20-
private implicit val ec = system.dispatcher
20+
private implicit val ec: ExecutionContextExecutor = system.dispatcher
2121
private implicit val materializer: Materializer =
2222
Materializer.matFromSystem(system)
2323
private val eventSerializer: ReactiveMongoEventSerializer =

Diff for: core/src/test/scala/org/nullvector/crud/ReactiveMongoCrudTest.scala

+9-10
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ import scala.util.Random
2525
class ReactiveMongoCrudTest extends AsyncFlatSpec {
2626

2727
implicit private val system: ActorSystem = ActorSystem("Crud")
28-
val crud = DurableStateStoreRegistry
29-
.get(system)
28+
val crud = DurableStateStoreRegistry(system)
3029
.durableStateStoreFor[ReactiveMongoCrud](ReactiveMongoCrud.pluginId)
3130
private val driver: ReactiveMongoDriver = ReactiveMongoDriver(system)
3231

@@ -37,7 +36,7 @@ class ReactiveMongoCrudTest extends AsyncFlatSpec {
3736

3837
it should "insert an object" in {
3938
crud
40-
.upsertObject(randomPersistenceId, 2, ChessBoard(Map("a1" -> "R")), "")
39+
.upsertObject(randomPersistenceId, 1, ChessBoard(Map("a1" -> "R")), "")
4140
.map(_ shouldBe Done)
4241
}
4342

@@ -57,13 +56,13 @@ class ReactiveMongoCrudTest extends AsyncFlatSpec {
5756
val originalChessBoard = ChessBoard(Map("a1" -> "RB"))
5857
val updatedChessBoard = originalChessBoard.copy(piecePositions = Map("4b" -> "KW"))
5958
for {
60-
_ <- crud.upsertObject(pid, 35, originalChessBoard, "")
59+
_ <- crud.upsertObject(pid, 1, originalChessBoard, "")
6160
result1 <- crud.getObject(pid)
62-
_ <- crud.upsertObject(pid, 36, updatedChessBoard, "")
61+
_ <- crud.upsertObject(pid, 2, updatedChessBoard, "")
6362
result2 <- crud.getObject(pid)
6463
} yield {
65-
result1 shouldBe GetObjectResult(Some(originalChessBoard), 35)
66-
result2 shouldBe GetObjectResult(Some(updatedChessBoard), 36)
64+
result1 shouldBe GetObjectResult(Some(originalChessBoard), 1)
65+
result2 shouldBe GetObjectResult(Some(updatedChessBoard), 2)
6766
}
6867
}
6968

@@ -77,7 +76,7 @@ class ReactiveMongoCrudTest extends AsyncFlatSpec {
7776
result2 <- crud.getObject(pid)
7877
} yield {
7978
result1 shouldBe GetObjectResult(Some(chessBoard), 35)
80-
result2 shouldBe GetObjectResult(None, 1)
79+
result2 shouldBe GetObjectResult(None, 0)
8180
}
8281
}
8382

@@ -104,8 +103,8 @@ class ReactiveMongoCrudTest extends AsyncFlatSpec {
104103
boardV2 <- chessBoardRef.ask(ChessBoardBehavior.GetBoard(_))
105104
resultV2 <- crud.getObject(PersistenceId("ChessBoard", chessBoardId).id)
106105
} yield {
107-
resultV1 shouldBe GetObjectResult(Some(boardV1), 2L)
108-
resultV2 shouldBe GetObjectResult(Some(boardV2), 3L)
106+
resultV1 shouldBe GetObjectResult(Some(boardV1), 1L)
107+
resultV2 shouldBe GetObjectResult(Some(boardV2), 2L)
109108
}
110109
}
111110

Diff for: core/src/test/scala/org/nullvector/queries/ReactiveMongoReadJournalSpec.scala

+5-7
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ class ReactiveMongoReadJournalSpec()
5353
Await.result(rxDriver.journalCollection("j-0"), 1.second)
5454
}
5555

56+
behavior of "Read Journal"
57+
5658
it should "Events by tag from NoOffset" in {
5759
val prefixReadColl = "ReadCollection_A"
5860

@@ -439,7 +441,7 @@ class ReactiveMongoReadJournalSpec()
439441
.runWith(Sink.ignore),
440442
14.seconds
441443
)
442-
Thread.sleep(100)
444+
Thread.sleep(200)
443445
envelopes.peek().persistenceId shouldBe pId
444446
envelopes.size shouldBe 20
445447
}
@@ -450,14 +452,10 @@ class ReactiveMongoReadJournalSpec()
450452
val ids = new AtomicInteger()
451453
readJournal
452454
.persistenceIds()
453-
.async
454455
.runWith(Sink.foreach(e => ids.incrementAndGet()))
455-
.recover { case e: Throwable =>
456-
e.printStackTrace()
457-
}
458456
Await.ready(
459457
Source(1 to 10)
460-
.mapAsync(10) { collId =>
458+
.mapAsync(Runtime.getRuntime.availableProcessors()) { collId =>
461459
reactiveMongoJournalImpl.asyncWriteMessages((1 to 25).map { jIdx =>
462460
val pId = s"${prefixReadColl}_$collId-${Random.nextLong().abs}"
463461
AtomicWrite(
@@ -469,7 +467,7 @@ class ReactiveMongoReadJournalSpec()
469467
)
470468
})
471469
}
472-
.runWith(Sink.ignore),
470+
.run(),
473471
14.seconds
474472
)
475473
Thread.sleep(2000)

Diff for: core/src/test/scala/org/nullvector/snapshot/ReactiveMongoSnapshotSpec.scala

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.nullvector.snapshot
22

3-
import akka.actor.typed
43
import akka.actor.typed.scaladsl.Behaviors
4+
import akka.actor.{ActorSystem, typed}
55
import akka.persistence.{SnapshotMetadata, SnapshotSelectionCriteria}
66
import akka.testkit.{ImplicitSender, TestKitBase}
77
import com.typesafe.config.ConfigFactory
@@ -14,15 +14,15 @@ import reactivemongo.api.bson.{BSONDocument, Macros}
1414
import util.Collections
1515

1616
import java.util.Date
17-
import scala.concurrent.Await
18-
import scala.concurrent.duration._
17+
import scala.concurrent.duration.*
18+
import scala.concurrent.{Await, ExecutionContextExecutor}
1919

2020
class ReactiveMongoSnapshotSpec() extends TestKitBase with ImplicitSender with AnyWordSpecLike with Matchers with BeforeAndAfterAll {
2121

2222
private lazy implicit val typedAs: typed.ActorSystem[Nothing] =
2323
typed.ActorSystem(Behaviors.empty, "ReactiveMongoPlugin")
24-
override lazy val system = typedAs.classicSystem
25-
implicit lazy val ec = system.dispatcher
24+
override lazy val system: ActorSystem = typedAs.classicSystem
25+
implicit lazy val ec: ExecutionContextExecutor = system.dispatcher
2626

2727
val snapshotter: ReactiveMongoSnapshotImpl =
2828
new ReactiveMongoSnapshotImpl(ConfigFactory.load(), system)

Diff for: project/build.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=1.5.0
1+
sbt.version=1.9.0

0 commit comments

Comments
 (0)