Skip to content

Commit

Permalink
Change code to use FsCodec.SystemTextJson
Browse files Browse the repository at this point in the history
  • Loading branch information
bartelink committed Mar 6, 2020
1 parent 786c959 commit b0a761c
Show file tree
Hide file tree
Showing 29 changed files with 76 additions and 534 deletions.
13 changes: 6 additions & 7 deletions samples/Infrastructure/Services.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

open Domain
open FsCodec
open FsCodec.SystemTextJson.Serialization
open Microsoft.Extensions.DependencyInjection
open System
open System.Text.Json
Expand Down Expand Up @@ -49,24 +48,24 @@ type ServiceBuilder(storageConfig, handlerLog) =
let snapshot = Favorites.Fold.isOrigin,Favorites.Fold.snapshot

match storageConfig with
| Storage.StorageConfig.Cosmos _ -> Backend.Favorites.Service(handlerLog, resolver.ResolveWithJsonElementCodec(Favorites.Events.JsonElementCodec.codec JsonSerializer.defaultOptions, fold, initial, snapshot))
| _ -> Backend.Favorites.Service(handlerLog, resolver.ResolveWithUtf8ArrayCodec(Favorites.Events.Utf8ArrayCodec.codec, fold, initial, snapshot))
| Storage.StorageConfig.Cosmos _ -> Backend.Favorites.Service(handlerLog, resolver.ResolveWithJsonElementCodec(Favorites.Events.codecStj, fold, initial, snapshot))
| _ -> Backend.Favorites.Service(handlerLog, resolver.ResolveWithUtf8ArrayCodec(Favorites.Events.codecNewtonsoft, fold, initial, snapshot))

member __.CreateSaveForLaterService() =
let fold, initial = SavedForLater.Fold.fold, SavedForLater.Fold.initial
let snapshot = SavedForLater.Fold.isOrigin,SavedForLater.Fold.compact

match storageConfig with
| Storage.StorageConfig.Cosmos _ -> Backend.SavedForLater.Service(handlerLog, resolver.ResolveWithJsonElementCodec(SavedForLater.Events.JsonElementCodec.codec JsonSerializer.defaultOptions,fold,initial,snapshot), maxSavedItems=50)
| _ -> Backend.SavedForLater.Service(handlerLog, resolver.ResolveWithUtf8ArrayCodec(SavedForLater.Events.Utf8ArrayCodec.codec,fold,initial,snapshot), maxSavedItems=50)
| Storage.StorageConfig.Cosmos _ -> Backend.SavedForLater.Service(handlerLog, resolver.ResolveWithJsonElementCodec(SavedForLater.Events.codecStj,fold,initial,snapshot), maxSavedItems=50)
| _ -> Backend.SavedForLater.Service(handlerLog, resolver.ResolveWithUtf8ArrayCodec(SavedForLater.Events.codecNewtonsoft,fold,initial,snapshot), maxSavedItems=50)

member __.CreateTodosService() =
let fold, initial = TodoBackend.Fold.fold, TodoBackend.Fold.initial
let snapshot = TodoBackend.Fold.isOrigin, TodoBackend.Fold.snapshot

match storageConfig with
| Storage.StorageConfig.Cosmos _ -> TodoBackend.Service(handlerLog, resolver.ResolveWithJsonElementCodec(TodoBackend.Events.JsonElementCodec.codec JsonSerializer.defaultOptions,fold,initial,snapshot))
| _ -> TodoBackend.Service(handlerLog, resolver.ResolveWithUtf8ArrayCodec(TodoBackend.Events.Utf8ArrayCodec.codec,fold,initial,snapshot))
| Storage.StorageConfig.Cosmos _ -> TodoBackend.Service(handlerLog, resolver.ResolveWithJsonElementCodec(TodoBackend.Events.codecStj,fold,initial,snapshot))
| _ -> TodoBackend.Service(handlerLog, resolver.ResolveWithUtf8ArrayCodec(TodoBackend.Events.codecNewtonsoft,fold,initial,snapshot))

