Skip to content

Commit 0cf0885

Browse files
chore: add preface
1 parent 05819d4 commit 0cf0885

File tree

17 files changed

+262
-45
lines changed

17 files changed

+262
-45
lines changed

.github/workflows/build.yml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Build Storm Shadow
2+
on:
3+
push:
4+
branches:
5+
- main
6+
permissions:
7+
contents: write
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v3
13+
- name: Set up JDK 11
14+
uses: actions/setup-java@v3
15+
with:
16+
java-version: '19'
17+
distribution: 'temurin'
18+
cache: 'sbt'
19+
- name: Run tests
20+
run: sbt compile
21+
- name: Upload dependency graph
22+
uses: scalacenter/sbt-dependency-submission@ab086b50c947c9774b70f39fc7f6e20ca2706c91

.scalafmt.conf

+27-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,27 @@
1-
version = "3.7.3"
2-
runner.dialect = scala213
3-
fileOverride {
4-
"glob:**/shadow/src/main/scala/**" {
5-
runner.dialect = scala3
6-
}
7-
}
1+
version = 3.7.3
2+
maxColumn = 120
3+
4+
align.preset = more
5+
align.multiline = true
6+
align.stripMargin = true
7+
8+
continuationIndent.defnSite = 2
9+
assumeStandardLibraryStripMargin = true
10+
danglingParentheses.preset = true
11+
docstrings = JavaDoc
12+
lineEndings = preserve
13+
includeCurlyBraceInSelectChains = false
14+
spaces.inImportCurlyBraces = false
15+
optIn.annotationNewlines = true
16+
17+
rewrite.rules = [Imports, RedundantBraces, SortModifiers]
18+
rewrite.imports.sort = original
19+
20+
docstrings.wrap = yes
21+
docstrings.style = Asterisk
22+
23+
newlines.afterInfix = keep
24+
rewrite.rules = [RedundantParens]
25+
trailingCommas = "always"
26+
runner.dialect = Scala213Source3
27+
docstrings.wrapMaxColumn = 80

README.md

