-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sample: Expand IoT sample with consumer of temperature events (#973)
* using producer push from edge
- Loading branch information
Showing
17 changed files
with
519 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
samples/grpc/iot-service-scala/src/main/protobuf/iot/registration/SensorTwinService.proto
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
syntax = "proto3"; | ||
|
||
option java_multiple_files = true; | ||
option java_package = "iot.temperature.proto"; | ||
|
||
package iot.temperature; | ||
|
||
// gRPC definition for SensorTwinService | ||
|
||
service SensorTwinService { | ||
rpc GetTemperature (GetTemperatureRequest) returns (CurrentTemperature) {} | ||
} | ||
|
||
message GetTemperatureRequest { | ||
string sensor_id = 1; | ||
} | ||
|
||
message CurrentTemperature { | ||
string sensor_id = 1; | ||
int32 temperature = 2; | ||
} |
13 changes: 13 additions & 0 deletions
13
samples/grpc/iot-service-scala/src/main/protobuf/iot/registration/TemperatureEvents.proto
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
syntax = "proto3"; | ||
|
||
option java_multiple_files = true; | ||
option java_package = "iot.temperature.proto"; | ||
|
||
package iot.temperature; | ||
|
||
// Events consumed from external services | ||
|
||
message TemperatureRead { | ||
string sensor_id = 1; | ||
int32 temperature = 2; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,4 +15,5 @@ akka.projection.grpc { | |
|
||
iot-service { | ||
ask-timeout = 5 s | ||
temperature.projections-slice-count = 4 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
samples/grpc/iot-service-scala/src/main/resources/serialization.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
akka.actor.serialization-bindings { | ||
"iot.CborSerializable" = jackson-cbor | ||
"scalapb.GeneratedMessage" = proto | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
samples/grpc/iot-service-scala/src/main/scala/iot/temperature/SensorTwin.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package iot.temperature | ||
|
||
import akka.Done | ||
import akka.actor.typed.ActorRef | ||
import akka.actor.typed.ActorSystem | ||
import akka.actor.typed.Behavior | ||
import akka.cluster.sharding.typed.scaladsl.ClusterSharding | ||
import akka.cluster.sharding.typed.scaladsl.Entity | ||
import akka.cluster.sharding.typed.scaladsl.EntityTypeKey | ||
import akka.pattern.StatusReply | ||
import akka.persistence.typed.PersistenceId | ||
import akka.persistence.typed.state.scaladsl.DurableStateBehavior | ||
import akka.persistence.typed.state.scaladsl.Effect | ||
import iot.CborSerializable | ||
|
||
object SensorTwin { | ||
val EntityKey = EntityTypeKey[Command]("SensorTwin") | ||
|
||
sealed trait Command extends CborSerializable | ||
|
||
final case class State(temperature: Int) extends CborSerializable | ||
|
||
final case class UpdateTemperature( | ||
temperature: Int, | ||
replyTo: ActorRef[StatusReply[Done]]) | ||
extends Command | ||
|
||
final case class GetTemperature(replyTo: ActorRef[StatusReply[Int]]) | ||
extends Command | ||
|
||
def init(system: ActorSystem[_]): Unit = { | ||
ClusterSharding(system).init(Entity(EntityKey)(entityContext => | ||
SensorTwin(entityContext.entityId))) | ||
} | ||
|
||
def apply(sensorId: String): Behavior[Command] = | ||
DurableStateBehavior[Command, State]( | ||
PersistenceId(EntityKey.name, sensorId), | ||
State(0), | ||
(state, cmd) => | ||
cmd match { | ||
case UpdateTemperature(temperature, replyTo) => | ||
Effect | ||
.persist(State(temperature)) | ||
.thenReply(replyTo)(_ => StatusReply.Ack) | ||
|
||
case GetTemperature(replyTo) => | ||
Effect.reply(replyTo)(StatusReply.success(state.temperature)) | ||
}) | ||
|
||
} |
47 changes: 47 additions & 0 deletions
47
samples/grpc/iot-service-scala/src/main/scala/iot/temperature/SensorTwinServiceImpl.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package iot.temperature | ||
|
||
import java.util.concurrent.TimeoutException | ||
|
||
import scala.concurrent.Future | ||
|
||
import akka.actor.typed.ActorSystem | ||
import akka.cluster.sharding.typed.scaladsl.ClusterSharding | ||
import akka.grpc.GrpcServiceException | ||
import akka.util.Timeout | ||
import io.grpc.Status | ||
import iot.temperature.proto.SensorTwinService | ||
|
||
class SensorTwinServiceImpl(system: ActorSystem[_]) extends SensorTwinService { | ||
|
||
import system.executionContext | ||
|
||
implicit private val timeout: Timeout = | ||
Timeout.create( | ||
system.settings.config.getDuration("iot-service.ask-timeout")) | ||
|
||
private val sharding = ClusterSharding(system) | ||
|
||
override def getTemperature( | ||
in: proto.GetTemperatureRequest): Future[proto.CurrentTemperature] = { | ||
val entityRef = sharding.entityRefFor(SensorTwin.EntityKey, in.sensorId) | ||
val reply: Future[Int] = | ||
entityRef.askWithStatus(SensorTwin.GetTemperature(_)) | ||
val response = | ||
reply.map(temperature => | ||
proto.CurrentTemperature(in.sensorId, temperature)) | ||
convertError(response) | ||
} | ||
|
||
private def convertError[T](response: Future[T]): Future[T] = { | ||
response.recoverWith { | ||
case _: TimeoutException => | ||
Future.failed( | ||
new GrpcServiceException( | ||
Status.UNAVAILABLE.withDescription("Operation timed out"))) | ||
case exc => | ||
Future.failed( | ||
new GrpcServiceException( | ||
Status.INVALID_ARGUMENT.withDescription(exc.getMessage))) | ||
} | ||
} | ||
} |
Oops, something went wrong.