Skip to content
This repository has been archived by the owner on Mar 11, 2022. It is now read-only.

Add pure Kotlin EventSourcedEntityFactory, EntityHandler and ResolvedEntityFactory implementations #26

Merged
merged 25 commits into from
Apr 28, 2020
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
159f8ad
Add handlers and factories for register functions
sleipnir Apr 19, 2020
c3f26f7
Get Constructor
sleipnir Apr 19, 2020
6f23ec7
Add helper methods
sleipnir Apr 19, 2020
c91ecce
Remove Bytebuddy dependency
sleipnir Apr 20, 2020
a2b44ca
Remove transcode calls
sleipnir Apr 20, 2020
2a8dcbd
Remove bytebuddy agent
sleipnir Apr 20, 2020
40496fa
Add snapshots mappings
sleipnir Apr 20, 2020
63261e9
Merge branch 'master' into wip-kotlin-factory
sleipnir Apr 22, 2020
c1b86d4
Add initial structure for crdt services
sleipnir Apr 22, 2020
01ec8a6
Add command invoker implementation
sleipnir Apr 22, 2020
38c2491
Various adjusts
sleipnir Apr 23, 2020
ee63d25
Rename docker image
sleipnir Apr 23, 2020
5b73a80
Fix in commandHandler
sleipnir Apr 23, 2020
d7fd038
Adjusts
sleipnir Apr 23, 2020
9424bc3
Add commandHandlers support with params and Fix AnySupport load descr…
sleipnir Apr 25, 2020
c70c9e6
Add initial eventsourced implementation 90% of TCK passed
sleipnir Apr 27, 2020
b0fb40f
Handling FailInvoke. 100% of TCK passed
sleipnir Apr 27, 2020
c5624bf
Add tests to validate new EventSourcedEntityFactory
sleipnir Apr 27, 2020
6a7ebf6
Workaround for CRDT continue works
sleipnir Apr 27, 2020
524979f
Workaround for CRDT continue works
sleipnir Apr 27, 2020
4fc524a
Workaround for CRDT continue works
sleipnir Apr 27, 2020
d699906
Substitue bytebuddy classes to kotlin handlers ref issue https://gith…
sleipnir Apr 27, 2020
254a34d
Remove Cloudstate annotation
sleipnir Apr 28, 2020
496189b
Change array to list in register api
sleipnir Apr 28, 2020
7b476ea
Add snapshot test
sleipnir Apr 28, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cloudstate-kotlin-support/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
<grpc.version>1.22.1</grpc.version>
<akka.version>2.6.0-M7</akka.version>
<akka.grpc.version>0.7.1</akka.grpc.version>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

Expand All @@ -39,6 +38,7 @@
<version>0.4.3</version>
</dependency>

