Skip to content

Commit

Permalink
feat(scalasdk): replicated entities examples for Scala (lightbend#613)
Browse files Browse the repository at this point in the history
  • Loading branch information
octonato committed Oct 15, 2021
1 parent ec33470 commit 3b271de
Show file tree
Hide file tree
Showing 30 changed files with 192 additions and 84 deletions.

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name := "valueentity-counter"
name := "replicatedentity-examples"

organization := "com.akkaseverless.samples"
organizationHomepage := Some(url("https://akkaserverless.com"))
Expand Down Expand Up @@ -35,4 +35,3 @@ run / fork := false
Global / cancelable := false // ctrl-c

libraryDependencies ++= Seq("org.scalatest" %% "scalatest" % "3.2.7" % Test)

Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@ class SomeCounter(context: ReplicatedEntityContext) extends AbstractSomeCounter

/** Command handler for "Increase". */
def increase(currentData: ReplicatedCounter, increaseValue: counter.IncreaseValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `Increase` is not implemented, yet")
effects
.update(currentData.increment(increaseValue.value))
.thenReply(Empty.defaultInstance)


/** Command handler for "Decrease". */
def decrease(currentData: ReplicatedCounter, decreaseValue: counter.DecreaseValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `Decrease` is not implemented, yet")
effects
.update(currentData.decrement(decreaseValue.value))
.thenReply(Empty.defaultInstance)

/** Command handler for "Get". */
def get(currentData: ReplicatedCounter, getValue: counter.GetValue): ReplicatedEntity.Effect[counter.CurrentValue] =
effects.error("The command handler for `Get` is not implemented, yet")
effects
.reply(counter.CurrentValue(currentData.value))

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,33 @@ import com.google.protobuf.empty.Empty
/** A replicated entity. */
class SomeCounterMap(context: ReplicatedEntityContext) extends AbstractSomeCounterMap {


/** Command handler for "Increase". */
def increase(currentData: ReplicatedCounterMap[String], increaseValue: countermap.IncreaseValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `Increase` is not implemented, yet")
effects
.update(currentData.increment(increaseValue.key, increaseValue.value))
.thenReply(Empty.defaultInstance)

/** Command handler for "Decrease". */
def decrease(currentData: ReplicatedCounterMap[String], decreaseValue: countermap.DecreaseValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `Decrease` is not implemented, yet")
effects
.update(currentData.decrement(decreaseValue.key, decreaseValue.value))
.thenReply(Empty.defaultInstance)

/** Command handler for "Remove". */
def remove(currentData: ReplicatedCounterMap[String], removeValue: countermap.RemoveValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `Remove` is not implemented, yet")
effects
.update(currentData.remove(removeValue.key))
.thenReply(Empty.defaultInstance)

/** Command handler for "Get". */
def get(currentData: ReplicatedCounterMap[String], getValue: countermap.GetValue): ReplicatedEntity.Effect[countermap.CurrentValue] =
effects.error("The command handler for `Get` is not implemented, yet")
effects
.reply(countermap.CurrentValue(currentData(getValue.key)))

/** Command handler for "GetAll". */
def getAll(currentData: ReplicatedCounterMap[String], getAllValues: countermap.GetAllValues): ReplicatedEntity.Effect[countermap.CurrentValues] =
effects.error("The command handler for `GetAll` is not implemented, yet")
def getAll(currentData: ReplicatedCounterMap[String], getAllValues: countermap.GetAllValues): ReplicatedEntity.Effect[countermap.CurrentValues] = {
val keyValues = currentData.keySet.map { key => key -> currentData(key) }.toMap
effects.reply(countermap.CurrentValues(keyValues))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import com.akkaserverless.scalasdk.replicatedentity.ReplicatedEntityContext
import com.akkaserverless.scalasdk.replicatedentity.ReplicatedMap
import com.example.replicated.map
import com.google.protobuf.empty.Empty
import com.akkaserverless.scalasdk.replicatedentity.ReplicatedRegister
import com.akkaserverless.scalasdk.replicatedentity.ReplicatedSet

// This class was initially generated based on the .proto definition by Akka Serverless tooling.
//
Expand All @@ -15,29 +17,60 @@ import com.google.protobuf.empty.Empty
/** A replicated entity. */
class SomeMap(context: ReplicatedEntityContext) extends AbstractSomeMap {

// keys
private val FooKey = SomeKey("foo")
private val BarKey = SomeKey("bar")
private val BazKey = SomeKey("baz")

/** Command handler for "IncreaseFoo". */
def increaseFoo(currentData: ReplicatedMap[SomeKey, ReplicatedData], increaseFooValue: map.IncreaseFooValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `IncreaseFoo` is not implemented, yet")
def increaseFoo(currentData: ReplicatedMap[SomeKey, ReplicatedData], increaseFooValue: map.IncreaseFooValue): ReplicatedEntity.Effect[Empty] = {
val foo = currentData.getReplicatedCounter(FooKey)
effects
.update(currentData.update(FooKey, foo.increment(increaseFooValue.value)))
.thenReply(Empty.defaultInstance)
}

/** Command handler for "DecreaseFoo". */
def decreaseFoo(currentData: ReplicatedMap[SomeKey, ReplicatedData], decreaseFooValue: map.DecreaseFooValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `DecreaseFoo` is not implemented, yet")
def decreaseFoo(currentData: ReplicatedMap[SomeKey, ReplicatedData], decreaseFooValue: map.DecreaseFooValue): ReplicatedEntity.Effect[Empty] = {
val foo = currentData.getReplicatedCounter(FooKey)
effects
.update(currentData.update(FooKey, foo.decrement(decreaseFooValue.value)))
.thenReply(Empty.defaultInstance)
}

/** Command handler for "SetBar". */
def setBar(currentData: ReplicatedMap[SomeKey, ReplicatedData], setBarValue: map.SetBarValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `SetBar` is not implemented, yet")
def setBar(currentData: ReplicatedMap[SomeKey, ReplicatedData], setBarValue: map.SetBarValue): ReplicatedEntity.Effect[Empty] = {
val bar: ReplicatedRegister[String] = currentData.getReplicatedRegister(BarKey)
effects
.update(currentData.update(BarKey, bar.set(setBarValue.value)))
.thenReply(Empty.defaultInstance)
}

/** Command handler for "AddBaz". */
def addBaz(currentData: ReplicatedMap[SomeKey, ReplicatedData], addBazValue: map.AddBazValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `AddBaz` is not implemented, yet")
def addBaz(currentData: ReplicatedMap[SomeKey, ReplicatedData], addBazValue: map.AddBazValue): ReplicatedEntity.Effect[Empty] = {
val baz: ReplicatedSet[String] = currentData.getReplicatedSet(BazKey)
effects
.update(currentData.update(BarKey, baz.add(addBazValue.value)))
.thenReply(Empty.defaultInstance)
}

/** Command handler for "RemoveBaz". */
def removeBaz(currentData: ReplicatedMap[SomeKey, ReplicatedData], removeBazValue: map.RemoveBazValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `RemoveBaz` is not implemented, yet")
def removeBaz(currentData: ReplicatedMap[SomeKey, ReplicatedData], removeBazValue: map.RemoveBazValue): ReplicatedEntity.Effect[Empty] = {
val baz: ReplicatedSet[String] = currentData.getReplicatedSet(BazKey)
effects
.update(currentData.update(BarKey, baz.remove(removeBazValue.value)))
.thenReply(Empty.defaultInstance)
}

/** Command handler for "Get". */
def get(currentData: ReplicatedMap[SomeKey, ReplicatedData], getValues: map.GetValues): ReplicatedEntity.Effect[map.CurrentValues] =
effects.error("The command handler for `Get` is not implemented, yet")
def get(currentData: ReplicatedMap[SomeKey, ReplicatedData], getValues: map.GetValues): ReplicatedEntity.Effect[map.CurrentValues] = {

val foo = currentData.getReplicatedCounter(FooKey)
val bar: ReplicatedRegister[String] = currentData.getReplicatedRegister(BarKey, () => "")
val baz: ReplicatedSet[String] = currentData.getReplicatedSet(BazKey)

val resp = map.CurrentValues(foo.value, bar(), baz.elements.toSeq)
effects.reply(resp)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,46 @@ import com.google.protobuf.empty.Empty
/** A replicated entity. */
class SomeMultiMap(context: ReplicatedEntityContext) extends AbstractSomeMultiMap {


/** Command handler for "Put". */
def put(currentData: ReplicatedMultiMap[String, Double], putValue: multimap.PutValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `Put` is not implemented, yet")
def put(currentData: ReplicatedMultiMap[String, Double], putValue: multimap.PutValue): ReplicatedEntity.Effect[Empty] =
effects
.update(currentData.put(putValue.key, putValue.value))
.thenReply(Empty.defaultInstance)

/** Command handler for "PutAll". */
def putAll(currentData: ReplicatedMultiMap[String, Double], putAllValues: multimap.PutAllValues): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `PutAll` is not implemented, yet")
effects
.update(currentData.putAll(putAllValues.key, putAllValues.values))
.thenReply(Empty.defaultInstance)

/** Command handler for "Remove". */
def remove(currentData: ReplicatedMultiMap[String, Double], removeValue: multimap.RemoveValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `Remove` is not implemented, yet")
effects
.update(currentData.remove(removeValue.key, removeValue.value))
.thenReply(Empty.defaultInstance)

/** Command handler for "RemoveAll". */
def removeAll(currentData: ReplicatedMultiMap[String, Double], removeAllValues: multimap.RemoveAllValues): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `RemoveAll` is not implemented, yet")
effects
.update(currentData.removeAll(removeAllValues.key))
.thenReply(Empty.defaultInstance)

/** Command handler for "Get". */
def get(currentData: ReplicatedMultiMap[String, Double], getValues: multimap.GetValues): ReplicatedEntity.Effect[multimap.CurrentValues] =
effects.error("The command handler for `Get` is not implemented, yet")

def get(currentData: ReplicatedMultiMap[String, Double], getValues: multimap.GetValues): ReplicatedEntity.Effect[multimap.CurrentValues] = {
val values = currentData.get(getValues.key)
effects
.reply(multimap.CurrentValues(getValues.key, values.toSeq))
}

/** Command handler for "GetAll". */
def getAll(currentData: ReplicatedMultiMap[String, Double], getAllValues: multimap.GetAllValues): ReplicatedEntity.Effect[multimap.AllCurrentValues] =
effects.error("The command handler for `GetAll` is not implemented, yet")

def getAll(currentData: ReplicatedMultiMap[String, Double], getAllValues: multimap.GetAllValues): ReplicatedEntity.Effect[multimap.AllCurrentValues] = {
val currentValues =
currentData.keySet.map { key =>
val values = currentData.get(key)
multimap.CurrentValues(key, values.toSeq)
}

effects.reply(multimap.AllCurrentValues(currentValues.toSeq))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@ import com.google.protobuf.empty.Empty

/** A replicated entity. */
class SomeRegister(context: ReplicatedEntityContext) extends AbstractSomeRegister {

override def emptyValue: SomeValue =
throw new UnsupportedOperationException("Not implemented yet, replace with your empty register value")


override def emptyValue: SomeValue = SomeValue.defaultInstance

/** Command handler for "Set". */
def set(currentData: ReplicatedRegister[SomeValue], setValue: register.SetValue): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `Set` is not implemented, yet")
def set(currentData: ReplicatedRegister[SomeValue], setValue: register.SetValue): ReplicatedEntity.Effect[Empty] = {
val someValue = SomeValue(setValue.value)
effects
.update(currentData.set(someValue))
.thenReply(Empty.defaultInstance)
}

/** Command handler for "Get". */
def get(currentData: ReplicatedRegister[SomeValue], getValue: register.GetValue): ReplicatedEntity.Effect[register.CurrentValue] =
effects.error("The command handler for `Get` is not implemented, yet")

def get(currentData: ReplicatedRegister[SomeValue], getValue: register.GetValue): ReplicatedEntity.Effect[register.CurrentValue] =
effects.reply(register.CurrentValue(currentData().someField))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.example.replicated.registermap.domain

import com.akkaserverless.scalasdk.replicatedentity.ReplicatedEntity
import com.akkaserverless.scalasdk.replicatedentity.ReplicatedEntityContext
import com.akkaserverless.scalasdk.replicatedentity.ReplicatedRegisterMap
import com.example.replicated.registermap
import com.google.protobuf.empty.Empty

// This class was initially generated based on the .proto definition by Akka Serverless tooling.
//
// As long as this file exists it will not be overwritten: you can maintain it yourself,
// or delete it so it is regenerated as needed.

/** A replicated entity. */
class SomeRegisterMap(context: ReplicatedEntityContext) extends AbstractSomeRegisterMap {

/** Command handler for "Set". */
def set(currentData: ReplicatedRegisterMap[SomeKey, SomeValue], setValue: registermap.SetValue): ReplicatedEntity.Effect[Empty] = {

val keyValue =
for {
key <- setValue.key.map(_.field)
value <- setValue.value.map(_.field)
} yield (key, value)

keyValue.map { case (key, value) =>
effects
.update(currentData.setValue(SomeKey(key), SomeValue(value)))
.thenReply(Empty.defaultInstance)
}
.getOrElse {
effects
.error(s"Invalid input: received key = '${setValue.key}' and value = '${setValue.value}'")
}

}

/** Command handler for "Remove". */
def remove(currentData: ReplicatedRegisterMap[SomeKey, SomeValue], removeValue: registermap.RemoveValue): ReplicatedEntity.Effect[Empty] =
removeValue.key.map { key =>
effects
.update(currentData.remove(SomeKey(key.field)))
.thenReply(Empty.defaultInstance)
}
.getOrElse {
effects.error("Invalid input: key is empty")
}


/** Command handler for "Get". */
def get(currentData: ReplicatedRegisterMap[SomeKey, SomeValue], getValue: registermap.GetValue): ReplicatedEntity.Effect[registermap.CurrentValue] =
getValue.key.map { key =>
val value = currentData.get(SomeKey(key.field)).map(v => registermap.Value(v.someField))
effects
.reply(registermap.CurrentValue(getValue.key, value))
}
.getOrElse {
effects.error("The command handler for `Get` is not implemented, yet")
}

/** Command handler for "GetAll". */
def getAll(currentData: ReplicatedRegisterMap[SomeKey, SomeValue], getAllValues: registermap.GetAllValues): ReplicatedEntity.Effect[registermap.CurrentValues] = {

val allData =
currentData.keySet.map { key =>
val value = currentData.get(key).map(v => registermap.Value(v.someField))
registermap.CurrentValue(Some(registermap.Key(key.someField)), value)
}.toSeq

effects.reply(registermap.CurrentValues(allData))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,21 @@ import com.google.protobuf.empty.Empty
/** A replicated entity. */
class SomeSet(context: ReplicatedEntityContext) extends AbstractSomeSet {


/** Command handler for "Add". */
def add(currentData: ReplicatedSet[String], addElement: set.AddElement): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `Add` is not implemented, yet")
def add(currentData: ReplicatedSet[String], addElement: set.AddElement): ReplicatedEntity.Effect[Empty] =
effects
.update(currentData.add(addElement.element))
.thenReply(Empty.defaultInstance)


/** Command handler for "Remove". */
def remove(currentData: ReplicatedSet[String], removeElement: set.RemoveElement): ReplicatedEntity.Effect[Empty] =
effects.error("The command handler for `Remove` is not implemented, yet")
effects
.update(currentData.remove(removeElement.element))
.thenReply(Empty.defaultInstance)

/** Command handler for "Get". */
def get(currentData: ReplicatedSet[String], getElements: set.GetElements): ReplicatedEntity.Effect[set.CurrentElements] =
effects.error("The command handler for `Get` is not implemented, yet")
effects.reply(set.CurrentElements(currentData.elements.toSeq))

}

0 comments on commit 3b271de

Please sign in to comment.