Skip to content
6 changes: 5 additions & 1 deletion sdk/src/main/java/io/dapr/client/DaprClientBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
import io.grpc.ManagedChannelBuilder;
import okhttp3.OkHttpClient;

import java.time.Duration;
import java.time.temporal.TemporalUnit;

/**
* A builder for the DaprClient,
* Currently only and HTTP Client will be supported.
Expand Down Expand Up @@ -84,7 +87,8 @@ private DaprClient buildDaprClientHttp() {
if (this.daprHttClient == null) {
synchronized (DaprClientBuilder.class) {
if (this.daprHttClient == null) {
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
OkHttpClient okHttpClient = new OkHttpClient.Builder().callTimeout(Duration.ofSeconds(60))
.build();
DaprHttp daprHtt = new DaprHttp(port, okHttpClient);
this.daprHttClient = new DaprClientHttpAdapter(daprHtt);
}
Expand Down
15 changes: 9 additions & 6 deletions sdk/src/main/java/io/dapr/client/domain/StateOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package io.dapr.client.domain;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
Expand All @@ -19,6 +20,7 @@

import java.io.IOException;
import java.time.Duration;
import java.time.temporal.TemporalUnit;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -47,6 +49,7 @@ public RetryPolicy getRetryPolicy() {
return retryPolicy;
}

@JsonIgnore
public Map<String, String> getStateOptionsAsMap() {
Map<String, String> mapOptions = null;
if (this != null) {
Expand All @@ -59,7 +62,7 @@ public Map<String, String> getStateOptionsAsMap() {
}
if (this.getRetryPolicy() != null) {
if (this.getRetryPolicy().getInterval() != null) {
mapOptions.put("retryInterval", DurationUtils.ConvertDurationToDaprFormat(this.getRetryPolicy().getInterval()));
mapOptions.put("retryInterval", String.valueOf(this.getRetryPolicy().getInterval().toMillis()));
}
if (this.getRetryPolicy().getThreshold() != null) {
mapOptions.put("retryThreshold", this.getRetryPolicy().getThreshold().toString());
Expand Down Expand Up @@ -164,17 +167,17 @@ public Pattern getPattern() {

public static class StateOptionDurationSerializer extends StdSerializer<Duration> {

public StateOptionDurationSerializer() {

super(Duration.class);
}
public StateOptionDurationSerializer(Class<Duration> t) {
super(t);
}

@Override
public void serialize(Duration duration, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
String value = "";
if (duration != null && !duration.isZero() && !duration.isNegative()) {
value = DurationUtils.ConvertDurationToDaprFormat(duration);
}
jsonGenerator.writeString(value);
jsonGenerator.writeNumber(duration.toMillis());
}
}

Expand Down
99 changes: 99 additions & 0 deletions sdk/src/test/java/io/dapr/it/state/HttpStateClientIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
import io.dapr.it.services.EmptyService;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import reactor.core.publisher.Mono;

import java.time.Duration;

/**
* Test State HTTP DAPR capabilities using a DAPR instance with an empty service running
*/
Expand Down Expand Up @@ -442,4 +445,100 @@ public void saveUpdateAndGetStateWithEtagAndStateOptionsLastWrite() {
Assert.assertEquals("data in property B2", myLastDataResponse.getValue().getPropertyB());
}

@Test(timeout=13000)
public void saveDeleteWithRetry() {
final String stateKey = "keyToBeDeleteWithWrongEtagAndRetry";
StateOptions.RetryPolicy retryPolicy= new StateOptions.RetryPolicy(Duration.ofSeconds(3),3, StateOptions.RetryPolicy.Pattern.LINEAR);
StateOptions stateOptions = new StateOptions(null, null, retryPolicy);

//create DAPR client
DaprClient daprClient = new DaprClientBuilder().build();
//Create dummy data to be store
MyData data = new MyData();
data.setPropertyA("data in property A");
data.setPropertyB("data in property B");

//Create deferred action to save the sate
Mono<Void> saveResponse = daprClient.saveState(stateKey, null, data, null);
//execute the save state action
saveResponse.block();

//Create deferred action to retrieve the state
Mono<State<MyData>> response = daprClient.getState(new State(stateKey, null, null), MyData.class);
//execute the action for retrieve the state and the etag
State<MyData> myDataResponse = response.block();

//review that the etag is not empty
Assert.assertNotNull(myDataResponse.getEtag());
Assert.assertNotNull(myDataResponse.getKey());
Assert.assertNotNull(myDataResponse.getValue());
Assert.assertEquals("data in property A", myDataResponse.getValue().getPropertyA());
Assert.assertEquals("data in property B", myDataResponse.getValue().getPropertyB());


Mono<Void> deleteResponse = daprClient.deleteState(new State<MyData>(stateKey, "99999999", stateOptions));

long start = System.currentTimeMillis();
try {
//delete action
deleteResponse.block();
}catch(RuntimeException ex){
Assert.assertTrue(ex.getMessage().contains("failed to set value after 3 retries"));
}
long end = System.currentTimeMillis();
System.out.println("DEBUG: Logic A took " + (end - start) + " MilliSeconds");
long elapsedTime = end -start;
Assert.assertTrue(elapsedTime>9000 && elapsedTime<9200);

}

@Ignore("Ignored as an issue on DAPR")
@Test(timeout=13000)
public void saveUpdateWithRetry() {
final String stateKey = "keyToBeDeleteWithWrongEtagAndRetry";
StateOptions.RetryPolicy retryPolicy= new StateOptions.RetryPolicy(Duration.ofSeconds(4),3, StateOptions.RetryPolicy.Pattern.EXPONENTIAL);
StateOptions stateOptions = new StateOptions(null, null, retryPolicy);

//create DAPR client
DaprClient daprClient = new DaprClientBuilder().build();
//Create dummy data to be store
MyData data = new MyData();
data.setPropertyA("data in property A");
data.setPropertyB("data in property B");

//Create deferred action to save the sate
Mono<Void> saveResponse = daprClient.saveState(stateKey, null, data, null);
//execute the save state action
saveResponse.block();

//Create deferred action to retrieve the state
Mono<State<MyData>> response = daprClient.getState(new State(stateKey, null, null), MyData.class);
//execute the action for retrieve the state and the etag
State<MyData> myDataResponse = response.block();

//review that the etag is not empty
Assert.assertNotNull(myDataResponse.getEtag());
Assert.assertNotNull(myDataResponse.getKey());
Assert.assertNotNull(myDataResponse.getValue());
Assert.assertEquals("data in property A", myDataResponse.getValue().getPropertyA());
Assert.assertEquals("data in property B", myDataResponse.getValue().getPropertyB());

//Create deferred action to save the sate
saveResponse = daprClient.saveState(stateKey, "9999999", data, stateOptions);
//execute the save state action
long start = System.currentTimeMillis();


try {
saveResponse.block();
}catch(RuntimeException ex){
Assert.assertTrue(ex.getMessage().contains("failed to set value after 3 retries"));
}
long end = System.currentTimeMillis();
System.out.println("DEBUG: Logic A took " + (end - start) + " MilliSeconds");
long elapsedTime = end -start;
Assert.assertTrue(elapsedTime>9000 && elapsedTime<9200);

}

}