<!-- Remove Bytebuddy when issue https://github.com/cloudstateio/kotlin-support/issues/6 is fixed -->
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.cloudstate.kotlinsupport.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Annotation used to indicate that the annotated parameter accepts an entity id.
*
* <p>This parameter may appear on handler methods and constructors for any class that provides
* behavior for stateful service entity.
*
* <p>The type of the parameter must be {@link String}.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
public @interface EntityId {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.cloudstate.kotlinsupport.annotations.crdt;

import io.cloudstate.javasupport.crdt.CommandContext;
import io.cloudstate.javasupport.impl.CloudStateAnnotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Marks a method as a command handler.
*
* <p>This method will be invoked whenever the service call with name that matches this command
* handlers name is invoked.
*
* <p>The method may take the command object as a parameter, its type must match the gRPC service
* input type.
*
* <p>The return type of the method must match the gRPC services output type.
*
* <p>The method may also take a {@link CommandContext}, and/or a {@link
* io.cloudstate.javasupport.EntityId} annotated {@link String} parameter.
*/
@CloudStateAnnotation
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandHandler {

/**
* The name of the command to handle.
*
* <p>If not specified, the name of the method will be used as the command name, with the first
* letter capitalized to match the gRPC convention of capitalizing rpc method names.
*
* @return The command name.
*/
String name() default "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.cloudstate.kotlinsupport.annotations.crdt;

import io.cloudstate.javasupport.crdt.CommandHandler;
import io.cloudstate.javasupport.crdt.Crdt;
import io.cloudstate.javasupport.crdt.CrdtContext;
import io.cloudstate.javasupport.crdt.CrdtFactory;
import io.cloudstate.javasupport.impl.CloudStateAnnotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* A CRDT backed entity.
*
* <p>CRDT entities store their state in a subclass {@link Crdt}. These may be created using a
* {@link CrdtFactory}, which can be injected into the constructor or as a parameter to any {@link
* CommandHandler} annotated method.
*
* <p>Only one CRDT may be created, it is important that before creating a CRDT, the entity should
* check whether the CRDT has already been created, for example, it may have been created on another
* node and replicated to this node. To check, either use the {@link CrdtContext#state(Class)}
* method, which can be injected into the constructor or any {@link CommandHandler} method, or have
* an instance of the CRDT wrapped in {@link java.util.Optional} injected into the constructor or
* command handler methods.
*/
@CloudStateAnnotation
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CrdtEntity {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.cloudstate.kotlinsupport.annotations.eventsourced;

import io.cloudstate.javasupport.eventsourced.CommandContext;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Marks a method as a command handler.
*
* <p>This method will be invoked whenever the service call with name that matches this command
* handlers name is invoked.
*
* <p>The method may take the command object as a parameter, its type must match the gRPC service
* input type.
*
* <p>The return type of the method must match the gRPC services output type.
*
* <p>The method may also take a {@link CommandContext}, and/or a {@link
* io.cloudstate.javasupport.EntityId} annotated {@link String} parameter.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandHandler {

/**
* The name of the command to handle.
*
* <p>If not specified, the name of the method will be used as the command name, with the first
* letter capitalized to match the gRPC convention of capitalizing rpc method names.
*
* @return The command name.
*/
String name() default "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.cloudstate.kotlinsupport.annotations.eventsourced;

import io.cloudstate.javasupport.eventsourced.EventContext;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Marks a method as an event handler.
*
* <p>This method will be invoked whenever an event matching this event handlers event class is
* either replayed on entity recovery, by a command handler.
*
* <p>The method may take the event object as a parameter.
*
* <p>Methods annotated with this may take an {@link EventContext}.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EventHandler {
/**
* The event class. Generally, this will be determined by looking at the parameter of the event
* handler method, however if the event doesn't need to be passed to the method (for example,
* perhaps it contains no data), then this can be used to indicate which event this handler
* handles.
*/
Class<?> eventClass() default Object.class;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.cloudstate.kotlinsupport.annotations.eventsourced;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/** An event sourced entity. */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EventSourcedEntity {
/**
* The name of the persistence id.
*
* <p>If not specifed, defaults to the entities unqualified classname. It's strongly recommended
* that you specify it explicitly.
*/
String persistenceId() default "";

/**
* Specifies how snapshots of the entity state should be made: Zero means use default from
* configuration file. (Default) Any negative value means never snapshot. Any positive value means
* snapshot at-or-after that number of events.
*/
int snapshotEvery() default 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.cloudstate.kotlinsupport.annotations.eventsourced;

import io.cloudstate.javasupport.eventsourced.SnapshotContext;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Marks a method as a snapshot method.
*
* <p>An event sourced behavior may have at most one of these. When provided, it will be
* periodically (every <em>n</em> events emitted) be invoked to retrieve a snapshot of the current
* state, to be persisted, so that the event log can be loaded without replaying the entire history.
*
* <p>The method must return the current state of the entity.
*
* <p>The method may accept a {@link SnapshotContext} parameter.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Snapshot {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.cloudstate.kotlinsupport.annotations.eventsourced;

import io.cloudstate.javasupport.eventsourced.SnapshotContext;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Marks a method as a snapshot handler.
*
* <p>If, when recovering an entity, that entity has a snapshot, the snapshot will be passed to a
* corresponding snapshot handler method whose argument matches its type. The entity must set its
* current state to that snapshot.
*
* <p>An entity may declare more than one snapshot handler if it wants different handling for
* different types.
*
* <p>The snapshot handler method may additionally accept a {@link SnapshotContext} parameter,
* allowing it to access context for the snapshot, if required.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SnapshotHandler {}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import java.lang.annotation.Annotation;

public final class CommandHandlerImpl implements CommandHandler {
public class CommandHandlerImpl implements CommandHandler {

private final String name;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import java.lang.annotation.Annotation;

public final class CrdtEntityImpl implements CrdtEntity {
public class CrdtEntityImpl implements CrdtEntity {
public Class<? extends Annotation> annotationType() {
return CrdtEntity.class;
}
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading