-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EventSourcedEntityHandler generation and registration via provider #231
Conversation
* also split of java-customer-registry sampel into two; one for value entity and another for event sourced
e9e5d34
to
a80a138
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
maven-java/akkaserverless-maven-archetype-event-sourced-entity/pom.xml
Outdated
Show resolved
Hide resolved
import com.google.protobuf.Empty; | ||
import customer.api.CustomerApi; | ||
|
||
/** An event sourced entity. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not necessarily for this PR but one thing that would be nice would be if we could include what protobuf it corresponds to here (like we have manually in some of the serverless framework test classes).
import com.akkaserverless.javasdk.impl.eventsourcedentity.EventSourcedEntityHandler; | ||
import com.google.protobuf.Descriptors; | ||
|
||
public interface EventSourcedEntityProvider<S, E extends EventSourcedEntityBase<S>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add some "Not for user extension" here or do we consider it actual API for user extension as well as common (internal) interface for generated code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add a comment that the concrete implementation is generated, to start with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question.
Let's be restrictive and eventually relax the rules if needed. We have all the interest in keep it 'private'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can't make it completely internal because it's the parameter to register
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what I mean by 'private' is that it's not real private, but marked as "Not for user extension"
This is ready. I'll continue in a new PR by looking at the differences between event sourced and value entities and try to align. Part of that also look at the serialization second step in #150 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good.
I left some comments and suggestions. Don't need to be impl in this PR, so approving already. We can eventually add in follow-up PRs.
@@ -23,6 +23,7 @@ import org.bitbucket.inkytonik.kiama.output.PrettyPrinterTypes.Document | |||
|
|||
object ValueEntitySourceGenerator { | |||
import SourceGenerator._ | |||
import EntityServiceSourceGenerator.generateImports |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why generateImports
needed to move to EntityServiceSourceGenerator
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's used by both ValueEntitySourceGenerator and EntityServiceSourceGenerator, should probably be in some third utility class but EntityServiceSourceGenerator anyway looked like it wasn't only about EventSourced
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, the code for value entity and event sourced entity was previously in EntityServiceSourceGenerator and we started to split it into two different generators.
At some point, we spined-off ValueEntitySourceGenerator
and EntityServiceSourceGenerator
should have been renamed to EntitySourcedServiceSourceGenerator
, but we had other PRs in the making and it was better to postpone the rename to avoid conflicts.
generatedSourceDirectory.resolve( | ||
"com/example/service/persistence/MyEntity1Handler.java" | ||
), | ||
generatedSourceDirectory.resolve( | ||
"com/example/service/persistence/MyEntity1Provider.java" | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah! I missed this extra tests when introducing the handler and provider. Thanks.
@@ -316,7 +482,7 @@ object EntityServiceSourceGenerator { | |||
className: String): Option[String] = { | |||
entity match { | |||
case eventSourcedEntity: ModelBuilder.EventSourcedEntity => | |||
None | |||
Some(eventSourcedEntityProvider(service, eventSourcedEntity, packageName, className)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made it an option (here and above) because we didn't have a provider and a handler for ES.
We can remove the Option now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I'll remove that in next round
`class`("public", s"$className extends $interfaceClassName") { | ||
"@SuppressWarnings" <> parens(dquotes("unused")) <> line <> | ||
"private" <+> "final" <+> "String" <+> "entityId" <> semi <> line <> | ||
line <> | ||
constructor( | ||
"public", | ||
className, | ||
List("@EntityId" <+> "String" <+> "entityId") | ||
List("EventSourcedContext" <+> "context") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Value entity is only passing the String entityId
. We need to align this.
The context is not so useful right now. It only has the entityId and the serviceCallFactory
, but the serviceCallFactory
is already available from the CommandContext
.
We probably want to have something better than the exiting (untyped) ServiceCallFactory
and then we want it to be injected in the constructor so users can instantiate clients at construction time (and not per command using the CommandContext).
So, passing the context is probably something we may need to keep (and introduce in VE), but not yet clear how we will really use it.
On the other hand, passing context make unit testing harder. It will be better to not have a mock context of any kind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, there are more things that are different, I'll align them
import com.akkaserverless.javasdk.impl.eventsourcedentity.EventSourcedEntityHandler; | ||
import com.google.protobuf.Descriptors; | ||
|
||
public interface EventSourcedEntityProvider<S, E extends EventSourcedEntityBase<S>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what I mean by 'private' is that it's not real private, but marked as "Not for user extension"
one for value entity and another for event sourced
Refs #52