Git Product home page Git Product logo

activator-lagom-cargotracker's Introduction

lagom-cargotracker

A cargo tracker application built with Lagom.

The core concepts of reactive microservices have been introduced by Jonas Bonér in his report Reactive Microservices Architecture. Lagom is the implementation of the described concepts. To find a good example to implement a Microservices based system with Lagom, we just needed to look into Eric Evans' book Domain-Driven Design: Tackling Complexity in the Heart of Software and use the discussed example, the Cargo Tracker. The example in this repository follows this idea and is meant to be a starting point to build a full blown Lagom based cargo tracker.

Further Readings

Community Contributions

Contributions welcome! Feel free to fork the example and help to build it out.

License

This software is licensed under the Apache 2 license, quoted below.

Copyright (C) 2016 Lightbend Inc. (https://www.lightbend.com).

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

activator-lagom-cargotracker's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

activator-lagom-cargotracker's Issues

Event Sourcing Question

I really enjoyed your book, Developing Reactive Microservices and appreciated the Cargo tracker example code. I had a question, specifically around event sourcing. My understanding is event sourcing provides a clean solution to the classic problem of ensuring that both state updates and events are sent in a single operation. It solves this problem by essentially removing a separate state update and instead having the events be the authority and state can be built from those events later. This article provides a great description:

https://www.nginx.com/blog/event-driven-data-management-microservices/

Given that, I'm confused by the cargo tracker example code. When I look at RegistrationServiceImpl.register(), a Cargo immutable is published to the "topic" topic, then the RegisterCargo command is sent to the PersistentEntity (CargoEntity).

https://github.com/lagom/activator-lagom-cargotracker/blob/master/registration-impl/src/main/java/sample/cargotracker/registration/impl/RegistrationServiceImpl.java#L65-L71

I have two issues/questions about this.

First, the Cargo is published to the topic before the CargoEntity has been called, which determines whether it's a valid command or not, given the user inputs. This causes invalid Cargo objects to be published to the topic, which seems like undesirable behavior to me. This is a minor point, but I wanted to bring it up to make sure I'm not missing something here.

Second, and more importantly, the topic appears to be the mechanism for sending events to other services (or in this case the same service). Is that correct or should I be viewing topics as a way to send messages between actors within the same microservice? If topics are the way to send events to other services, then don't you have the same problem of sending a command to the PersistentEntity and then separately publishing an event to a topic? If the process crashes between these operations, you would persist the event generated by the command, but the Cargo topic publish would be lost. Does Lagom somehow ensure both of these happen, maybe by retrying the request?

If topics are not the mechanism used to publish events to other services, then how would you do this in lagom? Are you supposed to publish events to a topic as a side effect in your event handler function in the persistent entity class, i.e., in here?

https://github.com/lagom/activator-lagom-cargotracker/blob/master/registration-impl/src/main/java/sample/cargotracker/registration/impl/CargoEntity.java#L70-L75

I'd appreciate any clarifications you can provide. I'm very excited about Lagom's potential and am trying to understand how I can leverage it.

Windows sbt failed

[info] downloading https://repo1.maven.org/maven2/io/netty/netty/3.8.0.Final/netty-3.8.0.Final.jar ...
[info] [SUCCESSFUL ] io.netty#netty;3.8.0.Final!netty.jar(bundle) (44384ms)
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: com.lightbend.lagom#build-link;1.0.0-M1: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn] Note: Unresolved dependencies path:
[warn] com.lightbend.lagom:build-link:1.0.0-M1
[warn] +- com.lightbend.lagom:lagom-sbt-plugin:1.0.0-M1 (scalaVersion=2.10, sbtVersion=0.13) (D:\SkyDrive\work\activator-lagom-cargotracker\project\plugins.sbt#L1-2)
[warn] +- default:activator-lagom-cargotracker-build:0.1-SNAPSHOT (scalaVersion=2.10, sbtVersion=0.13)
sbt.ResolveException: unresolved dependency: com.lightbend.lagom#build-link;1.0.0-M1: not found
at sbt.IvyActions$.sbt$IvyActions$$resolve(IvyActions.scala:313)
at sbt.IvyActions$$anonfun$updateEither$1.apply(IvyActions.scala:191)
at sbt.IvyActions$$anonfun$updateEither$1.apply(IvyActions.scala:168)
at sbt.IvySbt$Module$$anonfun$withModule$1.apply(Ivy.scala:156)
at sbt.IvySbt$Module$$anonfun$withModule$1.apply(Ivy.scala:156)
at sbt.IvySbt$$anonfun$withIvy$1.apply(Ivy.scala:133)
at sbt.IvySbt.sbt$IvySbt$$action$1(Ivy.scala:57)
at sbt.IvySbt$$anon$4.call(Ivy.scala:65)
at xsbt.boot.Locks$GlobalLock.withChannel$1(Locks.scala:93)
at xsbt.boot.Locks$GlobalLock.xsbt$boot$Locks$GlobalLock$$withChannelRetries$1(Locks.scala:78)
at xsbt.boot.Locks$GlobalLock$$anonfun$withFileLock$1.apply(Locks.scala:97)
at xsbt.boot.Using$.withResource(Using.scala:10)
at xsbt.boot.Using$.apply(Using.scala:9)
at xsbt.boot.Locks$GlobalLock.ignoringDeadlockAvoided(Locks.scala:58)
at xsbt.boot.Locks$GlobalLock.withLock(Locks.scala:48)
at xsbt.boot.Locks$.apply0(Locks.scala:31)
at xsbt.boot.Locks$.apply(Locks.scala:28)
at sbt.IvySbt.withDefaultLogger(Ivy.scala:65)
at sbt.IvySbt.withIvy(Ivy.scala:128)
at sbt.IvySbt.withIvy(Ivy.scala:125)
at sbt.IvySbt$Module.withModule(Ivy.scala:156)
at sbt.IvyActions$.updateEither(IvyActions.scala:168)
at sbt.Classpaths$$anonfun$sbt$Classpaths$$work$1$1.apply(Defaults.scala:1439)
at sbt.Classpaths$$anonfun$sbt$Classpaths$$work$1$1.apply(Defaults.scala:1435)
at sbt.Classpaths$$anonfun$doWork$1$1$$anonfun$90.apply(Defaults.scala:1470)
at sbt.Classpaths$$anonfun$doWork$1$1$$anonfun$90.apply(Defaults.scala:1468)
at sbt.Tracked$$anonfun$lastOutput$1.apply(Tracked.scala:37)
at sbt.Classpaths$$anonfun$doWork$1$1.apply(Defaults.scala:1473)
at sbt.Classpaths$$anonfun$doWork$1$1.apply(Defaults.scala:1467)
at sbt.Tracked$$anonfun$inputChanged$1.apply(Tracked.scala:60)
at sbt.Classpaths$.cachedUpdate(Defaults.scala:1490)
at sbt.Classpaths$$anonfun$updateTask$1.apply(Defaults.scala:1417)
at sbt.Classpaths$$anonfun$updateTask$1.apply(Defaults.scala:1369)
at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40)
at sbt.std.Transform$$anon$4.work(System.scala:63)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:228)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:228)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
at sbt.Execute.work(Execute.scala:237)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:228)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:228)
at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:28)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
error sbt.ResolveException: unresolved dependency: com.lightbend.lagom#build-link;1.0.0-M1: not found
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.