let register (services : IServiceCollection, storageConfig, handlerLog) =
let regF (factory : IServiceProvider -> 'T) = services.AddSingleton<'T>(fun (sp: IServiceProvider) -> factory sp) |> ignore
Expand Down
5 changes: 2 additions & 3 deletions samples/Store/Backend/Backend.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<TargetFramework>netstandard2.1</TargetFramework>
<WarningLevel>5</WarningLevel>
<IsTestProject>false</IsTestProject>
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
Expand All @@ -23,8 +23,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="FSharp.Core" Version="3.1.2.5" Condition=" '$(TargetFramework)' == 'net461' " />
<PackageReference Include="FSharp.Core" Version="4.3.4" Condition=" '$(TargetFramework)' == 'netstandard2.0' " />
<PackageReference Include="FSharp.Core" Version="4.3.4" />
</ItemGroup>

</Project>
31 changes: 3 additions & 28 deletions samples/Store/Domain/Cart.fs
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,8 @@ module Events =
| ItemWaiveReturnsChanged of ItemWaiveReturnsInfo
interface TypeShape.UnionContract.IUnionContract

module Utf8ArrayCodec =
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()

module JsonElementCodec =
open FsCodec.SystemTextJson
open System.Text.Json

let private encode (options: JsonSerializerOptions) =
fun (evt: Event) ->
match evt with
| Snapshotted state -> "Snapshotted", JsonSerializer.SerializeToElement(state, options)
| ItemAdded addInfo -> "ItemAdded", JsonSerializer.SerializeToElement(addInfo, options)
| ItemRemoved removeInfo -> "ItemRemoved", JsonSerializer.SerializeToElement(removeInfo, options)
| ItemQuantityChanged changeInfo -> "ItemQuantityChanged", JsonSerializer.SerializeToElement(changeInfo, options)
| ItemWaiveReturnsChanged waiveInfo -> "ItemWaiveReturnsChanged", JsonSerializer.SerializeToElement(waiveInfo, options)

let private tryDecode (options: JsonSerializerOptions) =
fun (eventType, data: JsonElement) ->
match eventType with
| "Snapshotted" -> Some (Snapshotted <| JsonSerializer.DeserializeElement<Compaction.State>(data, options))
| "ItemAdded" -> Some (ItemAdded <| JsonSerializer.DeserializeElement<ItemAddInfo>(data, options))
| "ItemRemoved" -> Some (ItemRemoved <| JsonSerializer.DeserializeElement<ItemRemoveInfo>(data, options))
| "ItemQuantityChanged" -> Some (ItemQuantityChanged <| JsonSerializer.DeserializeElement<ItemQuantityChangeInfo>(data, options))
| "ItemWaiveReturnsChanged" -> Some (ItemWaiveReturnsChanged <| JsonSerializer.DeserializeElement<ItemWaiveReturnsInfo>(data, options))
| _ -> None

let codec options = FsCodec.Codec.Create<Event, JsonElement>(encode options, tryDecode options)
let codecNewtonsoft = FsCodec.NewtonsoftJson.Codec.Create<Event>()
let codecStj = FsCodec.SystemTextJson.Codec.Create<Event>()

module Fold =
type ItemInfo = { skuId: SkuId; quantity: int; returnsWaived: bool }
Expand Down Expand Up @@ -106,4 +81,4 @@ module Commands =
match waived with
| Some waived when itemExistsWithDifferentWaiveStatus skuId waived ->
yield Events.ItemWaiveReturnsChanged { context = c; skuId = skuId; waived = waived }
| _ -> () ]
| _ -> () ]
23 changes: 3 additions & 20 deletions samples/Store/Domain/ContactPreferences.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,8 @@ module Events =
| [<System.Runtime.Serialization.DataMember(Name = "contactPreferencesChanged")>]Updated of Value
interface TypeShape.UnionContract.IUnionContract

module Utf8ArrayCodec =
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()

module JsonElementCodec =
open FsCodec.SystemTextJson
open System.Text.Json

let private encode (options: JsonSerializerOptions) =
fun (evt: Event) ->
match evt with
| Updated value -> "contactPreferencesChanged", JsonSerializer.SerializeToElement(value, options)

let private tryDecode (options: JsonSerializerOptions) =
fun (eventType, data: JsonElement) ->
match eventType with
| "contactPreferencesChanged" -> Some (Updated <| JsonSerializer.DeserializeElement<Value>(data, options))
| _ -> None

let codec options = FsCodec.Codec.Create<Event, JsonElement>(encode options, tryDecode options)
let codecNewtonsoft = FsCodec.NewtonsoftJson.Codec.Create<Event>()
let codecStj = FsCodec.SystemTextJson.Codec.Create<Event>()

module Fold =

