Skip to content

Commit

Permalink
fix: state unpack in context creation
Browse files Browse the repository at this point in the history
  • Loading branch information
Adriano Santos committed Aug 23, 2024
1 parent 7de73b9 commit 0dd89fc
Show file tree
Hide file tree
Showing 14 changed files with 317 additions and 275 deletions.
464 changes: 237 additions & 227 deletions README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package io.eigr.spawn.internal;
package io.eigr.spawn.api.actors;

import com.google.protobuf.Message;
import io.eigr.spawn.api.actors.ActorContext;
import io.eigr.spawn.api.actors.Value;
import io.eigr.spawn.internal.ActionEmptyFunction;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.protobuf.GeneratedMessage;
import com.google.protobuf.Message;
import io.eigr.spawn.api.actors.ActionBindings;
import io.eigr.spawn.api.actors.ActorContext;
import io.eigr.spawn.api.actors.Value;
import io.eigr.spawn.api.exceptions.ActorInvocationException;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/eigr/spawn/internal/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public Entity(
String actorName,
Class<?> actorType,
ActorOuterClass.Kind kind,
Class stateType,
Class<?> stateType,
String actorBeanName,
boolean stateful,
long deactivateTimeout,
Expand Down Expand Up @@ -352,7 +352,7 @@ public ActorOuterClass.Kind getKind() {
return kind;
}

public Class getStateType() {
public Class<?> getStateType() {
return stateType;
}

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

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.protobuf.Any;
import com.google.protobuf.GeneratedMessage;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.*;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import io.eigr.functions.protocol.Protocol;
Expand Down Expand Up @@ -209,13 +207,16 @@ private Entity.EntityMethod getEntityMethod(String commandName, Entity entity) t
* @return the {@link ActorContext} instance
* @throws InvalidProtocolBufferException if the state cannot be unpacked
*/
private ActorContext createActorContext(Protocol.Context context, Entity entity) throws InvalidProtocolBufferException {
if (context.hasState()) {
private ActorContext createActorContext(Protocol.Context context, Entity entity) throws InvalidProtocolBufferException, ClassNotFoundException {
if (context.hasState() && entity.isStateful()) {
Any anyCtxState = context.getState();
log.debug("[{}] trying to get the state of the Actor {}. Parse Any type {} from State type {}",
system, entity.getActorName(), anyCtxState, entity.getStateType().getSimpleName());

Object state = anyCtxState.unpack(entity.getStateType());
String typeUrl = anyCtxState.getTypeUrl();
String typeName = typeUrl.substring(typeUrl.lastIndexOf('/') + 1);
Class protoClass = Class.forName(typeName);
Object state = anyCtxState.unpack(protoClass);
return new ActorContext(spawn, state);
} else {
return new ActorContext(spawn);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.eigr.spawn;
package io.eigr.spawn.test;

import io.eigr.spawn.api.Spawn;
import io.eigr.spawn.api.TransportOpts;
Expand Down
28 changes: 28 additions & 0 deletions src/test/java/io/eigr/spawn/test/ProtobufSerializationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.eigr.spawn.test;

import com.google.protobuf.Any;
import com.google.protobuf.InvalidProtocolBufferException;
import domain.actors.State;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.junit.jupiter.api.Assertions.assertNotNull;

public class ProtobufSerializationTest {
private static final Logger log = LoggerFactory.getLogger(ProtobufSerializationTest.class);

@Test
public void testAnyUnpack() throws InvalidProtocolBufferException, ClassNotFoundException {
State stateActor = State.newBuilder().buildPartial();

Any anyCtxState = Any.pack(stateActor);

String typeUrl = anyCtxState.getTypeUrl();
String typeName = typeUrl.substring(typeUrl.lastIndexOf('/') + 1);

Class protoClass = Class.forName(typeName);
stateActor = (State) anyCtxState.unpack(protoClass);
assertNotNull(stateActor);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package io.eigr.spawn;
package io.eigr.spawn.test;

import domain.actors.Reply;
import domain.actors.Request;
import io.eigr.spawn.api.ActorIdentity;
import io.eigr.spawn.api.ActorRef;
import io.eigr.spawn.api.exceptions.ActorCreationException;
import io.eigr.spawn.api.exceptions.ActorInvocationException;
import io.eigr.spawn.java.test.domain.Actor;
import io.eigr.spawn.test.actors.JoeActor;
import io.eigr.spawn.test.actors.StatelessNamedActor;
import io.eigr.spawn.test.actors.UnNamedActor;
Expand All @@ -25,15 +26,15 @@ void testNamedInvocation() throws ActorCreationException, ActorInvocationExcepti
Assertions.assertEquals(type, JoeActor.class);
Assertions.assertNotNull(joeActor);

Actor.Request msg = Actor.Request.newBuilder()
Request msg = Request.newBuilder()
.setLanguage("Erlang")
.build();

Optional<Actor.Reply> maybeReply =
joeActor.invoke("SetLanguage", msg, Actor.Reply.class);
Optional<Reply> maybeReply =
joeActor.invoke("SetLanguage", msg, Reply.class);

if (maybeReply.isPresent()) {
Actor.Reply reply = maybeReply.get();
Reply reply = maybeReply.get();
Assertions.assertNotNull(reply);
Assertions.assertEquals("Hi Erlang. Hello From Java", reply.getResponse());
}
Expand All @@ -49,15 +50,15 @@ void testUnNamedInvocation() throws ActorCreationException, ActorInvocationExcep
Assertions.assertEquals(type, UnNamedActor.class);
Assertions.assertNotNull(unNamedJoeActor);

Actor.Request msg = Actor.Request.newBuilder()
Request msg = Request.newBuilder()
.setLanguage("Erlang")
.build();

Optional<Actor.Reply> maybeReply =
unNamedJoeActor.invoke("SetLanguage", msg, Actor.Reply.class);
Optional<Reply> maybeReply =
unNamedJoeActor.invoke("SetLanguage", msg, Reply.class);

if (maybeReply.isPresent()) {
Actor.Reply reply = maybeReply.get();
Reply reply = maybeReply.get();
Assertions.assertNotNull(reply);
Assertions.assertEquals("Hi Erlang. Hello From Java", reply.getResponse());
}
Expand All @@ -73,15 +74,15 @@ void testStatelessInvocation() throws ActorCreationException, ActorInvocationExc
Assertions.assertEquals(type, StatelessNamedActor.class);
Assertions.assertNotNull(statelessNamedActor);

Actor.Request msg = Actor.Request.newBuilder()
Request msg = Request.newBuilder()
.setLanguage("Elixir")
.build();

Optional<Actor.Reply> maybeReply =
statelessNamedActor.invoke("SetLanguage", msg, Actor.Reply.class);
Optional<Reply> maybeReply =
statelessNamedActor.invoke("SetLanguage", msg, Reply.class);

if (maybeReply.isPresent()) {
Actor.Reply reply = maybeReply.get();
Reply reply = maybeReply.get();
Assertions.assertNotNull(reply);
Assertions.assertEquals("Hi Elixir. Hello From Java", reply.getResponse());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.eigr.spawn;
package io.eigr.spawn.test;

import domain.actors.Request;
import io.eigr.functions.protocol.Protocol;
import io.eigr.spawn.api.ActorIdentity;
import io.eigr.spawn.api.ActorRef;
Expand All @@ -8,7 +9,6 @@
import io.eigr.spawn.api.actors.workflows.Pipe;
import io.eigr.spawn.api.actors.workflows.SideEffect;
import io.eigr.spawn.api.exceptions.SpawnException;
import io.eigr.spawn.java.test.domain.Actor;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -25,7 +25,7 @@ public void before() throws SpawnException {

@Test
void testBroadcastBuilder() {
Broadcast broadcast = Broadcast.to("test.channel", "hi", Actor.Request.getDefaultInstance());
Broadcast broadcast = Broadcast.to("test.channel", "hi", Request.getDefaultInstance());
final Protocol.Broadcast protocolBroadcast = broadcast.build();
Assertions.assertEquals("test.channel", protocolBroadcast.getChannelGroup());
Assertions.assertNotNull(protocolBroadcast.getValue());
Expand All @@ -49,7 +49,7 @@ void testPipeBuilder() throws Exception {

@Test
void testSideEffectBuilder() throws Exception {
SideEffect effect = SideEffect.to(joeActorRef, "hi", Actor.Request.getDefaultInstance());
SideEffect effect = SideEffect.to(joeActorRef, "hi", Request.getDefaultInstance());
final Protocol.SideEffect protocolSideEffect = effect.build();
Protocol.InvocationRequest request = protocolSideEffect.getRequest();
Assertions.assertNotNull(request);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package io.eigr.spawn.test.actors;

import domain.actors.Reply;
import domain.actors.Request;
import domain.actors.State;
import io.eigr.spawn.api.actors.ActionBindings;
import io.eigr.spawn.api.actors.ActorContext;
import io.eigr.spawn.api.actors.StatefulActor;
import io.eigr.spawn.api.actors.Value;
import io.eigr.spawn.api.actors.behaviors.ActorBehavior;
import io.eigr.spawn.api.actors.behaviors.BehaviorCtx;
import io.eigr.spawn.api.actors.behaviors.NamedActorBehavior;
import io.eigr.spawn.internal.ActionBindings;
import io.eigr.spawn.java.test.domain.Actor.Reply;
import io.eigr.spawn.java.test.domain.Actor.Request;
import io.eigr.spawn.java.test.domain.Actor.State;

import static io.eigr.spawn.api.actors.behaviors.ActorBehavior.action;
import static io.eigr.spawn.api.actors.behaviors.ActorBehavior.name;
Expand Down
11 changes: 6 additions & 5 deletions src/test/java/io/eigr/spawn/test/actors/JoeActor.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package io.eigr.spawn.test.actors;

import domain.actors.Reply;
import domain.actors.Request;
import domain.actors.State;
import io.eigr.spawn.api.actors.ActionBindings;
import io.eigr.spawn.api.actors.ActorContext;
import io.eigr.spawn.api.actors.StatefulActor;
import io.eigr.spawn.api.actors.Value;
import io.eigr.spawn.api.actors.behaviors.ActorBehavior;
import io.eigr.spawn.api.actors.behaviors.BehaviorCtx;
import io.eigr.spawn.api.actors.behaviors.NamedActorBehavior;
import io.eigr.spawn.internal.ActionBindings;
import io.eigr.spawn.java.test.domain.Actor.Reply;
import io.eigr.spawn.java.test.domain.Actor.Request;
import io.eigr.spawn.java.test.domain.Actor.State;

import static io.eigr.spawn.api.actors.behaviors.ActorBehavior.*;
import static io.eigr.spawn.api.actors.behaviors.ActorBehavior.action;
import static io.eigr.spawn.api.actors.behaviors.ActorBehavior.channel;

public final class JoeActor implements StatefulActor<State> {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package io.eigr.spawn.test.actors;

import domain.actors.Reply;
import domain.actors.Request;
import io.eigr.spawn.api.actors.ActionBindings;
import io.eigr.spawn.api.actors.ActorContext;
import io.eigr.spawn.api.actors.StatelessActor;
import io.eigr.spawn.api.actors.Value;
import io.eigr.spawn.api.actors.behaviors.ActorBehavior;
import io.eigr.spawn.api.actors.behaviors.BehaviorCtx;
import io.eigr.spawn.api.actors.behaviors.NamedActorBehavior;
import io.eigr.spawn.internal.ActionBindings;
import io.eigr.spawn.java.test.domain.Actor.Reply;
import io.eigr.spawn.java.test.domain.Actor.Request;

import static io.eigr.spawn.api.actors.behaviors.ActorBehavior.action;
import static io.eigr.spawn.api.actors.behaviors.ActorBehavior.name;
Expand Down
8 changes: 4 additions & 4 deletions src/test/java/io/eigr/spawn/test/actors/UnNamedActor.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package io.eigr.spawn.test.actors;

import domain.actors.Reply;
import domain.actors.Request;
import domain.actors.State;
import io.eigr.spawn.api.actors.ActionBindings;
import io.eigr.spawn.api.actors.ActorContext;
import io.eigr.spawn.api.actors.StatefulActor;
import io.eigr.spawn.api.actors.Value;
import io.eigr.spawn.api.actors.behaviors.ActorBehavior;
import io.eigr.spawn.api.actors.behaviors.BehaviorCtx;
import io.eigr.spawn.api.actors.behaviors.UnNamedActorBehavior;
import io.eigr.spawn.internal.ActionBindings;
import io.eigr.spawn.java.test.domain.Actor.Reply;
import io.eigr.spawn.java.test.domain.Actor.Request;
import io.eigr.spawn.java.test.domain.Actor.State;

import static io.eigr.spawn.api.actors.behaviors.ActorBehavior.action;
import static io.eigr.spawn.api.actors.behaviors.ActorBehavior.name;
Expand Down
5 changes: 3 additions & 2 deletions src/test/proto/eigr/functions/java/sdk/test/actor.proto
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
syntax = "proto3";
package domain;
option java_package = "io.eigr.spawn.java.test.domain";
package domain.actors;
option java_package = "domain.actors";
option java_multiple_files = true;

message State {
repeated string languages = 1;
Expand Down

0 comments on commit 0dd89fc

Please sign in to comment.