Unit testing + bug fixing in GRPC Adapter (#79)

* Adding mockito plugin to be able to mock final classes
Increasing test coverage for ObjectSerializer
Fixing bug in GRPC Adapter while creating the envelopes, found during unit testing.

* First step into returning Http Headers as part of the response for the DaprClientHttpAdapter
Updating State object to match the API.
Fixing Broken Unit Tests and increasing coverage for DaprClientGrpcAdapter

* Adding documentation, fixing typos and renaming support method to be more descriptive.

* Addressing PR comments
Increasing test coverage
Fixing Merge conflicts

* Addressing PR comments
This commit is contained in:
Andres Robles 2020-01-13 10:01:45 -06:00 committed by Artur Souza
parent 6953bc49d1
commit 9703dabaae
16 changed files with 1359 additions and 320 deletions

View File

@ -6,6 +6,7 @@ package io.dapr.actors.runtime;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import io.dapr.utils.DurationUtils;
import io.dapr.utils.ObjectSerializer;
import java.io.IOException;

View File

@ -1,142 +0,0 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
package io.dapr.actors.runtime;
import java.time.Duration;
public class DurationUtils {
/**
* Converts time from the String format used by Dapr into a Duration.
*
* @param valueString A String representing time in the Dapr runtime's format (e.g. 4h15m50s60ms).
* @return A Duration
*/
public static Duration ConvertDurationFromDaprFormat(String valueString) {
// Convert the format returned by the Dapr runtime into Duration
// An example of the format is: 4h15m50s60ms. It does not include days.
int hIndex = valueString.indexOf('h');
int mIndex = valueString.indexOf('m');
int sIndex = valueString.indexOf('s');
int msIndex = valueString.indexOf("ms");
String hoursSpan = valueString.substring(0, hIndex);
int hours = Integer.parseInt(hoursSpan);
int days = hours / 24;
hours = hours % 24;
String minutesSpan = valueString.substring(hIndex + 1, mIndex);
int minutes = Integer.parseInt(minutesSpan);
String secondsSpan = valueString.substring(mIndex + 1, sIndex);
int seconds = Integer.parseInt(secondsSpan);
String millisecondsSpan = valueString.substring(sIndex + 1, msIndex);
int milliseconds = Integer.parseInt(millisecondsSpan);
return Duration.ZERO
.plusDays(days)
.plusHours(hours)
.plusMinutes(minutes)
.plusSeconds(seconds)
.plusMillis(milliseconds);
}
/**
* Converts a Duration to the format used by the Dapr runtime.
*
* @param value Duration
* @return The Duration formatted as a String in the format the Dapr runtime uses (e.g. 4h15m50s60ms)
*/
public static String ConvertDurationToDaprFormat(Duration value) {
String stringValue = "";
// return empty string for anything negative, it'll only happen for reminder "periods", not dueTimes. A
// negative "period" means fire once only.
if (value == Duration.ZERO ||
(value.compareTo(Duration.ZERO) == 1)) {
long hours = getDaysPart(value) * 24 + getHoursPart(value);
StringBuilder sb = new StringBuilder();
sb.append(hours);
sb.append("h");
sb.append(getMinutesPart((value)));
sb.append("m");
sb.append(getSecondsPart((value)));
sb.append("s");
sb.append(getMilliSecondsPart((value)));
sb.append("ms");
return sb.toString();
}
return stringValue;
}
/**
* Helper to get the "days" part of the Duration. For example if the duration is 26 hours, this returns 1.
*
* @param d Duration
* @return Number of days.
*/
static long getDaysPart(Duration d) {
long t = d.getSeconds() / 60 / 60 / 24;
return t;
}
/**
* Helper to get the "hours" part of the Duration. For example if the duration is 26 hours, this is 1 day, 2 hours, so this returns 2.
*
* @param d The duration to parse
* @return the hour part of the duration
*/
static long getHoursPart(Duration d) {
long u = (d.getSeconds() / 60 / 60) % 24;
return u;
}
/**
* Helper to get the "minutes" part of the Duration.
*
* @param d The duration to parse
* @return the minutes part of the duration
*/
static long getMinutesPart(Duration d) {
long u = (d.getSeconds() / 60) % 60;
return u;
}
/**
* Helper to get the "seconds" part of the Duration.
*
* @param d The duration to parse
* @return the seconds part of the duration
*/
static long getSecondsPart(Duration d) {
long u = d.getSeconds() % 60;
return u;
}
/**
* Helper to get the "millis" part of the Duration.
*
* @param d The duration to parse
* @return the milliseconds part of the duration
*/
static long getMilliSecondsPart(Duration d) {
long u = d.toMillis() % 1000;
return u;
}
}

View File

@ -118,13 +118,12 @@ public interface DaprClient {
* Retrieve a State based on their key.
*
* @param state The key of the State to be retrieved.
* @param stateOptions
* @param stateOptions The options for the call to use.
* @param clazz the Type of State needed as return.
* @param <T> the Type of the return.
* @param <K> The Type of the key of the State.
* @return A Mono Plan for the requested State.
*/
<T, K> Mono<T> getState(StateKeyValue<K> state, StateOptions stateOptions, Class<T> clazz);
<T> Mono<StateKeyValue<T>> getState(StateKeyValue<T> state, StateOptions stateOptions, Class<T> clazz);
/**
* Save/Update a list of states.

View File

@ -6,6 +6,8 @@ package io.dapr.client;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.protobuf.Any;
import com.google.protobuf.ByteString;
import com.google.protobuf.Duration;
import com.google.protobuf.Empty;
import io.dapr.DaprGrpc;
import io.dapr.DaprProtos;
@ -15,9 +17,8 @@ import io.dapr.client.domain.Verb;
import io.dapr.utils.ObjectSerializer;
import reactor.core.publisher.Mono;
import java.lang.reflect.Field;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
/**
* An adapter for the GRPC Client.
@ -64,15 +65,12 @@ class DaprClientGrpcAdapter implements DaprClient {
@Override
public <T> Mono<Void> publishEvent(String topic, T event, Map<String, String> metadata) {
try {
String serializedEvent = objectSerializer.serializeString(event);
Map<String, String> mapEvent = new HashMap<>();
mapEvent.put("Topic", topic);
mapEvent.put("Data", serializedEvent);
byte[] byteEvent = objectSerializer.serialize(event);
Any data = Any.newBuilder().setValue(ByteString.copyFrom(byteEvent)).build();
// TODO: handle metadata.
byte[] byteEvent = objectSerializer.serialize(mapEvent);
DaprProtos.PublishEventEnvelope envelope = DaprProtos.PublishEventEnvelope.parseFrom(byteEvent);
DaprProtos.PublishEventEnvelope envelope = DaprProtos.PublishEventEnvelope.newBuilder()
.setTopic(topic).setData(data).build();
ListenableFuture<Empty> futureEmpty = client.publishEvent(envelope);
return Mono.just(futureEmpty).flatMap(f -> {
try {
@ -93,18 +91,12 @@ class DaprClientGrpcAdapter implements DaprClient {
@Override
public <T, R> Mono<T> invokeService(Verb verb, String appId, String method, R request, Map<String, String> metadata, Class<T> clazz) {
try {
DaprProtos.InvokeServiceEnvelope.Builder envelopeBuilder = DaprProtos.InvokeServiceEnvelope.newBuilder();
envelopeBuilder.setId(appId);
envelopeBuilder.setMethod(verb.toString());
envelopeBuilder.setData(Any.parseFrom(objectSerializer.serialize(request)));
envelopeBuilder.getMetadataMap().putAll(metadata);
DaprProtos.InvokeServiceEnvelope envelope = envelopeBuilder.build();
DaprProtos.InvokeServiceEnvelope envelope = buildInvokeServiceEnvelope(verb.toString(), appId, method, request);
ListenableFuture<DaprProtos.InvokeServiceResponseEnvelope> futureResponse =
client.invokeService(envelope);
return Mono.just(futureResponse).flatMap(f -> {
try {
return Mono.just(objectSerializer.deserialize(f.get().getData().toByteArray(), clazz));
return Mono.just(objectSerializer.deserialize(f.get().getData().getValue().toByteArray(), clazz));
} catch (Exception ex) {
return Mono.error(ex);
}
@ -153,11 +145,12 @@ class DaprClientGrpcAdapter implements DaprClient {
@Override
public <T> Mono<Void> invokeBinding(String name, T request) {
try {
Map<String, String> mapMessage = new HashMap<>();
mapMessage.put("Name", name);
mapMessage.put("Data", objectSerializer.serializeString(request));
DaprProtos.InvokeBindingEnvelope envelope =
DaprProtos.InvokeBindingEnvelope.parseFrom(objectSerializer.serialize(mapMessage));
byte[] byteRequest = objectSerializer.serialize(request);
Any data = Any.newBuilder().setValue(ByteString.copyFrom(byteRequest)).build();
DaprProtos.InvokeBindingEnvelope.Builder builder = DaprProtos.InvokeBindingEnvelope.newBuilder()
.setName(name)
.setData(data);
DaprProtos.InvokeBindingEnvelope envelope = builder.build();
ListenableFuture<Empty> futureEmpty = client.invokeBinding(envelope);
return Mono.just(futureEmpty).flatMap(f -> {
try {
@ -173,20 +166,24 @@ class DaprClientGrpcAdapter implements DaprClient {
}
/**
* @return Returns an io.dapr.client.domain.StateKeyValue
*
* {@inheritDoc}
*/
@Override
public<T, K> Mono<T> getState(StateKeyValue<K> key, StateOptions stateOptions, Class<T> clazz) {
public <T> Mono<StateKeyValue<T>> getState(StateKeyValue<T> state, StateOptions stateOptions, Class<T> clazz) {
try {
Map<String, String> request = new HashMap<>();
request.put("Key", key.getKey());
request.put("Consistency", stateOptions.getConsistency());
byte[] serializedRequest = objectSerializer.serialize(request);
DaprProtos.GetStateEnvelope envelope = DaprProtos.GetStateEnvelope.parseFrom(serializedRequest);
DaprProtos.GetStateEnvelope.Builder builder = DaprProtos.GetStateEnvelope.newBuilder()
.setKey(state.getKey());
if (stateOptions != null && stateOptions.getConsistency() != null) {
builder.setConsistency(stateOptions.getConsistency().getValue());
}
DaprProtos.GetStateEnvelope envelope = builder.build();
ListenableFuture<DaprProtos.GetStateResponseEnvelope> futureResponse = client.getState(envelope);
return Mono.just(futureResponse).flatMap(f -> {
try {
return Mono.just(objectSerializer.deserialize(f.get().getData().getValue().toStringUtf8(), clazz));
return Mono.just(buildStateKeyValue(f.get(), state.getKey(), clazz));
} catch (Exception ex) {
return Mono.error(ex);
}
@ -196,22 +193,64 @@ class DaprClientGrpcAdapter implements DaprClient {
}
}
private <T> StateKeyValue<T> buildStateKeyValue(DaprProtos.GetStateResponseEnvelope resonse, String requestedKey, Class<T> clazz) throws IOException {
T value = objectSerializer.deserialize(resonse.getData().getValue().toByteArray(), clazz);
String etag = resonse.getEtag();
String key = requestedKey;
return new StateKeyValue<>(value, key, etag);
}
/**
* {@inheritDoc}
*/
@Override
public <T> Mono<Void> saveStates(List<StateKeyValue<T>> states, StateOptions options) {
try {
List<Map<String, Object>> listStates = new ArrayList<>();
Map<String, Object> mapOptions = transformStateOptionsToMap(options);
DaprProtos.StateRequestOptions.Builder optionBuilder = null;
if (options != null) {
DaprProtos.StateRetryPolicy.Builder retryPolicyBuilder = null;
if (options.getRetryPolicy() != null) {
retryPolicyBuilder = DaprProtos.StateRetryPolicy.newBuilder();
StateOptions.RetryPolicy retryPolicy = options.getRetryPolicy();
if (options.getRetryPolicy().getInterval() != null) {
Duration.Builder durationBuilder = Duration.newBuilder()
.setNanos(retryPolicy.getInterval().getNano())
.setSeconds(retryPolicy.getInterval().getSeconds());
retryPolicyBuilder.setInterval(durationBuilder.build());
}
retryPolicyBuilder.setThreshold(objectSerializer.deserialize(retryPolicy.getThreshold(), int.class));
if (retryPolicy.getPattern() != null) {
retryPolicyBuilder.setPattern(retryPolicy.getPattern().getValue());
}
}
optionBuilder = DaprProtos.StateRequestOptions.newBuilder();
if (options.getConcurrency() != null) {
optionBuilder.setConcurrency(options.getConcurrency().getValue());
}
if (options.getConsistency() != null) {
optionBuilder.setConsistency(options.getConsistency().getValue());
}
if (retryPolicyBuilder != null) {
optionBuilder.setRetryPolicy(retryPolicyBuilder.build());
}
}
DaprProtos.SaveStateEnvelope.Builder builder = DaprProtos.SaveStateEnvelope.newBuilder();
for (StateKeyValue state : states) {
Map<String, Object> mapState = transformStateKeyValueToMap(state, mapOptions);
listStates.add(mapState);
};
Map<String, Object> mapStates = new HashMap<>();
mapStates.put("Requests", listStates);
byte[] byteRequests = objectSerializer.serialize(mapStates);
DaprProtos.SaveStateEnvelope envelope = DaprProtos.SaveStateEnvelope.parseFrom(byteRequests);
byte[] byteState = objectSerializer.serialize(state.getValue());
Any data = Any.newBuilder().setValue(ByteString.copyFrom(byteState)).build();
DaprProtos.StateRequest.Builder stateBuilder = DaprProtos.StateRequest.newBuilder()
.setEtag(state.getEtag())
.setKey(state.getKey())
.setValue(data);
if(optionBuilder != null) {
stateBuilder.setOptions(optionBuilder.build());
}
builder.addRequests(stateBuilder.build());
}
DaprProtos.SaveStateEnvelope envelope = builder.build();
ListenableFuture<Empty> futureEmpty = client.saveState(envelope);
return Mono.just(futureEmpty).flatMap(f -> {
try {
@ -226,9 +265,6 @@ class DaprClientGrpcAdapter implements DaprClient {
}
}
/**
* {@inheritDoc}
*/
@Override
public <T> Mono<Void> saveState(String key, String etag, T value, StateOptions options) {
StateKeyValue<T> state = new StateKeyValue<>(value, key, etag);
@ -242,10 +278,45 @@ class DaprClientGrpcAdapter implements DaprClient {
@Override
public <T> Mono<Void> deleteState(StateKeyValue<T> state, StateOptions options) {
try {
Map<String, Object> mapOptions = transformStateOptionsToMap(options);
Map<String, Object> mapState = transformStateKeyValueToMap(state, mapOptions);
byte[] serializedState = objectSerializer.serialize(mapState);
DaprProtos.DeleteStateEnvelope envelope = DaprProtos.DeleteStateEnvelope.parseFrom(serializedState);
DaprProtos.StateOptions.Builder optionBuilder = null;
if (options != null) {
optionBuilder = DaprProtos.StateOptions.newBuilder();
DaprProtos.RetryPolicy.Builder retryPolicyBuilder = null;
if (options.getRetryPolicy() != null) {
retryPolicyBuilder = DaprProtos.RetryPolicy.newBuilder();
StateOptions.RetryPolicy retryPolicy = options.getRetryPolicy();
if (options.getRetryPolicy().getInterval() != null) {
Duration.Builder durationBuilder = Duration.newBuilder()
.setNanos(retryPolicy.getInterval().getNano())
.setSeconds(retryPolicy.getInterval().getSeconds());
retryPolicyBuilder.setInterval(durationBuilder.build());
}
retryPolicyBuilder.setThreshold(objectSerializer.deserialize(retryPolicy.getThreshold(), int.class));
if (retryPolicy.getPattern() != null) {
retryPolicyBuilder.setPattern(retryPolicy.getPattern().getValue());
}
}
optionBuilder = DaprProtos.StateOptions.newBuilder();
if (options.getConcurrency() != null) {
optionBuilder.setConcurrency(options.getConcurrency().getValue());
}
if (options.getConsistency() != null) {
optionBuilder.setConsistency(options.getConsistency().getValue());
}
if (retryPolicyBuilder != null) {
optionBuilder.setRetryPolicy(retryPolicyBuilder.build());
}
}
DaprProtos.DeleteStateEnvelope.Builder builder = DaprProtos.DeleteStateEnvelope.newBuilder()
.setEtag(state.getEtag())
.setKey(state.getKey());
if (optionBuilder != null) {
builder.setOptions(optionBuilder.build());
}
DaprProtos.DeleteStateEnvelope envelope = builder.build();
ListenableFuture<Empty> futureEmpty = client.deleteState(envelope);
return Mono.just(futureEmpty).flatMap(f -> {
try {
@ -262,6 +333,7 @@ class DaprClientGrpcAdapter implements DaprClient {
/**
* Operation not supported for GRPC
*
* @throws UnsupportedOperationException every time is called.
*/
@Override
@ -271,6 +343,7 @@ class DaprClientGrpcAdapter implements DaprClient {
/**
* Operation not supported for GRPC
*
* @throws UnsupportedOperationException every time is called.
*/
@Override
@ -280,6 +353,7 @@ class DaprClientGrpcAdapter implements DaprClient {
/**
* Operation not supported for GRPC
*
* @throws UnsupportedOperationException every time is called.
*/
@Override
@ -289,6 +363,7 @@ class DaprClientGrpcAdapter implements DaprClient {
/**
* Operation not supported for GRPC
*
* @throws UnsupportedOperationException every time is called.
*/
@Override
@ -298,6 +373,7 @@ class DaprClientGrpcAdapter implements DaprClient {
/**
* Operation not supported for GRPC
*
* @throws UnsupportedOperationException every time is called.
*/
@Override
@ -307,6 +383,7 @@ class DaprClientGrpcAdapter implements DaprClient {
/**
* Operation not supported for GRPC
*
* @throws UnsupportedOperationException every time is called.
*/
@Override
@ -316,6 +393,7 @@ class DaprClientGrpcAdapter implements DaprClient {
/**
* Operation not supported for GRPC
*
* @throws UnsupportedOperationException every time is called.
*/
@Override
@ -324,46 +402,26 @@ class DaprClientGrpcAdapter implements DaprClient {
}
/**
* Converts state options to map.
*
* TODO: Move this logic to StateOptions.
* @param options Instance to have is methods converted into map.
* @return Map for the state options.
* @throws IllegalAccessException Cannot extract params.
* Builds the object io.dapr.{@link DaprProtos.InvokeServiceEnvelope} to be send based on the parameters.
* @param verb String that must match HTTP Methods
* @param appId The application id to be invoked
* @param method The application method to be invoked
* @param request The body of the request to be send as part of the invokation
* @param <K> The Type of the Body
* @return The object to be sent as part of the invokation.
* @throws IOException If there's an issue serializing the request.
*/
private Map<String, Object> transformStateOptionsToMap(StateOptions options)
throws IllegalAccessException {
Map<String, Object> mapOptions = null;
if (options != null) {
mapOptions = new HashMap<>();
for (Field field : options.getClass().getFields()) {
Object fieldValue = field.get(options);
if (fieldValue != null) {
mapOptions.put(field.getName(), fieldValue);
}
}
private <K> DaprProtos.InvokeServiceEnvelope buildInvokeServiceEnvelope(
String verb, String appId, String method, K request) throws IOException {
DaprProtos.InvokeServiceEnvelope.Builder envelopeBuilder = DaprProtos.InvokeServiceEnvelope.newBuilder()
.setId(appId)
.setMethod(verb);
if (request != null) {
byte[] byteRequest = objectSerializer.serialize(request);
Any data = Any.newBuilder().setValue(ByteString.copyFrom(byteRequest)).build();
envelopeBuilder.setData(data);
}
return mapOptions;
return envelopeBuilder.build();
}
/**
* Creates an map for the given key-value operation.
*
* // TODO: Move this logic into StateKeyValue.
* @param state Key value for the state change.
* @param mapOptions Options to be applied to this operation.
* @return Map for the key-value operation.
* @throws IllegalAccessException Cannot identify key-value attributes.
*/
private Map<String, Object> transformStateKeyValueToMap(StateKeyValue state, Map<String, Object> mapOptions)
throws IllegalAccessException {
Map<String, Object> mapState = new HashMap<>();
for (Field field : state.getClass().getFields()) {
mapState.put(field.getName(), field.get(state));
}
if (mapOptions != null && !mapOptions.isEmpty()) {
mapState.put("Options", mapOptions);
}
return mapState;
}
}

View File

@ -11,6 +11,7 @@ import io.dapr.utils.Constants;
import io.dapr.utils.ObjectSerializer;
import reactor.core.publisher.Mono;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
@ -93,10 +94,10 @@ public class DaprClientHttpAdapter implements DaprClient {
}
String path = String.format("%s/%s/method/%s", Constants.INVOKE_PATH, appId, method);
byte[] serializedRequestBody = objectSerializer.serialize(request);
return this.client.invokeAPI(httMethod, path, serializedRequestBody, metadata)
.flatMap(r -> {
Mono<DaprHttp.Response> response = this.client.invokeAPI(httMethod, path, serializedRequestBody, metadata);
return response.flatMap(r -> {
try {
return Mono.just(objectSerializer.deserialize(r, clazz));
return Mono.just(objectSerializer.deserialize(r.getBody(), clazz));
} catch (Exception ex) {
return Mono.error(ex);
}
@ -168,7 +169,7 @@ public class DaprClientHttpAdapter implements DaprClient {
* {@inheritDoc}
*/
@Override
public <T, K> Mono<T> getState(StateKeyValue<K> state, StateOptions options, Class<T> clazz) {
public <T> Mono<StateKeyValue<T>> getState(StateKeyValue<T> state, StateOptions stateOptions, Class<T> clazz) {
try {
if (state.getKey() == null) {
throw new IllegalArgumentException("Name cannot be null or empty.");
@ -181,12 +182,12 @@ public class DaprClientHttpAdapter implements DaprClient {
StringBuilder url = new StringBuilder(Constants.STATE_PATH)
.append("/")
.append(state.getKey())
.append(getOptionsAsQueryParameter(options));
.append(getOptionsAsQueryParameter(stateOptions));
return this.client
.invokeAPI(DaprHttp.HttpMethods.GET.name(), url.toString(), headers)
.flatMap(s -> {
try {
return Mono.just(objectSerializer.deserialize(s, clazz));
return Mono.just(buildStateKeyValue(s, state.getKey(), clazz));
} catch (Exception ex) {
return Mono.error(ex);
}
@ -258,7 +259,14 @@ public class DaprClientHttpAdapter implements DaprClient {
@Override
public Mono<String> invokeActorMethod(String actorType, String actorId, String methodName, String jsonPayload) {
String url = String.format(Constants.ACTOR_METHOD_RELATIVE_URL_FORMAT, actorType, actorId, methodName);
return this.client.invokeAPI(DaprHttp.HttpMethods.POST.name(), url, jsonPayload, null);
Mono<DaprHttp.Response> responseMono = this.client.invokeAPI(DaprHttp.HttpMethods.POST.name(), url, jsonPayload, null);
return responseMono.flatMap(f -> {
try {
return Mono.just(objectSerializer.deserialize(f.getBody(), String.class));
} catch (Exception ex) {
return Mono.error(ex);
}
});
}
/**
@ -267,7 +275,14 @@ public class DaprClientHttpAdapter implements DaprClient {
@Override
public Mono<String> getActorState(String actorType, String actorId, String keyName) {
String url = String.format(Constants.ACTOR_STATE_KEY_RELATIVE_URL_FORMAT, actorType, actorId, keyName);
return this.client.invokeAPI(DaprHttp.HttpMethods.GET.name(), url, "", null);
Mono<DaprHttp.Response> responseMono = this.client.invokeAPI(DaprHttp.HttpMethods.GET.name(), url, "", null);
return responseMono.flatMap(f -> {
try {
return Mono.just(objectSerializer.deserialize(f.getBody(), String.class));
} catch (Exception ex) {
return Mono.error(ex);
}
});
}
/**
@ -361,4 +376,23 @@ public class DaprClientHttpAdapter implements DaprClient {
return mapOptions;
}
/**
* Builds a StateKeyValue object based on the Response
* @param resonse The response of the HTTP Call
* @param requestedKey The Key Requested.
* @param clazz The Class of the Value of the state
* @param <T> The Type of the Value of the state
* @return A StateKeyValue instance
* @throws IOException If there's a issue deserialzing the response.
*/
private <T> StateKeyValue<T> buildStateKeyValue(DaprHttp.Response resonse, String requestedKey, Class<T> clazz) throws IOException {
T value = objectSerializer.deserialize(resonse.getBody(), clazz);
String key = requestedKey;
String etag = null;
if (resonse.getHeaders() != null && resonse.getHeaders().containsKey("ETag")) {
etag = objectSerializer.deserialize(resonse.getHeaders().get("ETag"), String.class);
}
return new StateKeyValue<>(value, key, etag);
}
}

View File

@ -8,16 +8,18 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import io.dapr.exceptions.DaprError;
import io.dapr.exceptions.DaprException;
import io.dapr.utils.Constants;
import okhttp3.*;
import io.dapr.utils.ObjectSerializer;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import reactor.core.publisher.Mono;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -27,7 +29,31 @@ class DaprHttp {
/**
* HTTP Methods supported.
*/
enum HttpMethods { GET, PUT, POST, DELETE; }
enum HttpMethods {GET, PUT, POST, DELETE;}
static class Response {
private byte[] body;
private Map<String, String> headers;
private int statusCode;
public Response(byte[] body, Map<String, String> headers, int statusCode) {
this.body = body;
this.headers = headers;
this.statusCode = statusCode;
}
public byte[] getBody() {
return body;
}
public Map<String, String> getHeaders() {
return headers;
}
public int getStatusCode() {
return statusCode;
}
}
/**
* Defines the standard application/json type for HTTP calls in Dapr.
@ -86,8 +112,8 @@ class DaprHttp {
* @param urlString url as String.
* @return Asynchronous text
*/
public Mono<String> invokeAPI(String method, String urlString, Map<String, String> headers) {
return this.invokeAPI(method, urlString, (String) null, headers);
public Mono<Response> invokeAPI(String method, String urlString, Map<String, String> headers) {
return this.invokeAPI(method, urlString, (byte[]) null, headers);
}
/**
@ -98,13 +124,8 @@ class DaprHttp {
* @param content payload to be posted.
* @return Asynchronous text
*/
public Mono<String> invokeAPI(String method, String urlString, String content, Map<String, String> headers) {
return this.invokeAPI(
method,
urlString,
content == null ? EMPTY_BYTES : content.getBytes(StandardCharsets.UTF_8),
headers)
.map(s -> new String(s, StandardCharsets.UTF_8));
public Mono<Response> invokeAPI(String method, String urlString, String content, Map<String, String> headers) {
return this.invokeAPI(method, urlString, content == null ? EMPTY_BYTES : content.getBytes(StandardCharsets.UTF_8), headers);
}
/**
@ -115,12 +136,12 @@ class DaprHttp {
* @param content payload to be posted.
* @return Asynchronous text
*/
public Mono<byte[]> invokeAPI(String method, String urlString, byte[] content, Map<String, String> headers) {
public Mono<Response> invokeAPI(String method, String urlString, byte[] content, Map<String, String> headers) {
return Mono.fromFuture(CompletableFuture.supplyAsync(
() -> {
try {
String requestId = UUID.randomUUID().toString();
RequestBody body;
RequestBody body = REQUEST_BODY_EMPTY_JSON;
String contentType = headers != null ? headers.get("content-type") : null;
MediaType mediaType = contentType == null ? MEDIA_TYPE_APPLICATION_JSON : MediaType.get(contentType);
@ -128,7 +149,7 @@ class DaprHttp {
body = mediaType.equals(MEDIA_TYPE_APPLICATION_JSON) ?
REQUEST_BODY_EMPTY_JSON : RequestBody.Companion.create(new byte[0], mediaType);
} else {
body = RequestBody.Companion.create(content, mediaType);
body = RequestBody.Companion.create(content, mediaType);
}
Request.Builder requestBuilder = new Request.Builder()
@ -150,17 +171,22 @@ class DaprHttp {
Request request = requestBuilder.build();
try (Response response = this.httpClient.newCall(request).execute()) {
byte[] responseBody = response.body().bytes();
try (okhttp3.Response response = this.httpClient.newCall(request).execute()) {
if (!response.isSuccessful()) {
DaprError error = this.parseDaprError(responseBody);
DaprError error = parseDaprError(response.body().bytes());
if ((error != null) && (error.getErrorCode() != null) && (error.getMessage() != null)) {
throw new DaprException(error);
throw new RuntimeException(new DaprException(error));
}
throw new IOException("Unknown error.");
throw new RuntimeException("Unknown error.");
}
return responseBody == null ? EMPTY_BYTES : responseBody;
Map<String, String> mapHeaders = new HashMap<>();
byte[] result = response.body().bytes();
response.headers().forEach(pair -> {
mapHeaders.put(pair.getFirst(), pair.getSecond());
});
return new Response(result, mapHeaders, response.code());
}
} catch (Exception e) {
throw new RuntimeException(e);
@ -178,7 +204,6 @@ class DaprHttp {
if (json == null) {
return null;
}
return OBJECT_MAPPER.readValue(json, DaprError.class);
}

View File

@ -4,26 +4,89 @@
*/
package io.dapr.client.domain;
/**
* This class reprent what a State is
* @param <T>
*/
public class StateKeyValue<T> {
/**
* The value of the state
*/
private final T value;
/**
* The key of the state
*/
private final String key;
/**
* The ETag to be used
* Keep in mind that for some state stores (like reids) only numbers are supported.
*/
private final String etag;
/**
* Create an inmutable state
* @param value
* @param key
* @param etag
*/
public StateKeyValue(T value, String key, String etag) {
this.value = value;
this.key = key;
this.etag = etag;
}
/**
* Retrieves the Value of the state
* @return
*/
public T getValue() {
return value;
}
/**
* Retrieves the Key of the state
* @return
*/
public String getKey() {
return key;
}
/**
* Retrieve the ETag of this state
* @return
*/
public String getEtag() {
return etag;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof StateKeyValue)) return false;
StateKeyValue<?> that = (StateKeyValue<?>) o;
if (getValue() != null ? !getValue().equals(that.getValue()) : that.getValue() != null) return false;
if (getKey() != null ? !getKey().equals(that.getKey()) : that.getKey() != null) return false;
if (getEtag() != null ? !getEtag().equals(that.getEtag()) : that.getEtag() != null) return false;
return true;
}
@Override
public int hashCode() {
int result = getValue() != null ? getValue().hashCode() : 0;
result = 31 * result + (getKey() != null ? getKey().hashCode() : 0);
result = 31 * result + (getEtag() != null ? getEtag().hashCode() : 0);
return result;
}
@Override
public String toString() {
return "StateKeyValue{" +
"value=" + value +
", key='" + key + '\'' +
", etag='" + etag + '\'' +
'}';
}
}

View File

@ -4,16 +4,98 @@
*/
package io.dapr.client.domain;
import java.time.Duration;
public class StateOptions {
private final Consistency consistency;
private final Concurrency concurrency;
private final RetryPolicy retryPolicy;
private final String consistency;
public StateOptions(String consistency) {
public StateOptions(Consistency consistency, Concurrency concurrency, RetryPolicy retryPolicy) {
this.consistency = consistency;
this.concurrency = concurrency;
this.retryPolicy = retryPolicy;
}
public String getConsistency() {
public Concurrency getConcurrency() {
return concurrency;
}
public Consistency getConsistency() {
return consistency;
}
public RetryPolicy getRetryPolicy() {
return retryPolicy;
}
public static enum Consistency {
EVENTUAL("eventual"),
STRONG("strong");
private final String value;
private Consistency(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}
public static enum Concurrency {
FIRST_WRITE("first-write"),
LAST_WRITE ("last-write");
private final String value;
private Concurrency(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}
public static class RetryPolicy {
public static enum Pattern {
LINEAR("linear"),
EXPONENTIAL("exponential");
private String value;
private Pattern(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}
private final Duration interval;
private final String threshold;
private final Pattern pattern;
public RetryPolicy(Duration interval, String threshold, Pattern pattern) {
this.interval = interval;
this.threshold = threshold;
this.pattern = pattern;
}
public Duration getInterval() {
return interval;
}
public String getThreshold() {
return threshold;
}
public Pattern getPattern() {
return pattern;
}
}
}

View File

@ -0,0 +1,142 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
package io.dapr.utils;
import java.time.Duration;
public class DurationUtils {
/**
* Converts time from the String format used by Dapr into a Duration.
*
* @param valueString A String representing time in the Dapr runtime's format (e.g. 4h15m50s60ms).
* @return A Duration
*/
public static Duration ConvertDurationFromDaprFormat(String valueString) {
// Convert the format returned by the Dapr runtime into Duration
// An example of the format is: 4h15m50s60ms. It does not include days.
int hIndex = valueString.indexOf('h');
int mIndex = valueString.indexOf('m');
int sIndex = valueString.indexOf('s');
int msIndex = valueString.indexOf("ms");
String hoursSpan = valueString.substring(0, hIndex);
int hours = Integer.parseInt(hoursSpan);
int days = hours / 24;
hours = hours % 24;
String minutesSpan = valueString.substring(hIndex + 1, mIndex);
int minutes = Integer.parseInt(minutesSpan);
String secondsSpan = valueString.substring(mIndex + 1, sIndex);
int seconds = Integer.parseInt(secondsSpan);
String millisecondsSpan = valueString.substring(sIndex + 1, msIndex);
int milliseconds = Integer.parseInt(millisecondsSpan);
return Duration.ZERO
.plusDays(days)
.plusHours(hours)
.plusMinutes(minutes)
.plusSeconds(seconds)
.plusMillis(milliseconds);
}
/**
* Converts a Duration to the format used by the Dapr runtime.
*
* @param value Duration
* @return The Duration formatted as a String in the format the Dapr runtime uses (e.g. 4h15m50s60ms)
*/
public static String ConvertDurationToDaprFormat(Duration value) {
String stringValue = "";
// return empty string for anything negative, it'll only happen for reminder "periods", not dueTimes. A
// negative "period" means fire once only.
if (value == Duration.ZERO ||
(value.compareTo(Duration.ZERO) == 1)) {
long hours = getDaysPart(value) * 24 + getHoursPart(value);
StringBuilder sb = new StringBuilder();
sb.append(hours);
sb.append("h");
sb.append(getMinutesPart((value)));
sb.append("m");
sb.append(getSecondsPart((value)));
sb.append("s");
sb.append(getMilliSecondsPart((value)));
sb.append("ms");
return sb.toString();
}
return stringValue;
}
/**
* Helper to get the "days" part of the Duration. For example if the duration is 26 hours, this returns 1.
*
* @param d Duration
* @return Number of days.
*/
static long getDaysPart(Duration d) {
long t = d.getSeconds() / 60 / 60 / 24;
return t;
}
/**
* Helper to get the "hours" part of the Duration. For example if the duration is 26 hours, this is 1 day, 2 hours, so this returns 2.
*
* @param d The duration to parse
* @return the hour part of the duration
*/
static long getHoursPart(Duration d) {
long u = (d.getSeconds() / 60 / 60) % 24;
return u;
}
/**
* Helper to get the "minutes" part of the Duration.
*
* @param d The duration to parse
* @return the minutes part of the duration
*/
static long getMinutesPart(Duration d) {
long u = (d.getSeconds() / 60) % 60;
return u;
}
/**
* Helper to get the "seconds" part of the Duration.
*
* @param d The duration to parse
* @return the seconds part of the duration
*/
static long getSecondsPart(Duration d) {
long u = d.getSeconds() % 60;
return u;
}
/**
* Helper to get the "millis" part of the Duration.
*
* @param d The duration to parse
* @return the milliseconds part of the duration
*/
static long getMilliSecondsPart(Duration d) {
long u = d.toMillis() % 1000;
return u;
}
}

View File

@ -0,0 +1,610 @@
package io.dapr.client;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.SettableFuture;
import com.google.protobuf.Any;
import com.google.protobuf.ByteString;
import com.google.protobuf.Empty;
import io.dapr.DaprGrpc;
import io.dapr.DaprProtos;
import io.dapr.client.domain.StateKeyValue;
import io.dapr.client.domain.StateOptions;
import io.dapr.client.domain.Verb;
import io.dapr.utils.ObjectSerializer;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
import org.junit.Before;
import org.junit.Test;
import reactor.core.publisher.Mono;
import javax.annotation.Nullable;
import java.io.IOException;
import java.time.Duration;
import static com.google.common.util.concurrent.Futures.addCallback;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
public class DaprClientGrpcAdapterTest {
private DaprGrpc.DaprFutureStub client;
private DaprClientGrpcAdapter adater;
private ObjectSerializer serializer;
@Before
public void setup() {
client = mock(DaprGrpc.DaprFutureStub.class);
adater = new DaprClientGrpcAdapter(client);
serializer = new ObjectSerializer();
}
@Test(expected = UnsupportedOperationException.class)
public void unregisterActorTimerTest() {
Mono<Void> result = adater.unregisterActorTimer("actorType", "actorId", "timerName");
result.block();
}
@Test(expected = UnsupportedOperationException.class)
public void registerActorTimerTest() {
Mono<Void> result = adater.registerActorTimer("actorType", "actorId", "timerName" , "DATA");
result.block();
}
@Test(expected = UnsupportedOperationException.class)
public void unregisterActorReminderTest() {
Mono<Void> result = adater.unregisterActorReminder("actorType", "actorId", "reminderName");
result.block();
}
@Test(expected = UnsupportedOperationException.class)
public void registerActorReminderTest() {
Mono<Void> result = adater.registerActorReminder("actorType", "actorId", "reminderName", "DATA");
result.block();
}
@Test(expected = UnsupportedOperationException.class)
public void saveActorStateTransactionallyTest() {
Mono<Void> result = adater.saveActorStateTransactionally("actorType", "actorId", "DATA");
result.block();
}
@Test(expected = UnsupportedOperationException.class)
public void getActorStateTest() {
Mono<String> result = adater.getActorState("actorType", "actorId", "keyName");
String state = result.block();
}
@Test(expected = UnsupportedOperationException.class)
public void invokeActorMethodTest() {
Mono<String> result = adater.invokeActorMethod("actorType", "actorId", "methodName", "jsonPlayload");
String monoResult = result.block();
}
@Test(expected = RuntimeException.class)
public void publishEventExceptionThrownTest() {
when(client.publishEvent(any(DaprProtos.PublishEventEnvelope.class)))
.thenThrow(RuntimeException.class);
Mono<Void> result = adater.publishEvent("topic", "object");
result.block();
}
@Test(expected = RuntimeException.class)
public void publishEventCallbackExceptionThrownTest() {
SettableFuture<Empty> settableFuture = SettableFuture.create();
RuntimeException ex = new RuntimeException("An Exception");
MockCallback<Empty> callback = new MockCallback<Empty>(ex);
addCallback(settableFuture, callback, directExecutor());
when(client.publishEvent(any(DaprProtos.PublishEventEnvelope.class)))
.thenReturn(settableFuture);
Mono<Void> result = adater.publishEvent("topic", "object");
settableFuture.setException(ex);
result.block();
}
@Test
public void publishEventTest() {
SettableFuture<Empty> settableFuture = SettableFuture.create();
MockCallback<Empty> callback = new MockCallback<Empty>(Empty.newBuilder().build());
addCallback(settableFuture, callback, directExecutor());
when(client.publishEvent(any(DaprProtos.PublishEventEnvelope.class)))
.thenReturn(settableFuture);
Mono<Void> result = adater.publishEvent("topic", "object");
settableFuture.set(Empty.newBuilder().build());
result.block();
assertTrue(callback.wasCalled);
}
@Test
public void publishEventObjectTest() {
SettableFuture<Empty> settableFuture = SettableFuture.create();
MockCallback<Empty> callback = new MockCallback<Empty>(Empty.newBuilder().build());
addCallback(settableFuture, callback, directExecutor());
when(client.publishEvent(any(DaprProtos.PublishEventEnvelope.class)))
.thenReturn(settableFuture);
MyObject event = new MyObject(1, "Event");
Mono<Void> result = adater.publishEvent("topic", event);
settableFuture.set(Empty.newBuilder().build());
result.block();
assertTrue(callback.wasCalled);
}
@Test(expected = RuntimeException.class)
public void invokeBindingExceptionThrownTest() {
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenThrow(RuntimeException.class);
Mono<Void> result = adater.invokeBinding("BindingName", "request");
result.block();
}
@Test(expected = RuntimeException.class)
public void invokeBindingCallbackExceptionThrownTest() {
SettableFuture<Empty> settableFuture = SettableFuture.create();
RuntimeException ex = new RuntimeException("An Exception");
MockCallback<Empty> callback =
new MockCallback<Empty>(ex);
addCallback(settableFuture, callback, directExecutor());
settableFuture.setException(ex);
when(client.invokeBinding(any(DaprProtos.InvokeBindingEnvelope.class)))
.thenReturn(settableFuture);
Mono<Void> result = adater.invokeBinding("BindingName", "request");
result.block();
}
@Test
public void invokeBindingTest() {
SettableFuture<Empty> settableFuture = SettableFuture.create();
MockCallback<Empty> callback = new MockCallback<Empty>(Empty.newBuilder().build());
addCallback(settableFuture, callback, directExecutor());
when(client.invokeBinding(any(DaprProtos.InvokeBindingEnvelope.class)))
.thenReturn(settableFuture);
Mono<Void> result = adater.invokeBinding("BindingName", "request");
settableFuture.set(Empty.newBuilder().build());
result.block();
assertTrue(callback.wasCalled);
}
@Test
public void invokeBindingObjectTest() {
SettableFuture<Empty> settableFuture = SettableFuture.create();
MockCallback<Empty> callback = new MockCallback<Empty>(Empty.newBuilder().build());
addCallback(settableFuture, callback, directExecutor());
when(client.invokeBinding(any(DaprProtos.InvokeBindingEnvelope.class)))
.thenReturn(settableFuture);
MyObject event = new MyObject(1, "Event");
Mono<Void> result = adater.invokeBinding("BindingName", event);
settableFuture.set(Empty.newBuilder().build());
result.block();
assertTrue(callback.wasCalled);
}
@Test(expected = RuntimeException.class)
public void invokeServiceVoidExceptionThrownTest() {
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenThrow(RuntimeException.class);
Mono<Void> result = adater.invokeService(Verb.GET, "appId", "method", "request", null);
result.block();
}
@Test(expected = RuntimeException.class)
public void invokeServiceVoidCallbackExceptionThrownTest() {
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
RuntimeException ex = new RuntimeException("An Exception");
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(ex);
addCallback(settableFuture, callback, directExecutor());
settableFuture.setException(ex);
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
Mono<Void> result = adater.invokeService(Verb.GET, "appId", "method", "request", null);
result.block();
}
@Test
public void invokeServiceVoidTest() throws Exception {
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(DaprProtos.InvokeServiceResponseEnvelope.newBuilder()
.setData(getAny("Value")).build());
addCallback(settableFuture, callback, directExecutor());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
Mono<Void> result = adater.invokeService(Verb.GET, "appId", "method", "request", null);
settableFuture.set(DaprProtos.InvokeServiceResponseEnvelope.newBuilder().setData(getAny("Value")).build());
result.block();
assertTrue(callback.wasCalled);
}
@Test
public void invokeServiceVoidObjectTest() throws Exception {
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(DaprProtos.InvokeServiceResponseEnvelope.newBuilder()
.setData(getAny("Value")).build());
addCallback(settableFuture, callback, directExecutor());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
MyObject request = new MyObject(1, "Event");
Mono<Void> result = adater.invokeService(Verb.GET, "appId", "method", request, null);
settableFuture.set(DaprProtos.InvokeServiceResponseEnvelope.newBuilder().setData(getAny("Value")).build());
result.block();
assertTrue(callback.wasCalled);
}
@Test(expected = RuntimeException.class)
public void invokeServiceExceptionThrownTest() {
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenThrow(RuntimeException.class);
Mono<String> result = adater.invokeService(Verb.GET, "appId", "method", "request", null, String.class);
result.block();
}
@Test(expected = RuntimeException.class)
public void invokeServiceCallbackExceptionThrownTest() {
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
RuntimeException ex = new RuntimeException("An Exception");
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(ex);
addCallback(settableFuture, callback, directExecutor());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
Mono<String> result = adater.invokeService(Verb.GET, "appId", "method", "request", null, String.class);
settableFuture.setException(ex);
result.block();
}
@Test
public void invokeServiceTest() throws Exception {
String expected = "Value";
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(DaprProtos.InvokeServiceResponseEnvelope.newBuilder()
.setData(getAny(expected)).build());
addCallback(settableFuture, callback, directExecutor());
settableFuture.set(DaprProtos.InvokeServiceResponseEnvelope.newBuilder().setData(getAny(expected)).build());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
Mono<String> result = adater.invokeService(Verb.GET, "appId", "method", "request", null, String.class);
String strOutput = result.block();
assertEquals(expected, strOutput);
}
@Test
public void invokeServiceObjectTest() throws Exception {
MyObject resultObj = new MyObject(1, "Value");
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(DaprProtos.InvokeServiceResponseEnvelope.newBuilder()
.setData(getAny(resultObj)).build());
addCallback(settableFuture, callback, directExecutor());
settableFuture.set(DaprProtos.InvokeServiceResponseEnvelope.newBuilder().setData(getAny(resultObj)).build());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
Mono<String> result = adater.invokeService(Verb.GET, "appId", "method", "request", null, String.class);
String strOutput = result.block();
assertEquals(serializer.serializeString(resultObj), strOutput);
}
@Test(expected = RuntimeException.class)
public void invokeServiceNoRequestBodyExceptionThrownTest() {
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenThrow(RuntimeException.class);
Mono<String> result = adater.invokeService(Verb.GET, "appId", "method", null, String.class);
result.block();
}
@Test(expected = RuntimeException.class)
public void invokeServiceNoRequestCallbackExceptionThrownTest() {
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
RuntimeException ex = new RuntimeException("An Exception");
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(ex);
addCallback(settableFuture, callback, directExecutor());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
Mono<String> result = adater.invokeService(Verb.GET, "appId", "method", null, String.class);
settableFuture.setException(ex);
result.block();
}
@Test
public void invokeServiceNoRequestBodyTest() throws Exception {
String expected = "Value";
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(DaprProtos.InvokeServiceResponseEnvelope.newBuilder()
.setData(getAny(expected)).build());
addCallback(settableFuture, callback, directExecutor());
settableFuture.set(DaprProtos.InvokeServiceResponseEnvelope.newBuilder().setData(getAny(expected)).build());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
Mono<String> result = adater.invokeService(Verb.GET, "appId", "method",null, String.class);
String strOutput = result.block();
assertEquals(expected, strOutput);
}
@Test
public void invokeServiceNoRequestBodyObjectTest() throws Exception {
MyObject resultObj = new MyObject(1, "Value");
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(DaprProtos.InvokeServiceResponseEnvelope.newBuilder()
.setData(getAny(resultObj)).build());
addCallback(settableFuture, callback, directExecutor());
settableFuture.set(DaprProtos.InvokeServiceResponseEnvelope.newBuilder().setData(getAny(resultObj)).build());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
Mono<String> result = adater.invokeService(Verb.GET, "appId", "method",null, String.class);
String strOutput = result.block();
assertEquals(serializer.serializeString(resultObj), strOutput);
}
@Test(expected = RuntimeException.class)
public void invokeServiceByteRequestExceptionThrownTest() throws IOException {
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenThrow(RuntimeException.class);
String request = "Request";
byte[] byteRequest = serializer.serialize(request);
Mono<byte[]> result = adater.invokeService(Verb.GET, "appId", "method", byteRequest, null);
result.block();
}
@Test(expected = RuntimeException.class)
public void invokeServiceByteRequestCallbackExceptionThrownTest() throws IOException {
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
RuntimeException ex = new RuntimeException("An Exception");
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(ex);
addCallback(settableFuture, callback, directExecutor());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
String request = "Request";
byte[] byteRequest = serializer.serialize(request);
Mono<byte[]> result = adater.invokeService(Verb.GET, "appId", "method", byteRequest, null);
settableFuture.setException(ex);
result.block();
}
@Test
public void invokeByteRequestServiceTest() throws Exception {
String expected = "Value";
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(DaprProtos.InvokeServiceResponseEnvelope.newBuilder()
.setData(getAny(expected)).build());
addCallback(settableFuture, callback, directExecutor());
settableFuture.set(DaprProtos.InvokeServiceResponseEnvelope.newBuilder().setData(getAny(expected)).build());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
String request = "Request";
byte[] byteRequest = serializer.serialize(request);
Mono<byte[]> result = adater.invokeService(Verb.GET, "appId", "method", byteRequest, null);
byte[] byteOutput = result.block();
String strOutput = serializer.deserialize(byteOutput, String.class);
assertEquals(expected, strOutput);
}
@Test
public void invokeServiceByteRequestObjectTest() throws Exception {
MyObject resultObj = new MyObject(1, "Value");
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(DaprProtos.InvokeServiceResponseEnvelope.newBuilder()
.setData(getAny(resultObj)).build());
addCallback(settableFuture, callback, directExecutor());
settableFuture.set(DaprProtos.InvokeServiceResponseEnvelope.newBuilder().setData(getAny(resultObj)).build());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
String request = "Request";
byte[] byteRequest = serializer.serialize(request);
Mono<byte[]> result = adater.invokeService(Verb.GET, "appId", "method", byteRequest, null);
byte[] byteOutput = result.block();
assertEquals(resultObj, serializer.deserialize(byteOutput, MyObject.class));
}
@Test(expected = RuntimeException.class)
public void invokeServiceNoRequestNoClassBodyExceptionThrownTest() {
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenThrow(RuntimeException.class);
Mono<Void> result = adater.invokeService(Verb.GET, "appId", "method", null);
result.block();
}
@Test(expected = RuntimeException.class)
public void invokeServiceNoRequestNoClassCallbackExceptionThrownTest() {
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
RuntimeException ex = new RuntimeException("An Exception");
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(ex);
addCallback(settableFuture, callback, directExecutor());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
Mono<Void> result = adater.invokeService(Verb.GET, "appId", "method", null);
settableFuture.setException(ex);
result.block();
}
@Test
public void invokeServiceNoRequestNoClassBodyTest() throws Exception {
String expected = "Value";
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(DaprProtos.InvokeServiceResponseEnvelope.newBuilder()
.setData(getAny(expected)).build());
addCallback(settableFuture, callback, directExecutor());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
Mono<Void> result = adater.invokeService(Verb.GET, "appId", "method", null);
settableFuture.set(DaprProtos.InvokeServiceResponseEnvelope.newBuilder().setData(getAny(expected)).build());
result.block();
assertTrue(callback.wasCalled);
}
@Test
public void invokeServiceNoRequestNoClassBodyObjectTest() throws Exception {
MyObject resultObj = new MyObject(1, "Value");
SettableFuture<DaprProtos.InvokeServiceResponseEnvelope> settableFuture = SettableFuture.create();
MockCallback<DaprProtos.InvokeServiceResponseEnvelope> callback =
new MockCallback<DaprProtos.InvokeServiceResponseEnvelope>(DaprProtos.InvokeServiceResponseEnvelope.newBuilder()
.setData(getAny(resultObj)).build());
addCallback(settableFuture, callback, directExecutor());
settableFuture.set(DaprProtos.InvokeServiceResponseEnvelope.newBuilder().setData(getAny(resultObj)).build());
when(client.invokeService(any(DaprProtos.InvokeServiceEnvelope.class)))
.thenReturn(settableFuture);
Mono<Void> result = adater.invokeService(Verb.GET, "appId", "method", null);
result.block();
assertTrue(callback.wasCalled);
}
@Test(expected = RuntimeException.class)
public void getStateExceptionThrownTest() {
when(client.getState(any(io.dapr.DaprProtos.GetStateEnvelope.class))).thenThrow(RuntimeException.class);
StateKeyValue<String> key = buildStateKey(null, "Key1", "ETag1");
Mono<StateKeyValue<String>> result = adater.getState(key, null, String.class);
result.block();
}
@Test(expected = RuntimeException.class)
public void getStateCallbackExceptionThrownTest() {
SettableFuture<DaprProtos.GetStateResponseEnvelope> settableFuture = SettableFuture.create();
RuntimeException ex = new RuntimeException("An Exception");
MockCallback<DaprProtos.GetStateResponseEnvelope> callback =
new MockCallback<>(ex);
addCallback(settableFuture, callback, directExecutor());
when(client.getState(any(io.dapr.DaprProtos.GetStateEnvelope.class)))
.thenReturn(settableFuture);
StateKeyValue<String> key = buildStateKey(null, "Key1", "ETag1");
Mono<StateKeyValue<String>> result = adater.getState(key, null, String.class);
settableFuture.setException(ex);
result.block();
}
@Test
public void getStateStringValueNoOptionsTest() throws IOException {
String etag = "ETag1";
String key = "key1";
String expectedValue = "Expected state";
StateKeyValue<String> expectedState = buildStateKey(expectedValue, key, etag);
DaprProtos.GetStateResponseEnvelope responseEnvelope = DaprProtos.GetStateResponseEnvelope.newBuilder()
.setData(getAny(expectedValue))
.setEtag(etag)
.build();
SettableFuture<DaprProtos.GetStateResponseEnvelope> settableFuture = SettableFuture.create();
MockCallback<DaprProtos.GetStateResponseEnvelope> callback = new MockCallback<>(responseEnvelope);
addCallback(settableFuture, callback, directExecutor());
when(client.getState(any(io.dapr.DaprProtos.GetStateEnvelope.class)))
.thenReturn(settableFuture);
StateKeyValue<String> keyRequest = buildStateKey(null, key, etag);
Mono<StateKeyValue<String>> result = adater.getState(keyRequest, null, String.class);
settableFuture.set(responseEnvelope);
assertEquals(expectedState, result.block());
}
private <T> StateKeyValue<T> buildStateKey(T value, String key, String etag) {
return new StateKeyValue(value, key, etag);
}
private StateOptions buildStateOptions(StateOptions.Consistency consistency, StateOptions.Concurrency concurrency,
Duration interval, String threshold, StateOptions.RetryPolicy.Pattern pattern) {
StateOptions.RetryPolicy retryPolicy = null;
if (interval != null || threshold != null || pattern != null) {
retryPolicy = new StateOptions.RetryPolicy(interval, threshold, pattern);
}
StateOptions options = null;
if (consistency != null || concurrency != null || retryPolicy != null) {
options = new StateOptions(consistency, concurrency, retryPolicy);
}
return options;
}
private <T> Any getAny(T value) throws IOException {
byte[] byteValue = serializer.serialize(value);
return Any.newBuilder().setValue(ByteString.copyFrom(byteValue)).build();
}
private final class MockCallback<T> implements FutureCallback<T> {
@Nullable
private T value = null;
@Nullable
private Throwable failure = null;
private boolean wasCalled = false;
public MockCallback(T expectedValue) {
this.value = expectedValue;
}
public MockCallback(Throwable expectedFailure) {
this.failure = expectedFailure;
}
@Override
public synchronized void onSuccess(@NullableDecl T result) {
assertFalse(wasCalled);
wasCalled = true;
assertEquals(value, result);
}
@Override
public synchronized void onFailure(Throwable throwable) {
assertFalse(wasCalled);
wasCalled = true;
assertEquals(failure, throwable);
}
}
public static class MyObject {
private Integer id;
private String value;
public MyObject() {
}
public MyObject(Integer id, String value) {
this.id = id;
this.value = value;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof MyObject)) return false;
MyObject myObject = (MyObject) o;
if (!getId().equals(myObject.getId())) return false;
if (getValue() != null ? !getValue().equals(myObject.getValue()) : myObject.getValue() != null) return false;
return true;
}
@Override
public int hashCode() {
int result = getId().hashCode();
result = 31 * result + (getValue() != null ? getValue().hashCode() : 0);
return result;
}
}
}

View File

@ -15,6 +15,11 @@ import java.util.Map;
*/
public class DaprHttpStub extends DaprHttp {
public static class ResponseStub extends DaprHttp.Response {
public ResponseStub(byte[] body, Map<String, String> headers, int statusCode) {
super(body, headers, statusCode);
}
}
/**
* Instantiates a stub for DaprHttp
*/
@ -24,9 +29,10 @@ public class DaprHttpStub extends DaprHttp {
/**
* {@inheritDoc}
* @return
*/
@Override
public Mono<String> invokeAPI(String method, String urlString, Map<String, String> headers) {
public Mono<DaprHttp.Response> invokeAPI(String method, String urlString, Map<String, String> headers) {
return Mono.empty();
}
@ -34,7 +40,7 @@ public class DaprHttpStub extends DaprHttp {
* {@inheritDoc}
*/
@Override
public Mono<String> invokeAPI(String method, String urlString, String content, Map<String, String> headers) {
public Mono<DaprHttp.Response> invokeAPI(String method, String urlString, String content, Map<String, String> headers) {
return Mono.empty();
}
@ -42,7 +48,7 @@ public class DaprHttpStub extends DaprHttp {
* {@inheritDoc}
*/
@Override
public Mono<byte[]> invokeAPI(String method, String urlString, byte[] content, Map<String, String> headers) {
public Mono<DaprHttp.Response> invokeAPI(String method, String urlString, byte[] content, Map<String, String> headers) {
return Mono.empty();
}
}

View File

@ -4,6 +4,7 @@
*/
package io.dapr.client;
import io.dapr.utils.ObjectSerializer;
import okhttp3.*;
import okhttp3.mock.Behavior;
import okhttp3.mock.MockInterceptor;
@ -24,6 +25,8 @@ public class DaprHttpTest {
private MockInterceptor mockInterceptor;
private ObjectSerializer serializer = new ObjectSerializer();
private final String EXPECTED_RESULT = "{\"data\":\"ewoJCSJwcm9wZXJ0eUEiOiAidmFsdWVBIiwKCQkicHJvcGVydHlCIjogInZhbHVlQiIKCX0=\"}";
@Before
@ -41,8 +44,10 @@ public class DaprHttpTest {
DaprHttp daprHttp = new DaprHttp("http://localhost",3500,okHttpClient);
Mono<String> mono = daprHttp.invokeAPI("POST","v1.0/state",null);
assertEquals(EXPECTED_RESULT,mono.block());
Mono<DaprHttp.Response> mono = daprHttp.invokeAPI("POST","v1.0/state",null);
DaprHttp.Response response = mono.block();
String body = serializer.deserialize(response.getBody(), String.class);
assertEquals(EXPECTED_RESULT,body);
}
@ -55,8 +60,10 @@ public class DaprHttpTest {
DaprHttp daprHttp = new DaprHttp("http://localhost",3500,okHttpClient);
Mono<String> mono = daprHttp.invokeAPI("DELETE","v1.0/state",null);
assertEquals(EXPECTED_RESULT,mono.block());
Mono<DaprHttp.Response> mono = daprHttp.invokeAPI("DELETE","v1.0/state",null);
DaprHttp.Response response = mono.block();
String body = serializer.deserialize(response.getBody(), String.class);
assertEquals(EXPECTED_RESULT,body);
}
@ -69,14 +76,15 @@ public class DaprHttpTest {
DaprHttp daprHttp = new DaprHttp("http://localhost",3500,okHttpClient);
Mono<String> mono = daprHttp.invokeAPI("GET","v1.0/get",null);
assertEquals(EXPECTED_RESULT,mono.block());
Mono<DaprHttp.Response> mono = daprHttp.invokeAPI("GET","v1.0/get",null);
DaprHttp.Response response = mono.block();
String body = serializer.deserialize(response.getBody(), String.class);
assertEquals(EXPECTED_RESULT,body);
}
@Test
public void invokeMethodWithHeaders() {
public void invokeMethodWithHeaders() throws IOException {
Map<String, String> headers = new HashMap<>();
headers.put("header","value");
@ -87,14 +95,15 @@ public class DaprHttpTest {
.respond(EXPECTED_RESULT);
DaprHttp daprHttp = new DaprHttp("http://localhost",3500,okHttpClient);
Mono<String> mono = daprHttp.invokeAPI("GET","v1.0/get",headers);
assertEquals(EXPECTED_RESULT,mono.block());
Mono<DaprHttp.Response> mono = daprHttp.invokeAPI("GET","v1.0/get",headers);
DaprHttp.Response response = mono.block();
String body = serializer.deserialize(response.getBody(), String.class);
assertEquals(EXPECTED_RESULT,body);
}
@Test(expected = RuntimeException.class)
public void invokeMethodRuntimeException(){
public void invokeMethodRuntimeException() throws IOException {
Map<String, String> headers = new HashMap<>();
headers.put("header","value");
@ -107,9 +116,10 @@ public class DaprHttpTest {
DaprHttp daprHttp = new DaprHttp("http://localhost",3500,okHttpClient);
Mono<String> mono = daprHttp.invokeAPI("GET","v1.0/get",headers);
assertEquals(EXPECTED_RESULT,mono.block());
Mono<DaprHttp.Response> mono = daprHttp.invokeAPI("GET","v1.0/get",headers);
DaprHttp.Response response = mono.block();
String body = serializer.deserialize(response.getBody(), String.class);
assertEquals(EXPECTED_RESULT,body);
}
}

View File

@ -204,7 +204,8 @@ public class DaprRuntimeTest {
this.daprRuntime.handleInvocation(
METHOD_NAME,
message.data,
message.metadata));
message.metadata)
.map(r -> new DaprHttpStub.ResponseStub(r, null, 200)));
Mono<byte[]> response = client.invokeService(Verb.POST, APP_ID, METHOD_NAME, message.data, message.metadata);
Assert.assertEquals(

View File

@ -1,5 +1,6 @@
package io.dapr.actors.runtime;
package io.dapr.utils;
import io.dapr.utils.DurationUtils;
import org.junit.Assert;
import org.junit.Test;

View File

@ -174,13 +174,13 @@ public class ObjectSerializerTest {
}
@Test
public void serializeObjectTest() {
public void serializeStringObjectTest() {
MyObjectTestToSerialize obj = new MyObjectTestToSerialize();
obj.setStringValue("A String");
obj.setIntValue(2147483647);
obj.setBoolValue(true);
obj.setCharValue('a');
obj.setByteValue((byte)65);
obj.setByteValue((byte) 65);
obj.setShortValue((short) 32767);
obj.setLongValue(9223372036854775807L);
obj.setFloatValue(1.0f);
@ -197,13 +197,42 @@ public class ObjectSerializerTest {
}
}
@Test
public void serializeObjectTest() {
MyObjectTestToSerialize obj = new MyObjectTestToSerialize();
obj.setStringValue("A String");
obj.setIntValue(2147483647);
obj.setBoolValue(true);
obj.setCharValue('a');
obj.setByteValue((byte) 65);
obj.setShortValue((short) 32767);
obj.setLongValue(9223372036854775807L);
obj.setFloatValue(1.0f);
obj.setDoubleValue(1000.0);
//String expectedResult = "{\"stringValue\":\"A String\",\"intValue\":2147483647,\"boolValue\":true,\"charValue\":\"a\",\"byteValue\":65,\"shortValue\":32767,\"longValue\":9223372036854775807,\"floatValue\":1.0,\"doubleValue\":1000.0}";
ObjectSerializer serializer = new ObjectSerializer();
byte[] serializedValue;
try {
serializedValue = serializer.serialize(obj);
assertNotNull(serializedValue);
MyObjectTestToSerialize deserializedValue = serializer.deserialize(serializedValue, MyObjectTestToSerialize.class);
assertEquals(obj, deserializedValue);
} catch (IOException exception) {
fail(exception.getMessage());
}
}
@Test
public void serializeNullTest() {
ObjectSerializer serializer = new ObjectSerializer();
String serializedValue;
byte[] byteSerializedValue;
try {
serializedValue = serializer.serializeString(null);
assertNull("The expected result is null", serializedValue);
assertNull(serializedValue);
byteSerializedValue = serializer.serialize(null);
assertNull(byteSerializedValue);
} catch (IOException exception) {
fail(exception.getMessage());
}
@ -214,9 +243,14 @@ public class ObjectSerializerTest {
String valueToSerialize = "A String";
ObjectSerializer serializer = new ObjectSerializer();
String serializedValue;
byte [] byteValue;
try {
serializedValue = serializer.serializeString(valueToSerialize);
assertEquals(valueToSerialize, serializedValue);
byteValue = serializer.serialize(valueToSerialize);
assertNotNull(byteValue);
String deserializedValue = serializer.deserialize(byteValue, String.class);
assertEquals(valueToSerialize, deserializedValue);
} catch (IOException exception) {
fail(exception.getMessage());
}
@ -228,9 +262,109 @@ public class ObjectSerializerTest {
String expectedResult = valueToSerialize.toString();
ObjectSerializer serializer = new ObjectSerializer();
String serializedValue;
byte [] byteValue;
try {
serializedValue = serializer.serializeString(valueToSerialize.intValue());
assertEquals(expectedResult, serializedValue);
byteValue = serializer.serialize(valueToSerialize);
assertNotNull(byteValue);
Integer deserializedValue = serializer.deserialize(byteValue, Integer.class);
assertEquals(valueToSerialize, deserializedValue);
} catch (IOException exception) {
fail(exception.getMessage());
}
}
@Test
public void serializeShortTest() {
Short valueToSerialize = 1;
String expectedResult = valueToSerialize.toString();
ObjectSerializer serializer = new ObjectSerializer();
String serializedValue;
byte [] byteValue;
try {
serializedValue = serializer.serializeString(valueToSerialize.shortValue());
assertEquals(expectedResult, serializedValue);
byteValue = serializer.serialize(valueToSerialize);
assertNotNull(byteValue);
Short deserializedValue = serializer.deserialize(byteValue, Short.class);
assertEquals(valueToSerialize, deserializedValue);
} catch (IOException exception) {
fail(exception.getMessage());
}
}
@Test
public void serializeLongTest() {
Long valueToSerialize = 1L;
String expectedResult = valueToSerialize.toString();
ObjectSerializer serializer = new ObjectSerializer();
String serializedValue;
byte [] byteValue;
try {
serializedValue = serializer.serializeString(valueToSerialize.longValue());
assertEquals(expectedResult, serializedValue);
byteValue = serializer.serialize(valueToSerialize);
assertNotNull(byteValue);
Long deserializedValue = serializer.deserialize(byteValue, Long.class);
assertEquals(valueToSerialize, deserializedValue);
} catch (IOException exception) {
fail(exception.getMessage());
}
}
@Test
public void serializeFloatTest() {
Float valueToSerialize = 1.0f;
String expectedResult = valueToSerialize.toString();
ObjectSerializer serializer = new ObjectSerializer();
String serializedValue;
byte [] byteValue;
try {
serializedValue = serializer.serializeString(valueToSerialize.floatValue());
assertEquals(expectedResult, serializedValue);
byteValue = serializer.serialize(valueToSerialize);
assertNotNull(byteValue);
Float deserializedValue = serializer.deserialize(byteValue, Float.class);
assertEquals(valueToSerialize, deserializedValue);
} catch (IOException exception) {
fail(exception.getMessage());
}
}
@Test
public void serializeDoubleTest() {
Double valueToSerialize = 1.0;
String expectedResult = valueToSerialize.toString();
ObjectSerializer serializer = new ObjectSerializer();
String serializedValue;
byte [] byteValue;
try {
serializedValue = serializer.serializeString(valueToSerialize.doubleValue());
assertEquals(expectedResult, serializedValue);
byteValue = serializer.serialize(valueToSerialize);
assertNotNull(byteValue);
Double deserializedValue = serializer.deserialize(byteValue, Double.class);
assertEquals(valueToSerialize, deserializedValue);
} catch (IOException exception) {
fail(exception.getMessage());
}
}
@Test
public void serializeBooleanTest() {
Boolean valueToSerialize = true;
String expectedResult = valueToSerialize.toString();
ObjectSerializer serializer = new ObjectSerializer();
String serializedValue;
byte [] byteValue;
try {
serializedValue = serializer.serializeString(valueToSerialize.booleanValue());
assertEquals(expectedResult, serializedValue);
byteValue = serializer.serialize(valueToSerialize);
assertNotNull(byteValue);
Boolean deserializedValue = serializer.deserialize(byteValue, Boolean.class);
assertEquals(valueToSerialize, deserializedValue);
} catch (IOException exception) {
fail(exception.getMessage());
}
@ -244,7 +378,7 @@ public class ObjectSerializerTest {
expectedResult.setIntValue(2147483647);
expectedResult.setBoolValue(true);
expectedResult.setCharValue('a');
expectedResult.setByteValue((byte)65);
expectedResult.setByteValue((byte) 65);
expectedResult.setShortValue((short) 32767);
expectedResult.setLongValue(9223372036854775807L);
expectedResult.setFloatValue(1.0f);
@ -259,33 +393,47 @@ public class ObjectSerializerTest {
}
}
@Test
public void deserializeBtyesTest() {
ObjectSerializer serializer = new ObjectSerializer();
try {
byte[] resultStr = serializer.deserialize("String", byte[].class);
assertNotNull(resultStr);
byte[] result = serializer.deserialize("String".getBytes(), byte[].class);
assertNotNull(result);
} catch (IOException exception) {
fail(exception.getMessage());
}
}
@Test
public void deserializeNullObjectOrPrimitiveTest() {
ObjectSerializer serializer = new ObjectSerializer();
try {
MyObjectTestToSerialize expectedObj = null;
MyObjectTestToSerialize objResult = serializer.deserialize(null, MyObjectTestToSerialize.class);
assertEquals(expectedObj, objResult);
boolean expectedBoolResutl = false;
boolean boolResult = serializer.deserialize(null, boolean.class);
assertEquals(expectedBoolResutl, boolResult);
byte expectedByteResult = Byte.valueOf((byte) 0);
byte byteResult = serializer.deserialize(null, byte.class);
assertEquals(expectedByteResult, byteResult);
short expectedShortResult = (short) 0;
short shortResult = serializer.deserialize(null, short.class);
assertEquals(expectedShortResult, shortResult);
int expectedIntResult = 0;
int intResult = serializer.deserialize(null, int.class);
assertEquals(expectedIntResult, intResult);
long expectedLongResult = 0L;
long longResult = serializer.deserialize(null, long.class);
assertEquals(expectedLongResult, longResult);
float expectedFloatResult = 0f;
float floatResult = serializer.deserialize(null, float.class);
assertEquals(expectedFloatResult, floatResult);
double expectedDoubleResult = (double) 0;
double doubleResult = serializer.deserialize(null, double.class);
assertEquals(expectedDoubleResult, doubleResult);
MyObjectTestToSerialize objResult = serializer.deserialize(null, MyObjectTestToSerialize.class);
assertEquals(expectedObj, objResult);
boolean expectedBoolResutl = false;
boolean boolResult = serializer.deserialize(null, boolean.class);
assertEquals(expectedBoolResutl, boolResult);
byte expectedByteResult = Byte.valueOf((byte) 0);
byte byteResult = serializer.deserialize(null, byte.class);
assertEquals(expectedByteResult, byteResult);
short expectedShortResult = (short) 0;
short shortResult = serializer.deserialize(null, short.class);
assertEquals(expectedShortResult, shortResult);
int expectedIntResult = 0;
int intResult = serializer.deserialize(null, int.class);
assertEquals(expectedIntResult, intResult);
long expectedLongResult = 0L;
long longResult = serializer.deserialize(null, long.class);
assertEquals(expectedLongResult, longResult);
float expectedFloatResult = 0f;
float floatResult = serializer.deserialize(null, float.class);
assertEquals(expectedFloatResult, floatResult, 0.0f);
double expectedDoubleResult = (double) 0;
double doubleResult = serializer.deserialize(null, double.class);
assertEquals(expectedDoubleResult, doubleResult, 0.0);
} catch (IOException exception) {
fail(exception.getMessage());
}
@ -298,7 +446,7 @@ public class ObjectSerializerTest {
expectedResult.setIntValue(2147483647);
expectedResult.setBoolValue(true);
expectedResult.setCharValue('a');
expectedResult.setByteValue((byte)65);
expectedResult.setByteValue((byte) 65);
expectedResult.setShortValue((short) 32767);
expectedResult.setLongValue(9223372036854775807L);
expectedResult.setFloatValue(1.0f);
@ -320,7 +468,7 @@ public class ObjectSerializerTest {
expectedResult.setStringValue("A String");
expectedResult.setBoolValue(true);
expectedResult.setCharValue('a');
expectedResult.setByteValue((byte)65);
expectedResult.setByteValue((byte) 65);
expectedResult.setShortValue((short) 32767);
expectedResult.setLongValue(9223372036854775807L);
expectedResult.setFloatValue(1.0f);
@ -342,7 +490,7 @@ public class ObjectSerializerTest {
expectedResult.setStringValue("A String");
expectedResult.setIntValue(2147483647);
expectedResult.setCharValue('a');
expectedResult.setByteValue((byte)65);
expectedResult.setByteValue((byte) 65);
expectedResult.setShortValue((short) 32767);
expectedResult.setLongValue(9223372036854775807L);
expectedResult.setFloatValue(1.0f);
@ -364,7 +512,7 @@ public class ObjectSerializerTest {
expectedResult.setStringValue("A String");
expectedResult.setIntValue(2147483647);
expectedResult.setBoolValue(true);
expectedResult.setByteValue((byte)65);
expectedResult.setByteValue((byte) 65);
expectedResult.setShortValue((short) 32767);
expectedResult.setLongValue(9223372036854775807L);
expectedResult.setFloatValue(1.0f);
@ -409,7 +557,7 @@ public class ObjectSerializerTest {
expectedResult.setIntValue(2147483647);
expectedResult.setBoolValue(true);
expectedResult.setCharValue('a');
expectedResult.setByteValue((byte)65);
expectedResult.setByteValue((byte) 65);
expectedResult.setLongValue(9223372036854775807L);
expectedResult.setFloatValue(1.0f);
expectedResult.setDoubleValue(1000.0);
@ -431,7 +579,7 @@ public class ObjectSerializerTest {
expectedResult.setIntValue(2147483647);
expectedResult.setBoolValue(true);
expectedResult.setCharValue('a');
expectedResult.setByteValue((byte)65);
expectedResult.setByteValue((byte) 65);
expectedResult.setShortValue((short) 32767);
expectedResult.setFloatValue(1.0f);
expectedResult.setDoubleValue(1000.0);
@ -453,7 +601,7 @@ public class ObjectSerializerTest {
expectedResult.setIntValue(2147483647);
expectedResult.setBoolValue(true);
expectedResult.setCharValue('a');
expectedResult.setByteValue((byte)65);
expectedResult.setByteValue((byte) 65);
expectedResult.setShortValue((short) 32767);
expectedResult.setLongValue(9223372036854775807L);
expectedResult.setDoubleValue(1000.0);
@ -475,7 +623,7 @@ public class ObjectSerializerTest {
expectedResult.setIntValue(2147483647);
expectedResult.setBoolValue(true);
expectedResult.setCharValue('a');
expectedResult.setByteValue((byte)65);
expectedResult.setByteValue((byte) 65);
expectedResult.setShortValue((short) 32767);
expectedResult.setLongValue(9223372036854775807L);
expectedResult.setFloatValue(1.0f);

View File

@ -0,0 +1 @@
mock-maker-inline