Expand All @@ -56,4 +39,4 @@ module Commands =
match command with
| Update ({ preferences = preferences } as value) ->
if state = preferences then [] else
[ Events.Updated value ]
[ Events.Updated value ]
5 changes: 3 additions & 2 deletions samples/Store/Domain/Domain.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<TargetFrameworks>netstandard2.1</TargetFrameworks>
<WarningLevel>5</WarningLevel>
<IsTestProject>false</IsTestProject>
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
Expand All @@ -19,9 +19,10 @@

<ItemGroup>
<PackageReference Include="FSharp.Core" Version="3.1.2.5" Condition=" '$(TargetFramework)' == 'net461' " />
<PackageReference Include="FSharp.Core" Version="4.3.4" Condition=" '$(TargetFramework)' == 'netstandard2.0' " />
<PackageReference Include="FSharp.Core" Version="4.3.4" Condition=" '$(TargetFramework)' == 'netstandard2.1' " />

<PackageReference Include="FsCodec.NewtonsoftJson" Version="2.0.2-alpha.0.6" />
<PackageReference Include="FsCodec.SystemTextJson" Version="2.0.2-alpha.0.6" />
</ItemGroup>

<ItemGroup>
Expand Down
23 changes: 2 additions & 21 deletions samples/Store/Domain/Favorites.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,8 @@ module Events =
| Unfavorited of Unfavorited
interface TypeShape.UnionContract.IUnionContract

module Utf8ArrayCodec =
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()

module JsonElementCodec =
open FsCodec.SystemTextJson
open System.Text.Json

let private encode (options: JsonSerializerOptions) = fun (evt: Event) ->
match evt with
| Snapshotted snapshotted -> "Snapshotted", JsonSerializer.SerializeToElement(snapshotted, options)
| Favorited favorited -> "Favorited", JsonSerializer.SerializeToElement(favorited, options)
| Unfavorited unfavorited -> "Unfavorited", JsonSerializer.SerializeToElement(unfavorited, options)

let private tryDecode (options: JsonSerializerOptions) = fun (eventType, data: JsonElement) ->
match eventType with
| "Snapshotted" -> Some (Snapshotted <| JsonSerializer.DeserializeElement<Snapshotted>(data, options))
| "Favorited" -> Some (Favorited <| JsonSerializer.DeserializeElement<Favorited>(data, options))
| "Unfavorited" -> Some (Unfavorited <| JsonSerializer.DeserializeElement<Unfavorited>(data, options))
| _ -> None

let codec options = FsCodec.Codec.Create<Event, JsonElement>(encode options, tryDecode options)
let codecNewtonsoft = FsCodec.NewtonsoftJson.Codec.Create<Event>()
let codecStj = FsCodec.SystemTextJson.Codec.Create<Event>()

module Fold =

Expand Down
29 changes: 3 additions & 26 deletions samples/Store/Domain/SavedForLater.fs
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,8 @@ module Events =
| Added of Added
interface TypeShape.UnionContract.IUnionContract

module Utf8ArrayCodec =
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()

module JsonElementCodec =
open FsCodec.SystemTextJson
open System.Text.Json

let private encode (options: JsonSerializerOptions) =
fun (evt: Event) ->
match evt with
| Compacted compacted -> Compaction.EventType, JsonSerializer.SerializeToElement(compacted, options)
| Merged merged -> "Merged", JsonSerializer.SerializeToElement(merged, options)
| Removed removed -> "Removed", JsonSerializer.SerializeToElement(removed, options)
| Added added -> "Added", JsonSerializer.SerializeToElement(added, options)

let private tryDecode (options: JsonSerializerOptions) =
fun (eventType, data: JsonElement) ->
match eventType with
| Compaction.EventType -> Some (Compacted <| JsonSerializer.DeserializeElement<Compaction.Compacted>(data, options))
| "Merged" -> Some (Merged <| JsonSerializer.DeserializeElement<Merged>(data, options))
| "Removed" -> Some (Removed <| JsonSerializer.DeserializeElement<Removed>(data, options))
| "Added" -> Some (Added <| JsonSerializer.DeserializeElement<Added>(data, options))
| _ -> None

let codec options = FsCodec.Codec.Create<Event, JsonElement>(encode options, tryDecode options)
let codecNewtonsoft = FsCodec.NewtonsoftJson.Codec.Create<Event>()
let codecStj = FsCodec.SystemTextJson.Codec.Create<Event>()

