This repository has been archived by the owner on Dec 4, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #57 - adding MacWire with a train station example
- Loading branch information
Alexander Weber
committed
Apr 14, 2016
1 parent
ad2a300
commit 9c3d276
Showing
18 changed files
with
330 additions
and
1 deletion.
There are no files selected for viewing
73 changes: 73 additions & 0 deletions
73
chaos-examples/src/main/scala/mesosphere/chaos/examples/trains/TrainStation.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,73 @@ | ||
package mesosphere.chaos.examples.trains | ||
|
||
import akka.actor.{ActorSystem, Props} | ||
import com.softwaremill.macwire.aop.ProxyingInterceptor | ||
import com.softwaremill.macwire.wiredInModule | ||
import com.softwaremill.tagging._ | ||
import mesosphere.chaos.examples.trains.modules.impl.loading.LoadListenerActor | ||
import mesosphere.chaos.examples.trains.modules.impl.station.{Load, LoadListener} | ||
import mesosphere.chaos.examples.trains.modules.{StationModule, ModernShuntingModule, TraditionalShuntingModule, LoadingModule} | ||
|
||
object TrainStation extends App { | ||
val system = ActorSystem("trainSystem") | ||
|
||
val traditionalModules = new TraditionalShuntingModule | ||
with LoadingModule | ||
with StationModule { | ||
|
||
lazy val logEvents = ProxyingInterceptor { ctx => | ||
println(s"${ctx.target} calling method: ${ctx.method.getName}") | ||
ctx.proceed() | ||
} | ||
lazy val actorSystem = system | ||
} | ||
|
||
val modernModules = new ModernShuntingModule | ||
with LoadingModule | ||
with StationModule { | ||
lazy val logEvents = ProxyingInterceptor { ctx => | ||
println(s"${ctx.target} calling method: ${ctx.method.getName}") | ||
ctx.proceed() | ||
} | ||
lazy val actorSystem = system | ||
} | ||
|
||
println("# Traditional station:") | ||
println(traditionalModules.trainStation("Old school station.").prepareAndDispatchNextTrain()) | ||
println("\n# Modern station:") | ||
println(modernModules.trainStation("Futuristic teleporting station.").prepareAndDispatchNextTrain()) | ||
|
||
|
||
// Dynamically wired in PlugIns | ||
val wired = wiredInModule(modernModules) | ||
|
||
val pluginList = Seq(classOf[SlackPlugin]) | ||
|
||
val plugins = pluginList.map { pluginClass => | ||
wired | ||
.wireClassInstance(pluginClass) | ||
.asInstanceOf[TrainStationPlugin] | ||
} | ||
|
||
plugins.foreach(_.init()) | ||
|
||
|
||
// Actor injection | ||
|
||
// usage; statically checked ActorRef types! | ||
val loadListener = system | ||
.actorOf(Props[LoadListenerActor]) | ||
.taggedWith[LoadListener] | ||
|
||
val reactiveTrainDispatch = modernModules.createReactiveTrainDispatch(loadListener) | ||
|
||
reactiveTrainDispatch ! Load | ||
} | ||
|
||
trait TrainStationPlugin { | ||
def init(): Unit | ||
} | ||
|
||
class SlackPlugin extends TrainStationPlugin { | ||
override def init() = { println("Slack plugin initialized.") } | ||
} |
13 changes: 13 additions & 0 deletions
13
...examples/src/main/scala/mesosphere/chaos/examples/trains/modules/InterceptorLogging.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,13 @@ | ||
package mesosphere.chaos.examples.trains.modules | ||
|
||
import com.softwaremill.macwire.aop.Interceptor | ||
|
||
trait InterceptorLogging { | ||
/** | ||
* Using interceptors is a two-step process. | ||
* First, we have to declare what should be intercepted. | ||
* Ideally, this shouldn’t involve the implementation of the interceptor in any way. | ||
* Secondly, we have to define what the interceptor does - the behaviour. | ||
*/ | ||
def logEvents: Interceptor | ||
} |
17 changes: 17 additions & 0 deletions
17
chaos-examples/src/main/scala/mesosphere/chaos/examples/trains/modules/LoadingModule.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,17 @@ | ||
package mesosphere.chaos.examples.trains.modules | ||
|
||
import com.softwaremill.macwire._ | ||
import mesosphere.chaos.examples.trains.modules.impl.loading.{CarLoader, CarType, CraneController, TrainLoader} | ||
import mesosphere.chaos.examples.trains.modules.impl.shunting.PointSwitcher | ||
|
||
@Module | ||
trait LoadingModule extends InterceptorLogging { | ||
lazy val craneController = logEvents(wire[CraneController]) | ||
lazy val trainLoader = logEvents(wire[TrainLoader]) | ||
|
||
// Factories as functions | ||
lazy val carLoaderFactory = (ct: CarType) => wire[CarLoader] | ||
|
||
// dependency of the module | ||
def pointSwitcher: PointSwitcher | ||
} |
21 changes: 21 additions & 0 deletions
21
chaos-examples/src/main/scala/mesosphere/chaos/examples/trains/modules/ShuntingModule.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,21 @@ | ||
package mesosphere.chaos.examples.trains.modules | ||
|
||
import com.softwaremill.macwire._ | ||
import mesosphere.chaos.examples.trains.modules.impl.shunting._ | ||
|
||
@Module | ||
trait ShuntingModule extends InterceptorLogging { | ||
lazy val pointSwitcher = logEvents(wire[PointSwitcher]) | ||
|
||
// dependency of the module | ||
def trainShunter: TrainShunter | ||
} | ||
|
||
trait TraditionalShuntingModule extends ShuntingModule { | ||
lazy val trainCarCoupler = logEvents(wire[TrainCarCoupler]) | ||
lazy val trainShunter = logEvents(wire[TraditionalTrainShunter]) | ||
} | ||
|
||
trait ModernShuntingModule extends ShuntingModule { | ||
lazy val trainShunter = logEvents(wire[TeleportingTrainShunter]) | ||
} |
27 changes: 27 additions & 0 deletions
27
chaos-examples/src/main/scala/mesosphere/chaos/examples/trains/modules/StationModule.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,27 @@ | ||
package mesosphere.chaos.examples.trains.modules | ||
|
||
import akka.actor.{ActorSystem, ActorRef, Props} | ||
import com.softwaremill.macwire._ | ||
import com.softwaremill.tagging._ | ||
import mesosphere.chaos.examples.trains.modules.impl.loading.TrainLoader | ||
import mesosphere.chaos.examples.trains.modules.impl.station._ | ||
|
||
@Module | ||
trait StationModule extends ShuntingModule with LoadingModule { | ||
// Factory function | ||
def trainStation(name: String) = logEvents(wire[TrainStation]) | ||
|
||
// Multiple instances via tagging | ||
lazy val regularTrainLoader = wire[TrainLoader].taggedWith[Regular] | ||
lazy val liquidTrainLoader = wire[TrainLoader].taggedWith[Liquid] | ||
|
||
lazy val trainDispatch = logEvents(wire[TrainDispatch]) | ||
|
||
// Actor wiring | ||
|
||
// actor system module dependency | ||
def actorSystem: ActorSystem | ||
|
||
def createReactiveTrainDispatch(loadListener: ActorRef @@ LoadListener) = | ||
actorSystem.actorOf(Props(wire[ReactiveTrainDispatch])) | ||
} |
9 changes: 9 additions & 0 deletions
9
chaos-examples/src/main/scala/mesosphere/chaos/examples/trains/modules/StatsModule.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,9 @@ | ||
package mesosphere.chaos.examples.trains.modules | ||
|
||
import com.softwaremill.macwire._ | ||
import mesosphere.chaos.examples.trains.modules.impl.stats.{LoadingStats, ShuntingStats} | ||
|
||
class StatsModule(shuntingModule: ShuntingModule, loadingModule: LoadingModule) { | ||
lazy val loadingStats = wire[LoadingStats] | ||
lazy val shuntingStats = wire[ShuntingStats] | ||
} |
5 changes: 5 additions & 0 deletions
5
...rc/main/scala/mesosphere/chaos/examples/trains/modules/impl/loading/CraneController.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,5 @@ | ||
package mesosphere.chaos.examples.trains.modules.impl.loading | ||
|
||
class CraneController() { | ||
def controll() = println("crane moved") | ||
} |
13 changes: 13 additions & 0 deletions
13
.../main/scala/mesosphere/chaos/examples/trains/modules/impl/loading/LoadListenerActor.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,13 @@ | ||
package mesosphere.chaos.examples.trains.modules.impl.loading | ||
|
||
import akka.actor.Actor | ||
import mesosphere.chaos.examples.trains.modules.impl.station.Load | ||
|
||
case object Full | ||
|
||
class LoadListenerActor extends Actor { | ||
override def receive: Receive = { | ||
case Load => sender() ! Full | ||
case _ => println("unknown message type") | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
...es/src/main/scala/mesosphere/chaos/examples/trains/modules/impl/loading/TrainLoader.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,23 @@ | ||
package mesosphere.chaos.examples.trains.modules.impl.loading | ||
|
||
import mesosphere.chaos.examples.trains.modules.impl.loading.TrainLoader.CarLoaderFactory | ||
import mesosphere.chaos.examples.trains.modules.impl.shunting.PointSwitcher | ||
|
||
sealed trait CarType | ||
trait Coal extends CarType | ||
trait Refrigerated extends CarType | ||
|
||
class CarLoader() | ||
|
||
class TrainLoader(craneController: CraneController, | ||
pointSwitcher: PointSwitcher, | ||
carLoaderFactory: CarLoaderFactory) { | ||
def load() = { | ||
println("loaded") | ||
pointSwitcher.switch() | ||
} | ||
} | ||
|
||
object TrainLoader { | ||
type CarLoaderFactory = CarType => CarLoader | ||
} |
5 changes: 5 additions & 0 deletions
5
...src/main/scala/mesosphere/chaos/examples/trains/modules/impl/shunting/PointSwitcher.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,5 @@ | ||
package mesosphere.chaos.examples.trains.modules.impl.shunting | ||
|
||
class PointSwitcher() { | ||
def switch() = println("switched") | ||
} |
3 changes: 3 additions & 0 deletions
3
...c/main/scala/mesosphere/chaos/examples/trains/modules/impl/shunting/TrainCarCoupler.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,3 @@ | ||
package mesosphere.chaos.examples.trains.modules.impl.shunting | ||
|
||
class TrainCarCoupler() { def couple() = println("coupled") } |
16 changes: 16 additions & 0 deletions
16
.../src/main/scala/mesosphere/chaos/examples/trains/modules/impl/shunting/TrainShunter.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,16 @@ | ||
package mesosphere.chaos.examples.trains.modules.impl.shunting | ||
|
||
trait TrainShunter { def shunt() = println("shunted") } | ||
class TraditionalTrainShunter(pointSwitcher: PointSwitcher, | ||
trainCarCoupler: TrainCarCoupler) extends TrainShunter { | ||
override def shunt() = { | ||
pointSwitcher.switch() | ||
trainCarCoupler.couple() | ||
super.shunt() | ||
} | ||
} | ||
class TeleportingTrainShunter() extends TrainShunter { | ||
override def shunt() = { | ||
println("teleported") | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
...n/scala/mesosphere/chaos/examples/trains/modules/impl/station/ReactiveTrainDispatch.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,19 @@ | ||
package mesosphere.chaos.examples.trains.modules.impl.station | ||
|
||
import com.softwaremill.tagging.@@ | ||
import akka.actor.{ActorRef, Actor} | ||
import mesosphere.chaos.examples.trains.modules.impl.loading.{Full, TrainLoader} | ||
|
||
case object Load | ||
trait LoadListener | ||
|
||
class ReactiveTrainDispatch( | ||
trainLoader: TrainLoader @@ Regular, | ||
trainDispatch: TrainDispatch, | ||
loadListener: ActorRef @@ LoadListener) extends Actor { | ||
def receive = { | ||
case Load => loadListener ! Load | ||
case Full => println("reactively fully loaded") | ||
case _ => println("unknown message type") | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
.../src/main/scala/mesosphere/chaos/examples/trains/modules/impl/station/TrainDispatch.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,3 @@ | ||
package mesosphere.chaos.examples.trains.modules.impl.station | ||
|
||
class TrainDispatch() { def dispatch() = "dispatched" } |
22 changes: 22 additions & 0 deletions
22
...s/src/main/scala/mesosphere/chaos/examples/trains/modules/impl/station/TrainStation.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,22 @@ | ||
package mesosphere.chaos.examples.trains.modules.impl.station | ||
|
||
import com.softwaremill.tagging.@@ | ||
import mesosphere.chaos.examples.trains.modules.impl.loading.TrainLoader | ||
import mesosphere.chaos.examples.trains.modules.impl.shunting.TrainShunter | ||
|
||
trait Regular | ||
trait Liquid | ||
|
||
class TrainStation(name: String, | ||
trainShunter: TrainShunter, | ||
regularTrainLoader: TrainLoader @@ Regular, | ||
liquidTrainLoader: TrainLoader @@ Liquid, | ||
trainDispatch: TrainDispatch) { | ||
|
||
def prepareAndDispatchNextTrain() = { | ||
trainShunter.shunt() | ||
regularTrainLoader.load() | ||
liquidTrainLoader.load() | ||
trainDispatch.dispatch() | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
...les/src/main/scala/mesosphere/chaos/examples/trains/modules/impl/stats/StaatsModule.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,7 @@ | ||
package mesosphere.chaos.examples.trains.modules.impl.stats | ||
|
||
import mesosphere.chaos.examples.trains.modules.impl.loading.TrainLoader | ||
import mesosphere.chaos.examples.trains.modules.impl.shunting.TrainShunter | ||
|
||
class LoadingStats(trainLoader: TrainLoader) | ||
class ShuntingStats(trainShunter: TrainShunter) |
24 changes: 24 additions & 0 deletions
24
...examples/src/test/scala/mesosphere/chaos/examples/trains/modules/ShuntingModuleTest.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,24 @@ | ||
package mesosphere.chaos.examples.trains.modules | ||
|
||
import com.softwaremill.macwire.aop.NoOpInterceptor | ||
import mesosphere.chaos.examples.trains.modules.impl.shunting.PointSwitcher | ||
import org.mockito.Mockito._ | ||
import org.scalatest.FlatSpec | ||
|
||
class ShuntingModuleTest extends FlatSpec { | ||
it should "work" in { | ||
// given | ||
val mockPointSwitcher = mock(classOf[PointSwitcher]) | ||
|
||
// when | ||
val moduleToTest = new TraditionalShuntingModule { | ||
// the mock implementation will be used to wire the graph | ||
override lazy val pointSwitcher = mockPointSwitcher | ||
lazy val logEvents = NoOpInterceptor | ||
} | ||
moduleToTest.trainShunter.shunt() | ||
|
||
// then | ||
verify(mockPointSwitcher).switch() | ||
} | ||
} |
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