diff --git a/sdk/src/main/java/io/dapr/actors/runtime/ActorTimer.java b/sdk/src/main/java/io/dapr/actors/runtime/ActorTimer.java new file mode 100644 index 000000000..c1c5f36b1 --- /dev/null +++ b/sdk/src/main/java/io/dapr/actors/runtime/ActorTimer.java @@ -0,0 +1,41 @@ +package io.dapr.actors.runtime; + +import java.time.Duration; +import java.util.function.Function; + +/** + * Represents the timer set on an Actor. + */ +public interface ActorTimer { + + /** + * Gets the time when timer is first due. + * @return Time as Duration when timer is first due. + */ + Duration getDueTime(); + + /** + * Gets the periodic time when timer will be invoked. + * @return Periodic time as Duration when timer will be invoked. + */ + Duration getPeriod(); + + /** + * Gets the name of the Timer. The name is unique per actor. + * @return The name of the timer. + */ + String getName(); + + /** + * + * @return Gets a delegate that specifies a method to be called when the timer fires. + * It has one parameter: the state object passed to RegisterTimer. + */ + Function getAsyncCallback(); + + /** + * + * @return Gets state containing information to be used by the callback method, or null. + */ + Object getState(); +} diff --git a/sdk/src/main/java/io/dapr/actors/runtime/ActorTimerImpl.java b/sdk/src/main/java/io/dapr/actors/runtime/ActorTimerImpl.java new file mode 100644 index 000000000..ebd1f9d15 --- /dev/null +++ b/sdk/src/main/java/io/dapr/actors/runtime/ActorTimerImpl.java @@ -0,0 +1,88 @@ +package io.dapr.actors.runtime; + +import org.json.JSONObject; +import java.time.Duration; +import java.util.function.Function; + +/** + * Represents the timer set on an Actor. + */ +class ActorTimerImpl implements ActorTimer { + + private final AbstractActor owner; + private String name; + private Function asyncCallback; + private Object state; + private Duration dueTime; + private Duration period; + + /** + * + * @param owner The Actor that owns this timer. The timer callback will be fired for this Actor. + * @param timerName The name of the timer. + * @param asyncCallback The callback to invoke when the timer fires. + * @param state information to be used by the callback method + * @param dueTime the time when timer is first due. + * @param period the periodic time when timer will be invoked. + */ + public ActorTimerImpl(AbstractActor owner, String timerName, Function asyncCallback, Object state, Duration dueTime, Duration period) { + this.owner = owner; + this.name = timerName; + this.asyncCallback = asyncCallback; + this.state = state; + this.dueTime = dueTime; + this.period = period; + } + + /** + * Gets the name of the Timer. The name is unique per actor. + * @return The name of the timer. + */ + public String getName() { + return this.name; + } + + /** + * Gets the time when timer is first due. + * @return Time as Duration when timer is first due. + */ + public Duration getDueTime() { + return this.dueTime; + } + + /** + * @return Gets a delegate that specifies a method to be called when the timer fires. + * It has one parameter: the state object passed to RegisterTimer. + */ + public Function getAsyncCallback() { + return this.asyncCallback; + } + + /** + * Gets the periodic time when timer will be invoked. + * @return Periodic time as Duration when timer will be invoked. + */ + public Duration getPeriod() { + return this.period; + } + + /** + * + * @return Gets state containing information to be used by the callback method, or null. + */ + public Object getState() { + return this.state; + } + + /** + * + * @return + */ + String serialize() + { + JSONObject j = new JSONObject(); + j.put("dueTime", ConverterUtils.ConvertDurationToDaprFormat(this.getDueTime())); + j.put("period", ConverterUtils.ConvertDurationToDaprFormat(this.getPeriod())); + return j.toString(); + } +} diff --git a/sdk/src/test/java/io/dapr/actors/runtime/ActorTimerImplTest.java b/sdk/src/test/java/io/dapr/actors/runtime/ActorTimerImplTest.java new file mode 100644 index 000000000..52bdc5c43 --- /dev/null +++ b/sdk/src/test/java/io/dapr/actors/runtime/ActorTimerImplTest.java @@ -0,0 +1,57 @@ +package io.dapr.actors.runtime; + +import org.junit.Assert; +import org.junit.Test; + +import java.time.Duration; + +public class ActorTimerImplTest { + + @Test + public void serialize() { + Duration dueTime = Duration.ZERO + .plusMinutes(7) + .plusSeconds(17); + + Duration period = Duration.ZERO + .plusHours(1) + .plusSeconds(3); + + ActorTimerImpl timer = new ActorTimerImpl( + null, + "testTimer", + null, + null, + dueTime, + period); + String s = timer.serialize(); + + String expected = "{\"period\":\"1h0m3s0ms\",\"dueTime\":\"0h7m17s0ms\"}"; + Assert.assertEquals(expected, s); + } + + @Test + public void serializeWithOneTimePeriod() { + Duration dueTime = Duration.ZERO + .plusMinutes(7) + .plusSeconds(17); + + // this is intentionally negative + Duration period = Duration.ZERO + .minusHours(1) + .minusMinutes(3); + + ActorTimerImpl timer = new ActorTimerImpl( + null, + "testTimer", + null, + null, + dueTime, + period); + String s = timer.serialize(); + + // A negative period will be serialized to an empty string which is interpreted by Dapr to mean fire once only. + String expected = "{\"period\":\"\",\"dueTime\":\"0h7m17s0ms\"}"; + Assert.assertEquals(expected, s); + } +}