module Fold =
open Events
Expand Down Expand Up @@ -129,4 +106,4 @@ module Commands =
let index = Index state
let net = skus |> Array.filter (index.DoesNotAlreadyContainSameOrMoreRecent dateSaved)
if Array.isEmpty net then true, []
else validateAgainstInvariants [ Events.Added { skus = net ; dateSaved = dateSaved } ]
else validateAgainstInvariants [ Events.Added { skus = net ; dateSaved = dateSaved } ]
7 changes: 3 additions & 4 deletions samples/Store/Integration/CartIntegration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ open Equinox
open Equinox.Cosmos.Integration
open Equinox.EventStore
open Equinox.MemoryStore
open FsCodec.SystemTextJson.Serialization
open Swensen.Unquote

#nowarn "1182" // From hereon in, we may have some 'unused' privates (the tests)
Expand All @@ -16,15 +15,15 @@ let createMemoryStore () =
// we want to validate that the JSON UTF8 is working happily
VolatileStore<byte[]>()
let createServiceMemory log store =
Backend.Cart.Service(log, fun (id,opt) -> MemoryStore.Resolver(store, Domain.Cart.Events.Utf8ArrayCodec.codec, fold, initial).Resolve(id,?option=opt))
Backend.Cart.Service(log, fun (id,opt) -> MemoryStore.Resolver(store, Domain.Cart.Events.codecNewtonsoft, fold, initial).Resolve(id,?option=opt))

let eventStoreCodec = Domain.Cart.Events.Utf8ArrayCodec.codec
let eventStoreCodec = Domain.Cart.Events.codecNewtonsoft
let resolveGesStreamWithRollingSnapshots gateway =
fun (id,opt) -> EventStore.Resolver(gateway, eventStoreCodec, fold, initial, access = AccessStrategy.RollingSnapshots snapshot).Resolve(id,?option=opt)
let resolveGesStreamWithoutCustomAccessStrategy gateway =
fun (id,opt) -> EventStore.Resolver(gateway, eventStoreCodec, fold, initial).Resolve(id,?option=opt)

let cosmosCodec = Domain.Cart.Events.JsonElementCodec.codec JsonSerializer.defaultOptions
let cosmosCodec = Domain.Cart.Events.codecStj
let resolveCosmosStreamWithSnapshotStrategy gateway =
fun (id,opt) -> Cosmos.Resolver(gateway, cosmosCodec, fold, initial, Cosmos.CachingStrategy.NoCaching, Cosmos.AccessStrategy.Snapshot snapshot).Resolve(id,?option=opt)
let resolveCosmosStreamWithoutCustomAccessStrategy gateway =
Expand Down
10 changes: 4 additions & 6 deletions samples/Store/Integration/ContactPreferencesIntegration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,24 @@

open Equinox
open Equinox.Cosmos.Integration
open FsCodec.SystemTextJson.Serialization
open Swensen.Unquote
open Xunit

#nowarn "1182" // From hereon in, we may have some 'unused' privates (the tests)

let fold, initial = Domain.ContactPreferences.Fold.fold, Domain.ContactPreferences.Fold.initial

let createMemoryStore () =
new MemoryStore.VolatileStore<_>()
MemoryStore.VolatileStore<_>()
let createServiceMemory log store =
Backend.ContactPreferences.Service(log, MemoryStore.Resolver(store, FsCodec.Box.Codec.Create(), fold, initial).Resolve)

let eventStoreCodec = Domain.ContactPreferences.Events.Utf8ArrayCodec.codec
let eventStoreCodec = Domain.ContactPreferences.Events.codecNewtonsoft
let resolveStreamGesWithOptimizedStorageSemantics gateway =
EventStore.Resolver(gateway 1, eventStoreCodec, fold, initial, access = EventStore.AccessStrategy.LatestKnownEvent).Resolve
let resolveStreamGesWithoutAccessStrategy gateway =
EventStore.Resolver(gateway defaultBatchSize, eventStoreCodec, fold, initial).Resolve

let cosmosCodec = Domain.ContactPreferences.Events.JsonElementCodec.codec JsonSerializer.defaultOptions
let cosmosCodec = Domain.ContactPreferences.Events.codecStj
let resolveStreamCosmosWithLatestKnownEventSemantics gateway =
Cosmos.Resolver(gateway 1, cosmosCodec, fold, initial, Cosmos.CachingStrategy.NoCaching, Cosmos.AccessStrategy.LatestKnownEvent).Resolve
let resolveStreamCosmosUnoptimized gateway =
Expand Down Expand Up @@ -76,7 +74,7 @@ type Tests(testOutputHelper) =
let! service = arrange connectToSpecifiedCosmosOrSimulator createCosmosContext resolveStreamCosmosWithLatestKnownEventSemantics
do! act service args
}

