1
+ // -----------------------------------------------------------------------
2
+ // <copyright file="CustomObjectSerializerSpec.cs" company="Akka.NET Project">
3
+ // Copyright (C) 2009-2022 Lightbend Inc. <http://www.lightbend.com>
4
+ // Copyright (C) 2013-2022 .NET Foundation <https://github.com/akkadotnet/akka.net>
5
+ // </copyright>
6
+ // -----------------------------------------------------------------------
7
+
8
+ using System ;
9
+ using System . IO ;
10
+ using System . Text ;
11
+ using System . Threading . Tasks ;
12
+ using Akka . Actor ;
13
+ using Akka . Configuration ;
14
+ using Akka . Serialization ;
15
+ using FluentAssertions ;
16
+ using Microsoft . Data . Sqlite ;
17
+ using Xunit ;
18
+ using Xunit . Abstractions ;
19
+
20
+ namespace Akka . Persistence . Sqlite . Tests
21
+ {
22
+ public class CustomObjectSerializerSpec : Akka . TestKit . Xunit2 . TestKit , IAsyncLifetime
23
+ {
24
+ private static readonly Config Config = ConfigurationFactory . ParseString ( $@ "
25
+ akka.actor {{
26
+ serializers {{
27
+ mySerializer = ""{ typeof ( MySerializer ) . AssemblyQualifiedName } ""
28
+ }}
29
+ serialization-bindings {{
30
+ ""System.Object"" = mySerializer
31
+ }}
32
+ }}
33
+
34
+ akka.persistence {{
35
+ journal {{
36
+ plugin = ""akka.persistence.journal.sqlite""
37
+ sqlite {{
38
+ connection-string = ""DataSource=AkkaJournal.db""
39
+ auto-initialize = on
40
+ }}
41
+ }}
42
+ snapshot-store {{
43
+ plugin = ""akka.persistence.snapshot-store.sqlite""
44
+ sqlite {{
45
+ connection-string = ""DataSource=AkkaSnapshot.db""
46
+ auto-initialize = on
47
+ }}
48
+ }}
49
+ }}" ) . WithFallback ( SqlitePersistence . DefaultConfiguration ( ) ) ;
50
+
51
+ public CustomObjectSerializerSpec ( ITestOutputHelper helper )
52
+ : base ( Config , nameof ( CustomObjectSerializerSpec ) , helper )
53
+ {
54
+ }
55
+
56
+ [ Fact ( DisplayName = "Persistence.Sql should use custom serializer for object type" ) ]
57
+ public async Task CustomSerializerTest ( )
58
+ {
59
+ var probe = CreateTestProbe ( ) ;
60
+
61
+ var actor = Sys . ActorOf ( Props . Create ( ( ) => new PersistedActor ( "a" ) ) ) ;
62
+ actor . Tell ( "a" , probe ) ;
63
+ probe . ExpectMsg ( "a" ) ;
64
+
65
+ var conn = new SqliteConnection ( "DataSource=AkkaJournal.db" ) ;
66
+ conn . Open ( ) ;
67
+ const string sql = "SELECT ej.serializer_id FROM event_journal ej WHERE ej.persistence_id = 'a'" ;
68
+ await using var cmd = new SqliteCommand ( sql , conn ) ;
69
+ var record = await cmd . ExecuteReaderAsync ( ) ;
70
+ await record . ReadAsync ( ) ;
71
+ record [ 0 ] . Should ( ) . Be ( 9999 ) ;
72
+ }
73
+
74
+ public Task InitializeAsync ( )
75
+ {
76
+ if ( File . Exists ( "AkkaJournal.db" ) )
77
+ File . Delete ( "AkkaJournal.db" ) ;
78
+ return Task . CompletedTask ;
79
+ }
80
+
81
+ public Task DisposeAsync ( )
82
+ {
83
+ return Task . CompletedTask ;
84
+ }
85
+ }
86
+
87
+ internal class MySerializer : Serializer
88
+ {
89
+ public MySerializer ( ExtendedActorSystem system ) : base ( system )
90
+ {
91
+ }
92
+
93
+ public override bool IncludeManifest { get { return true ; } }
94
+ public override int Identifier { get { return 9999 ; } }
95
+
96
+ public override byte [ ] ToBinary ( object obj )
97
+ {
98
+ return Encoding . UTF8 . GetBytes ( obj . ToString ( ) ) ;
99
+ }
100
+
101
+ public override object FromBinary ( byte [ ] bytes , Type type )
102
+ {
103
+ return Encoding . UTF8 . GetString ( bytes ) ;
104
+ }
105
+ }
106
+
107
+ internal sealed class PersistedActor : UntypedPersistentActor
108
+ {
109
+ public PersistedActor ( string persistenceId )
110
+ {
111
+ PersistenceId = persistenceId ;
112
+ }
113
+
114
+ public override string PersistenceId { get ; }
115
+
116
+ protected override void OnCommand ( object message )
117
+ {
118
+ var sender = Sender ;
119
+ Persist ( message , _ =>
120
+ {
121
+ sender . Tell ( message ) ;
122
+ } ) ;
123
+ }
124
+
125
+ protected override void OnRecover ( object message )
126
+ {
127
+ }
128
+ }
129
+ }
0 commit comments