lagom / online-auction-java Goto Github PK
View Code? Open in Web Editor NEWLicense: Other
License: Other
Using the new feature (lagom/lagom#762) allowing start and stop code to be hooked to runAll
, it'd be useful to take elasticsearch in online-auction as an example for the feature.
A fresh clone of master
is not runnable:
sbt runAll
Expected
Default user home is displayed
Actual
[warn] o.a.k.c.NetworkClient - Error while fetching metadata with correlation id 1 : {item-ItemEvent=LEADER_NOT_AVAILABLE}
[warn] o.a.k.c.NetworkClient - Error while fetching metadata with correlation id 2 : {item-ItemEvent=LEADER_NOT_AVAILABLE}
[warn] o.a.k.c.NetworkClient - Error while fetching metadata with correlation id 1 : {bidding-BidEvent=LEADER_NOT_AVAILABLE}
[info] o.h.v.i.u.Version - HV000001: Hibernate Validator 5.2.4.Final
[info] Service webGateway listening for HTTP on 0:0:0:0:0:0:0:0:60496
[info] Service searchImpl listening for HTTP on 0:0:0:0:0:0:0:0:55320
[info] Service itemImpl listening for HTTP on 0:0:0:0:0:0:0:0:53203
[info] Service transactionImpl listening for HTTP on 0:0:0:0:0:0:0:0:51742
[info] Service biddingImpl listening for HTTP on 0:0:0:0:0:0:0:0:58427
[info] Service userImpl listening for HTTP on 0:0:0:0:0:0:0:0:56181
[info] (Services started, press enter to stop and go back to the console...)
[error] application -
! @74f86hh4b - Internal server error, for (GET) [/my/items/created] ->
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[CompletionException: java.util.NoSuchElementException: No value present]]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:293)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:220)
at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
at play.api.DefaultGlobal$.onError(GlobalSettings.scala:188)
at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:99)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:346)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:345)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
Caused by: java.util.concurrent.CompletionException: java.util.NoSuchElementException: No value present
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
at java.util.concurrent.CompletableFuture.biApply(CompletableFuture.java:1107)
at java.util.concurrent.CompletableFuture$BiApply.tryFire(CompletableFuture.java:1070)
... 5 common frames omitted
Caused by: java.util.NoSuchElementException: No value present
at java.util.Optional.get(Optional.java:135)
at views.html.myItems_Scope0$myItems_Scope1$myItems.apply(myItems.template.scala:41)
at views.html.myItems_Scope0$myItems_Scope1$myItems.render(myItems.template.scala:110)
at views.html.myItems.render(myItems.template.scala)
at controllers.ProfileController.lambda$null$0(ProfileController.java:41)
at java.util.concurrent.CompletableFuture.biApply(CompletableFuture.java:1105)
at java.util.concurrent.CompletableFuture$BiApply.tryFire(CompletableFuture.java:1070)
at java.util.concurrent.CompletableFuture$Completion.exec(CompletableFuture.java:443)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
When deploying the application in ConductR it deems unusable due to a route collision.
The collision is for the route:
POST /user
that should only be resolved by webGateway
as described in https://github.com/lagom/online-auction-java/blob/master/web-gateway/conf/routes#L6
but the default bundle.conf
for users-impl
is configuring the service as:
version = "1"
name = "userimpl"
compatibilityVersion = "1"
system = "userimpl"
systemVersion = "1"
nrOfCpus = 0.1
memory = 402653184
diskSpace = 200000000
roles = ["web"]
components = {
userimpl = {
description = "userImpl"
file-system-type = "universal"
start-command = ["userimpl/bin/userimpl", "-J-Xms134217728", "-J-Xmx134217728", "-Dhttp.address=$USER_BIND_IP", "-Dhttp.port=$USER_BIND_PORT", "-Dplay.crypto.secret=75736572496d706c"]
endpoints = {
"user" = {
bind-protocol = "http"
bind-port = 0
services = ["http://:9000/user"] <-- I suspect this is the cause of the collision.
},
"akka-remote" = {
bind-protocol = "tcp"
bind-port = 0
services = []
}
}
}
}
UPDATE: similar collisions with /item
and /search
.
Use Travis CI's support for databases and ScalaTest tagging to run search-impl
integration tests with ElasticSearch.
A possible issue will be the version miss-match between Travis options and our code/API client.
See also lagom/lagom#569
We discussed converting this project to Maven as an example for Maven/Java users.
Our current thinking is to have both build.sbt
and pom.xml
files on the master
branch, and then to also have long lived sbt
and maven
branches that strip the opposite build files out.
Using scala code (case classes) to create value objects and then use them from java is no possible.
sbt compilation will fail with a symbol not found
message.
AuctionScheduler
is not cluster aware: it will run its scheduled task on all nodes.
We should demonstrate use of a cluster singleton to ensure it only runs on one node.
(We should port this change to Scala as well.)
As per email if we should provide username and password based login. We get two options for it.
Basic Auth
with saving username and password within User
itself.OAuth/OAuth2
by using any third party lib.In basic auth it will need every call to send username and password. That is generally not favourable though.
I pulled down the project and tried to runAll but I just get into a loop of not being able to locate Cassandra.
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: ServiceLocator is not bound
[warn] a.p.c.j.CassandraJournal - Failed to connect to Cassandra and initialize. It will be retried on demand. Caused by: ServiceLocator is not bound
[error] a.a.OneForOneStrategy - Ask timed out on [Actor[akka://transactionImpl-application/user/cassandraOffsetStorePrepare-singleton/singleton/cassandraOffsetStorePrepare#-352900502]] after [20000 ms]. Sender[Actor[akka://transactionImpl-application/user/cassandraOffsetStorePrepare-singleton/singleton/cassandraOffsetStorePrepare#-352900502]] sent message of type "com.lightbend.lagom.internal.persistence.cluster.ClusterStartupTaskActor$Execute$".
akka.pattern.AskTimeoutException: Ask timed out on [Actor[akka://transactionImpl-application/user/cassandraOffsetStorePrepare-singleton/singleton/cassandraOffsetStorePrepare#-352900502]] after [20000 ms]. Sender[Actor[akka://transactionImpl-application/user/cassandraOffsetStorePrepare-singleton/singleton/cassandraOffsetStorePrepare#-352900502]] sent message of type "com.lightbend.lagom.internal.persistence.cluster.ClusterStartupTaskActor$Execute$".
at akka.pattern.PromiseActorRef$$anonfun$1.apply$mcV$sp(AskSupport.scala:604) ~[akka-actor_2.11-2.4.17.jar:na]
at akka.actor.Scheduler$$anon$4.run(Scheduler.scala:126) ~[akka-actor_2.11-2.4.17.jar:na]
at scala.concurrent.Future$InternalCallbackExecutor$.unbatchedExecute(Future.scala:601) ~[scala-library-2.11.8.jar:na]
at scala.concurrent.BatchingExecutor$class.execute(BatchingExecutor.scala:109) ~[scala-library-2.11.8.jar:na]
at scala.concurrent.Future$InternalCallbackExecutor$.execute(Future.scala:599) ~[scala-library-2.11.8.jar:na]
at akka.actor.LightArrayRevolverScheduler$TaskHolder.executeTask(LightArrayRevolverScheduler.scala:329) ~[akka-actor_2.11-2.4.17.jar:na]
at akka.actor.LightArrayRevolverScheduler$$anon$4.executeBucket$1(LightArrayRevolverScheduler.scala:280) ~[akka-actor_2.11-2.4.17.jar:na]
at akka.actor.LightArrayRevolverScheduler$$anon$4.nextTick(LightArrayRevolverScheduler.scala:284) ~[akka-actor_2.11-2.4.17.jar:na]
at akka.actor.LightArrayRevolverScheduler$$anon$4.run(LightArrayRevolverScheduler.scala:236) ~[akka-actor_2.11-2.4.17.jar:na]
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_121]
localhost:8000/services
[{"name":"cas_native","url":"tcp://127.0.0.1:4000/cas_native"},{"name":"kafka_native","url":"tcp://localhost:9092/kafka_native"},{"name":"elastic-search","url":"http://127.0.0.1:9200"}]
Add inline instructions to create items, start an auction and bid on the item.
The readme should explain that you open the UI with a browser and how (in general terms) to start an auction.
See #6 (comment)
Current state:
TransportException
: BidValidationException
which doesn't implement equals
and hashCode
ctx.commandFailed
with UpdateFailureException
which isn't a subclass of TransportException and implements equals
and hashCode
ctx.commandFailed
with NotFound
which is a subclass of TransportExceptionWe need to tidy up this, whether throwing an exception or using ctx.commandFailed
in all services
Current readme links to documentation introducing hello world. It'd be better if the links pointed to "https://www.lagomframework.com/get-started-java-maven.html" (and sbt equivalent) instead of "https://www.lagomframework.com/documentation/1.3.x/java/GettingStartedMaven.html"
It's be good if we could show off the usage of lagomExternalJavadslProject
in online-auction. It's a rather unknown feature we could demonstrate further to complement the docs
First page of the UserInfo table is currently not being fetched .
This project is no longer properly working with $ activator runAll
On gitter I got to know that lagom is gradually moving out of activator. I suggest we should remove activator and activator.bat
The bid is accepted, and the current price is updated to $10, to match the reserve.
The bid is accepted, but the current price stays at $5, below the reserve.
This also happens if you were to bid, for example, $7.
There is already a comprehensive suite of tests in AuctionEntityTest.java
, tests for these scenarios should be added first, to reproduce the problem, then the bug in AuctionEntity
can be fixed.
(see lagom/online-auction-scala#24)
The project's Readme should list:
Add inline instructions on how/when to search an item and how the feature is enabled.
An eager user should be helped/guided into enabling and using the search feature. That means linking to the repo README.md on how to enable a local elasticsearch
instance and explaining how search filters work.
Bid in bidding-api and Bid in bidding-impl are duplicate. I propose we should remove the Bid.java in bidding-impl
When running the application on a clean environment, if elasticsearch is not running and a user creates an item then that item will not be searchable.
Steps to reproduce:
data/
folder is empty so that no index with previous data exists and start elasticsearchExpected:
Actual:
Comments:
I haven't tracked down all possible scenarios where this issue happens. Here's some suspicions that can help narrow the cases:
item-service
or the bid-events
messages from kafka are lost (I highly doubt that since search-service
reuses a lot of code to consume from both topics)shouldEmitEventWhenSettingDeliveryPrice
, shouldForbidSettingDeliveryPriceByNonSeller
shouldSetDeliveryPrice
ServiceCall<Integer, Done> setDeliveryPrice(UUID itemId)
There's at least one link to Lagom Documentation pointing at java/1.2.x version of the docs.
See https://github.com/lagom/online-auction-java/blame/master/README.md#L36
#11 introduced a custom serializer for java Optional (see https://github.com/lagom/online-auction-java/blob/master/item-impl/src/main/resources/application.conf#L11-L19 and related class/es).
When this is provided by Akka the custom serializer should be removed and the provided by used instead.
Add inline instructions to create several users
./item-impl/src/main/java/com/example/auction/item/impl/ItemServiceImpl.java:82:
// TODO: remove this PItem from here and pass the 3 values in the command?
./item-impl/src/main/java/com/example/auction/item/impl/PItemCommand.java:23:
// TODO: change payload of this command.
PItemCommand.CreateItem (item-impl) should take 3 params:
And remove PItem object in ItemServiceImpl#createItem
When you create an auction in Japanese Yen, it's impossible to enter a valid increment, if it's less than 50, you get an error of invalid.step, if it's more than 50, you get an error of invalid.increment.
I cloned this (as sbt project) into IntelliJ, Java 8, and got the following:
Information:5/1/2017 8:11 PM - Compilation completed with 12 errors and 0 warnings in 2m 1s 500ms
C:\Users\RLOPACs\online-auction-java\tools\src\main\java\com\example\auction\pagination\PaginatedSequence.java
Error:(3, 14) java: package lombok does not exist
Error:(4, 24) java: package org.pcollections does not exist
Error:(9, 2) java: cannot find symbol
symbol: class Value
Error:(11, 5) java: cannot find symbol
symbol: class PSequence
location: class com.example.auction.pagination.PaginatedSequence
Error:(16, 30) java: cannot find symbol
symbol: class PSequence
location: class com.example.auction.pagination.PaginatedSequence
Error:(3, 12) java: package akka does not exist
Error:(24, 35) java: cannot find symbol
symbol: class Done
location: class com.example.core.CompletionStageUtils
Error:(35, 39) java: cannot find symbol
symbol: class Done
location: class com.example.core.CompletionStageUtils
Error:(36, 74) java: cannot find symbol
symbol: variable Done
location: class com.example.core.CompletionStageUtils
Error:(36, 74) java: cannot find symbol
symbol: variable Done
location: class com.example.core.CompletionStageUtils
If this is really a Java example then we should not require Scala code. See https://github.com/lagom/online-auction-java/blob/master/web-gateway/src/main/java/controllers/package.scala
Right now, the getUsers
service implementation is not ideal:
// Note this should never make production....
return req -> currentIdsQuery.currentPersistenceIds()
.filter(id -> id.startsWith("PUserEntity"))
.mapAsync(4, id -> entityRef(id.substring(11)).ask(PUserCommand.GetPUser.INSTANCE))
.filter(Optional::isPresent)
.map(user -> Mappers.toApi(user.get()))
.runWith(Sink.seq(), mat)
.thenApply(TreePVector::from);
As you can tell from the comment, this code is a quick hack... not something that should be considered a good example of writing a Lagom service.
It has a few problems:
This service call is used by the web-gateway application to load a list of all users in the Nav
. This is then used in turn for different purposes:
userService.getUser
for each ID, since all of the user information was already loaded and cached locally for the navigation barThese can be replaced by different means.
In the navigation bar, it might be better to show a bounded list of recently-created users. For example, we could put the ten most recently-created users in the list, rather than all of the users in the system. For most demo purposes, it will be exactly the same, since most people won't create that many users. However, if we decide to extend the demo to create users automatically (see #110 for example) then we might want to include a script that creates many more than ten users.
This is a perfect case for a read-side table in Lagom. This would look similar to the existing read-side processor in the item service and the one currently under review in the transaction service (#106). It would maintain a table of users and their creation date that could be queried by the service implementation in a new getRecentUsers
service call. We would need to extend the PUserCreated
event to carry a createdAt
timestamp.
I think that using the navigation to look up user details, rather than making calls to userService.getUser(id)
, could be considered a premature optimization. I suggest we undo that and stick with making the calls for now.
If we want to demonstrate optimizations in the future, we have a few options:
getUser(id)
but maintain a local cache, so it doesn't have to be called as oftengetUsers()
call that returns all users with a call that takes a list of user IDs to returnweb-gateway
listen to these events and maintain its own internal copy of user display namesCurrently, the private copy for a class of API project is PXyz (like PItem
, PItemState
, etc) or sometimes it's the exact same name with only a package difference.
We should settle a naming convention
#121 was merged, next steps are related to updating the existing tests to use the new testkit
project
Since all source code for testkit
project was extracted from Item service, I only updated the dependencies in that service
While working on PR #61 the main comand to run the tests sbt +test
changed and the current command is not executing the tests cross-scala version: sbt -DenableElasticsearch=true test
.
This is probably what we want but I'd like to double check it was not added on purpose to demo a particular feature.
/cc @jroper
./item-api/src/main/java/com/example/auction/item/api/PaginatedSequence.java:9:
// TODO: move to a common sbt project to reuse from searchApi
./search-api/src/main/java/com/example/auction/search/api/SearchResult.java:7:
// TODO: migrate to PaginatedSequence and reuse code. Needs moving PaginatedSequence to a shared project.
The web frontend is missing i18n keys for some validation errors, such as invalid.step.
After reading: lagom/lagom#287 (comment)
And noticing: https://github.com/lagom/lagom/pull/190/files#diff-024a57e412aadbaf28e63f03c73d6cc7R22
Maybe:
https://github.com/ignasi35/online-auction-java/blob/integration-tests-on-item-service/item-impl/src/test/java/com/example/auction/item/impl/ItemServiceImplIntegrationTest.java#L241
could be rewritten using kafka-testkit.
A possible outcome of this task is that kafka-testkit might need improving.
Readme.md could contain a link on how to get sbt
installed.
After #61 was merged the jobs in Travis are run using sudo: required
. This takes the build out of a container into a VM where sudo
can be used.
Without that restriction it may be possible to install elasticsearch by other means.
There may still be a restriction wrt installing the exact version we need to run the tests though.
Currently the initial experience for someone importing this project into their IDE is to see errors.
The README should mention that they should install this plugin to make it import cleanly:
Add a feature-flag (enabled by default) to display inline instructions on the user's UI. This means adding text snippets in the rendered HTML so that an eager user gets info in the actual UI when using the app.
Having inline instructions should help a new user get a better understanding of what can be done with the app once started. The feature flag will hide the inline instructions and is meant to remove noise if/when demoing the app.
This feature flag will control the data added in #59 (wip #68 ) , #58(done), #57(done) and #56 (done).
The existence of this inline help should be introduced in the README.md.
The steps to disable the feature should be documented in the repo README.md.
./item-impl/src/main/java/com/example/auction/item/impl/CassandraReadSideUtils.java:11:
// TODO: move to core?
./tools/src/main/java/com/example/core/CompletionStageUtils.java:14:
// TODO: move to core?
Move CassandraReadSideUtils (item-impl) and CompetionStageUtils (tools) into the core Lagom framework
It is cumbersome to create multiple users and at least one item before you can actually exercise the app and bid on something. It would be nice to add a script that loads a few users and items so that someone who downloads and runs online auction could observe the main functionality right away. They could still add other users and items if they wish.
Lagom 1.3.0 introduces some features that should be showcased in online-auction-java:
ProducerStub
for testing Broker consumptionservice-name
and acls
configurations with bindServiceInfo
programmatic approach.When installing the app in ConductR the web-gateway
fails to start:
1) Could not find a suitable constructor in com.lightbend.lagom.javadsl.api.ServiceInfo. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
at com.lightbend.lagom.javadsl.api.ServiceInfo.class(ServiceInfo.java:13)
while locating com.lightbend.lagom.javadsl.api.ServiceInfo
for parameter 2 at com.lightbend.lagom.internal.client.ServiceClientImplementor.<init>(ServiceClientImplementor.scala:44)
while locating com.lightbend.lagom.internal.client.ServiceClientImplementor
for parameter 3 at com.lightbend.lagom.internal.client.ServiceClientLoader.<init>(ServiceClientLoader.scala:16)
while locating com.lightbend.lagom.internal.client.ServiceClientLoader
for field at com.lightbend.lagom.internal.client.ServiceClientProvider.loader(ServiceClientLoader.scala:37)
at com.lightbend.lagom.javadsl.client.ServiceClientGuiceSupport.bindClient(ServiceClientGuiceSupport.java:14) (via modules: com.google.inject.util.Modules$OverrideModule -> Module)
2) Could not find a suitable constructor in com.lightbend.lagom.javadsl.api.ServiceInfo. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
at com.lightbend.lagom.javadsl.api.ServiceInfo.class(ServiceInfo.java:13)
while locating com.lightbend.lagom.javadsl.api.ServiceInfo
for parameter 2 at com.lightbend.lagom.internal.client.ServiceClientImplementor.<init>(ServiceClientImplementor.scala:44)
while locating com.lightbend.lagom.internal.client.ServiceClientImplementor
for parameter 3 at com.lightbend.lagom.internal.client.ServiceClientLoader.<init>(ServiceClientLoader.scala:16)
while locating com.lightbend.lagom.internal.client.ServiceClientLoader
for field at com.lightbend.lagom.internal.client.ServiceClientProvider.loader(ServiceClientLoader.scala:37)
at com.lightbend.lagom.javadsl.client.ServiceClientGuiceSupport.bindClient(ServiceClientGuiceSupport.java:14) (via modules: com.google.inject.util.Modules$OverrideModule -> Module)
3) Could not find a suitable constructor in com.lightbend.lagom.javadsl.api.ServiceInfo. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
at com.lightbend.lagom.javadsl.api.ServiceInfo.class(ServiceInfo.java:13)
while locating com.lightbend.lagom.javadsl.api.ServiceInfo
for parameter 2 at com.lightbend.lagom.internal.client.ServiceClientImplementor.<init>(ServiceClientImplementor.scala:44)
while locating com.lightbend.lagom.internal.client.ServiceClientImplementor
for parameter 3 at com.lightbend.lagom.internal.client.ServiceClientLoader.<init>(ServiceClientLoader.scala:16)
while locating com.lightbend.lagom.internal.client.ServiceClientLoader
for field at com.lightbend.lagom.internal.client.ServiceClientProvider.loader(ServiceClientLoader.scala:37)
at com.lightbend.lagom.javadsl.client.ServiceClientGuiceSupport.bindClient(ServiceClientGuiceSupport.java:14) (via modules: com.google.inject.util.Modules$OverrideModule -> Module)
4) Could not find a suitable constructor in com.lightbend.lagom.javadsl.api.ServiceInfo. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
at com.lightbend.lagom.javadsl.api.ServiceInfo.class(ServiceInfo.java:13)
while locating com.lightbend.lagom.javadsl.api.ServiceInfo
for parameter 2 at com.lightbend.lagom.internal.client.ServiceClientImplementor.<init>(ServiceClientImplementor.scala:44)
while locating com.lightbend.lagom.internal.client.ServiceClientImplementor
for parameter 3 at com.lightbend.lagom.internal.client.ServiceClientLoader.<init>(ServiceClientLoader.scala:16)
while locating com.lightbend.lagom.internal.client.ServiceClientLoader
for field at com.lightbend.lagom.internal.client.ServiceClientProvider.loader(ServiceClientLoader.scala:37)
at com.lightbend.lagom.javadsl.client.ServiceClientGuiceSupport.bindClient(ServiceClientGuiceSupport.java:14) (via modules: com.google.inject.util.Modules$OverrideModule -> Module)
4 errors
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
at com.google.inject.Guice.createInjector(Guice.java:96)
at com.google.inject.Guice.createInjector(Guice.java:84)
at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:181)
at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:123)
at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
at com.typesafe.conductr.bundlelib.play.api.ConductRApplicationLoader.load(ConductRApplicationLoader.scala:21)
at play.core.server.ProdServerStart$.start(ProdServerStart.scala:47)
at play.core.server.ProdServerStart$.main(ProdServerStart.scala:22)
at play.core.server.ProdServerStart.main(ProdServerStart.scala)
17:14:08 accd4f3a7956 Component webgateway exited with 255
Stopping bundle
That's a play App trying to invoke bindClient()
but there's no ServiceInfoProvider
available causing the Guice creation to fail.
Creating a ServiceInfoProvider
in ServiceClientGuiceSupport
has some undesired effects on ServiceLocator and ServiceRegistry.
./item-impl/src/main/java/com/example/auction/item/impl/ItemServiceImpl.java:53:
// TODO: doc this.
Write doc comments for the Javadoc in item-impl: ItemServiceImpl#handleBidEvent. Also complete the doc comments for this services API (following the example in bidding-api and item-api):
Add inline instructions on how/when a user can edit an item.
An eager user should have some brief info on how/when an item can be edited (item ownership, item status, etc...)
PItem
and PItemState
should be merged. This change will require JSON Evolutions which is why I think it'd better be done as a separate PR.
Current master
, transaction service is subscribed to items topic.
Through that topic, an AuctionFinished
event may be received. That event contains an Optional<UUID> winner
but there may be auctions without winner.
Current code assumes the Optional<UUID> winner
will always exist:
When there's no winner that code crashes and subscription becomes useless.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.