[<AutoData(SkipIfRequestedViaEnvironmentVariable="EQUINOX_INTEGRATION_SKIP_COSMOS")>]
let ``Can roundtrip against Cosmos, correctly folding the events with RollingUnfold semantics`` args = Async.RunSynchronously <| async {
let! service = arrange connectToSpecifiedCosmosOrSimulator createCosmosContext resolveStreamCosmosRollingUnfolds
Expand Down
7 changes: 3 additions & 4 deletions samples/Store/Integration/FavoritesIntegration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

open Equinox
open Equinox.Cosmos.Integration
open FsCodec.SystemTextJson.Serialization
open Swensen.Unquote

#nowarn "1182" // From hereon in, we may have some 'unused' privates (the tests)
Expand All @@ -15,12 +14,12 @@ let createMemoryStore () =
let createServiceMemory log store =
Backend.Favorites.Service(log, MemoryStore.Resolver(store, FsCodec.Box.Codec.Create(), fold, initial).Resolve)

let eventStoreCodec = Domain.Favorites.Events.Utf8ArrayCodec.codec
let eventStoreCodec = Domain.Favorites.Events.codecNewtonsoft
let createServiceGes gateway log =
let resolve = EventStore.Resolver(gateway, eventStoreCodec, fold, initial, access = EventStore.AccessStrategy.RollingSnapshots snapshot).Resolve
Backend.Favorites.Service(log, resolve)

let cosmosCodec = Domain.Favorites.Events.JsonElementCodec.codec JsonSerializer.defaultOptions
let cosmosCodec = Domain.Favorites.Events.codecStj
let createServiceCosmos gateway log =
let resolve = Cosmos.Resolver(gateway, cosmosCodec, fold, initial, Cosmos.CachingStrategy.NoCaching, Cosmos.AccessStrategy.Snapshot snapshot).Resolve
Backend.Favorites.Service(log, resolve)
Expand Down Expand Up @@ -68,7 +67,7 @@ type Tests(testOutputHelper) =
let service = createServiceCosmos gateway log
do! act service args
}

[<AutoData(SkipIfRequestedViaEnvironmentVariable="EQUINOX_INTEGRATION_SKIP_COSMOS")>]
let ``Can roundtrip against Cosmos, correctly folding the events with rolling unfolds`` args = Async.RunSynchronously <| async {
let log = createLog ()
Expand Down
29 changes: 2 additions & 27 deletions samples/TodoBackend/Todo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,8 @@ module Events =
| Snapshotted of Snapshotted
interface TypeShape.UnionContract.IUnionContract

module Utf8ArrayCodec =
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()

module JsonElementCodec =
open FsCodec.SystemTextJson
open System.Text.Json

let private encode (options: JsonSerializerOptions) =
fun (evt: Event) ->
match evt with
| Added todo -> "Added", JsonSerializer.SerializeToElement(todo, options)
| Updated todo -> "Updated", JsonSerializer.SerializeToElement(todo, options)
| Deleted deleted -> "Deleted", JsonSerializer.SerializeToElement(deleted, options)
| Cleared -> "Cleared", Unchecked.defaultof<JsonElement>
| Snapshotted snapshotted -> "Snapshotted", JsonSerializer.SerializeToElement(snapshotted, options)

let private tryDecode (options: JsonSerializerOptions) =
fun (eventType, data: JsonElement) ->
match eventType with
| "Added" -> Some (Added <| JsonSerializer.DeserializeElement<Todo>(data, options))
| "Updated" -> Some (Updated <| JsonSerializer.DeserializeElement<Todo>(data, options))
| "Deleted" -> Some (Deleted <| JsonSerializer.DeserializeElement<Deleted>(data, options))
| "Cleared" -> Some Cleared
| "Snapshotted" -> Some (Snapshotted <| JsonSerializer.DeserializeElement<Snapshotted>(data, options))
| _ -> None

let codec options = FsCodec.Codec.Create<Event, JsonElement>(encode options, tryDecode options)
let codecNewtonsoft = FsCodec.NewtonsoftJson.Codec.Create<Event>()
let codecStj = FsCodec.SystemTextJson.Codec.Create<Event>()

module Fold =
type State = { items : Events.Todo list; nextId : int }
Expand Down
Loading

0 comments on commit b0a761c

Please sign in to comment.