+25-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,25 @@
1-
# reactive-app-modernization-with-scala
1+
# reactive-app-modernization-with-scala
2+
3+
## Project: Storm Shadow
4+
5+
The business people have just decided, without talking to tech at all 🤮, that they want to ship their product in the
6+
next
7+
10 hours - we only have 2 tech guys around, and we don't want to get fired, so we need to get this done real quick. We
8+
will deliver this with [Nothing But Logic](https://www.kalix.io/) and remove all complexities of the back end by
9+
inferring all infrastructure needs from our code.
10+
11+
Remember - We have to focus solely on the business logic of this extremely crude architecture they have provided us
12+
with.
13+
14+
## Architecture
15+
16+
```mermaid
17+
graph LR
18+
A[Ingetor] --> B[Processor] --> C[Carrier]
19+
D[Manager] -->|Manage Ingestion Rules| A
20+
D -->|Manage Processing Rules| B
21+
D -->|Manage Delivery Rules| C
22+
U[User] --> D
23+
```
24+
25+
> Seminar conducted for the graduating class of 2023[MCA] at Guru Gobind Singh Indraprastha University, New Delhi

build.sbt

+47-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,54 @@
11
import Dependencies._
22

33
ThisBuild / scalaVersion := "2.13.10"
4+
ThisBuild / organization := "extremeprogramming"
5+
ThisBuild / version := "1.0.0-M1"
6+
ThisBuild / licenses += ("GPL", url("https://www.gnu.org/licenses/gpl-3.0.en.html"))
7+
ThisBuild / developers += Developer(
8+
"girdharshubham",
9+
"Shubham Girdhar",
10+
11+
url("https://github.com/girdharshubham"),
12+
)
413

5-
lazy val auth = (project in file("auth"))
14+
ThisBuild / javacOptions ++= Seq(
15+
"-source",
16+
"1.19",
17+
"-target",
18+
"1.19",
19+
"-Xlint:unchecked",
20+
"-Xlint:deprecation",
21+
)
22+
23+
ThisBuild / scalacOptions ++= Seq(
24+
"-deprecation",
25+
"-encoding",
26+
"UTF-8",
27+
"-feature",
28+
"-language:existentials",
29+
"-language:higherKinds",
30+
"-language:implicitConversions",
31+
"-unchecked",
32+
"-Xlint",
33+
"-Ywarn-dead-code",
34+
"-Ywarn-numeric-widen",
35+
"-Ywarn-value-discard",
36+
)
37+
38+
lazy val rams = (project in file("."))
39+
.aggregate(manager, ingestor, processor, carrier)
40+
41+
lazy val manager = (project in file("manager"))
642
.enablePlugins(KalixPlugin)
743
.settings(
8-
libraryDependencies ++= Seq(
9-
"org.scalatest" %% "scalatest" % "3.2.15" % Test
10-
)
44+
libraryDependencies ++= Seq(scalatest),
1145
)
46+
47+
lazy val ingestor = project in file("ingestor")
48+
// .enablePlugins(KalixPlugin)
49+
50+
lazy val processor = project in file("processor")
51+
// .enablePlugins(KalixPlugin)
52+
53+
lazy val carrier = project in file("carrier")
54+
// .enablePlugins(KalixPlugin)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package extremeprogramming.carrier
2+
3+
object App {
4+
def main(args: Array[String]): Unit = {
5+
println("Carrier Subsystem")
6+
}
7+
}

docker-compose.yml

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
version: 3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package extremeprogramming.ingestor
2+
3+
object App {
4+
def main(args: Array[String]): Unit = {
5+
println("Ingestor Subsystem")
6+
}
7+
}

auth/src/main/proto/auth/api/auth_api.proto renamed to manager/src/main/proto/extremeprogramming/manager/api/api.proto

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
syntax = "proto3";
22

3-
package auth.api;
3+
package extremeprogramming.manager.api;
44

55
import "google/protobuf/empty.proto";
66
import "kalix/annotations.proto";
@@ -26,9 +26,9 @@ message LogoutRequest {}
2626
service AuthService {
2727
option (kalix.codegen) = {
2828
value_entity: {
29-
name: "auth.UserEntity"
29+
name: "extremeprogramming.manager.UserEntity"
3030
entity_type: "users"
31-
state: "auth.domain.UserState"
31+
state: "extremeprogramming.manager.domain.UserState"
3232
}
3333
};
3434
rpc Register(User) returns (google.protobuf.Empty);

auth/src/main/proto/auth/domain/user.proto renamed to manager/src/main/proto/extremeprogramming/manager/domain/user.proto

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
syntax = "proto3";
22

3-
package auth.domain;
3+
package extremeprogramming.manager.domain;
44

55
message UserState {
66
string userName = 1;

auth/src/main/scala/auth/Main.scala renamed to manager/src/main/scala/extremeprogramming/manager/Main.scala

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
package auth
1+
package extremeprogramming.manager
22

33
import kalix.scalasdk.Kalix
4+
import extremeprogramming.manager.KalixFactory
45
import org.slf4j.LoggerFactory
56

67
// This class was initially generated based on the .proto definition by Kalix tooling.
@@ -10,7 +11,7 @@ import org.slf4j.LoggerFactory
1011

1112
object Main {
1213

13-
private val log = LoggerFactory.getLogger("auth.Main")
14+
private val log = LoggerFactory.getLogger("manager.Main")
1415

1516
def createKalix(): Kalix = {
1617
// The KalixFactory automatically registers any generated Actions, Views or Entities,
@@ -23,6 +24,6 @@ object Main {
2324

2425
def main(args: Array[String]): Unit = {
2526
log.info("starting the Kalix service")
26-
createKalix().start()
27+
createKalix().start(): Unit
2728
}
2829
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
package auth
1+
package extremeprogramming.manager
22

3-
import auth.api.User
4-
import auth.domain.UserState
3+
import extremeprogramming.manager.domain.UserState
54
import com.google.protobuf.empty.Empty
65
import kalix.scalasdk.valueentity.ValueEntity
76
import kalix.scalasdk.valueentity.ValueEntityContext
@@ -17,31 +16,31 @@ class UserEntity(context: ValueEntityContext) extends AbstractUserEntity {
1716
override def emptyState: UserState = UserState()
1817

1918
override def register(
20-
currentState: UserState,
21-
user: auth.api.User
19+
currentState: UserState,
20+
user: extremeprogramming.manager.api.User,
2221
): ValueEntity.Effect[Empty] =
2322
effects.updateState(user.toDomain).thenReply(Empty())
2423

2524
override def login(
26-
currentState: UserState,
27-
loginRequest: auth.api.LoginRequest
25+
currentState: UserState,
26+
loginRequest: extremeprogramming.manager.api.LoginRequest,
2827
): ValueEntity.Effect[Empty] = effects.reply(Empty())
2928

3029
override def logout(
31-
currentState: UserState,
32-
logoutRequest: auth.api.LogoutRequest
30+
currentState: UserState,
31+
logoutRequest: extremeprogramming.manager.api.LogoutRequest,
3332
): ValueEntity.Effect[Empty] = effects.reply(Empty())
3433

3534
}
3635

3736
object UserEntity {
38-
implicit class UserStateExtensions(val user: auth.api.User) extends AnyVal {
37+
implicit class UserStateExtensions(val user: extremeprogramming.manager.api.User) extends AnyVal {
3938
def toDomain: UserState = UserState(
4039
userName = user.userName,
4140
firstName = user.firstName,
4241
lastName = user.lastName,
4342
email = user.email,
44-
enabled = user.enabled
43+
enabled = user.enabled,
4544
)
4645
}
4746
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package extremeprogramming.manager
2+
3+
import org.scalatest.matchers.should.Matchers
4+
import org.scalatest.wordspec.AnyWordSpec
5+
6+
class UserEntitySpec
7+
extends AnyWordSpec
8+
with Matchers {
9+
10+
"UserEntity" must {
11+
12+
"have example test that can be removed" in {
13+
val _ = UserEntityTestKit(new UserEntity(_))
14+
pending
15+
// use the testkit to execute a command
16+
// and verify final updated state:
17+
// val result = service.someOperation(SomeRequest)
18+
// verify the reply
19+
// val reply = result.getReply()
20+
// reply shouldBe expectedReply
21+
// verify the final state after the command
22+
// service.currentState() shouldBe expectedState
23+
}
24+
25+
"handle command Register" in {
26+
val _ = UserEntityTestKit(new UserEntity(_))
27+
pending
28+
// val result = service.register(extremeprogramming.manager.api.User(...))
29+
}
30+
31+
"handle command Login" in {
32+
val _ = UserEntityTestKit(new UserEntity(_))
33+
pending
34+
// val result = service.login(extremeprogramming.manager.api.LoginRequest(...))
35+
}
36+
37+
"handle command Logout" in {
38+
val _ = UserEntityTestKit(new UserEntity(_))
39+
pending
40+
// val result = service.logout(extremeprogramming.manager.api.LogoutRequest(...))
41+
}
42+
43+
}
44+
}

auth/src/test/scala/auth/api/AuthServiceIntegrationSpec.scala renamed to manager/src/test/scala/extremeprogramming/manager/api/AuthServiceIntegrationSpec.scala

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
package auth.api
1+
package extremeprogramming.manager.api
22

3-
import akka.actor.ActorSystem
4-
import auth.Main
5-
import com.google.protobuf.empty.Empty
3+
import extremeprogramming.manager.Main
64
import kalix.scalasdk.testkit.KalixTestKit
75
import org.scalatest.BeforeAndAfterAll
86
import org.scalatest.concurrent.ScalaFutures

auth/src/test/scala/auth/UserEntitySpec.scala renamed to manager/src/test/scala/manager/UserEntitySpec.scala

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
1-
package auth
1+
package manager
22

3-
import auth.domain.UserState
4-
import com.google.protobuf.empty.Empty
5-
import kalix.scalasdk.testkit.ValueEntityResult
6-
import kalix.scalasdk.valueentity.ValueEntity
3+
import extremeprogramming.manager.UserEntity._
4+
import extremeprogramming.manager.domain.UserState
5+
import extremeprogramming.manager.{UserEntity, UserEntityTestKit}
76
import org.scalatest.matchers.should.Matchers
87
import org.scalatest.wordspec.AnyWordSpec
9-
import UserEntity._
108

119
class UserEntitySpec extends AnyWordSpec with Matchers {
1210

13-
val girdharshubham = auth.api.User(
11+
val girdharshubham = extremeprogramming.manager.api.User(
1412
userName = "girdharshubham",
1513
firstName = "Shubham",
1614
lastName = "Girdhar",
17-
15+
email = "[email protected]",
1816
)
1917

2018
"UserEntity" must {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package manager.api
2+
3+
4+
import extremeprogramming.manager.Main
5+
import kalix.scalasdk.testkit.KalixTestKit
6+
import org.scalatest.BeforeAndAfterAll
7+
import org.scalatest.concurrent.ScalaFutures
8+
import org.scalatest.matchers.should.Matchers
9+
import org.scalatest.time.Millis
10+
import org.scalatest.time.Seconds
11+
import org.scalatest.time.Span
12+
import org.scalatest.wordspec.AnyWordSpec
13+
14+
// This class was initially generated based on the .proto definition by Kalix tooling.
15+
//
16+
// As long as this file exists it will not be overwritten: you can maintain it yourself,
17+
// or delete it so it is regenerated as needed.
18+
19+
class AuthServiceIntegrationSpec
20+
extends AnyWordSpec
21+
with Matchers
22+
with BeforeAndAfterAll
23+
with ScalaFutures {
24+
25+
implicit private val patience: PatienceConfig =
26+
PatienceConfig(Span(5, Seconds), Span(500, Millis))
27+
28+
private val testKit = KalixTestKit(Main.createKalix()).start()
29+
30+
"AuthService" must {
31+
32+
"have example test that can be removed" in {
33+
pending
34+
// use the gRPC client to send requests to the
35+
// proxy and verify the results
36+
}
37+
38+
}
39+
40+
override def afterAll(): Unit = {
41+
testKit.stop()
42+
super.afterAll()
43+
}
44+
}

0 commit comments

Comments
 (0)