mirror of https://github.com/dapr/java-sdk.git
Use TypeRef for deserialization and client APIs. (#301)
* Use TypeRef for deserialization and client APIs. * Making TypeRef class constructor private to force use of .get()
This commit is contained in:
parent
f020b33656
commit
bd4b24cdb9
|
@ -9,6 +9,7 @@ import io.dapr.actors.ActorId;
|
|||
import io.dapr.actors.runtime.AbstractActor;
|
||||
import io.dapr.actors.runtime.ActorRuntimeContext;
|
||||
import io.dapr.actors.runtime.Remindable;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.text.DateFormat;
|
||||
|
@ -121,8 +122,8 @@ public class DemoActorImpl extends AbstractActor implements DemoActor, Remindabl
|
|||
* @return Class for reminder's state.
|
||||
*/
|
||||
@Override
|
||||
public Class<Integer> getStateType() {
|
||||
return Integer.class;
|
||||
public TypeRef<Integer> getStateType() {
|
||||
return TypeRef.INT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package io.dapr.actors.client;
|
||||
|
||||
import io.dapr.actors.ActorId;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
|
@ -27,6 +28,16 @@ public interface ActorProxy {
|
|||
*/
|
||||
String getActorType();
|
||||
|
||||
/**
|
||||
* Invokes an Actor method on Dapr.
|
||||
*
|
||||
* @param methodName Method name to invoke.
|
||||
* @param type The type of the return class.
|
||||
* @param <T> The type to be returned.
|
||||
* @return Asynchronous result with the Actor's response.
|
||||
*/
|
||||
<T> Mono<T> invokeActorMethod(String methodName, TypeRef<T> type);
|
||||
|
||||
/**
|
||||
* Invokes an Actor method on Dapr.
|
||||
*
|
||||
|
@ -37,6 +48,17 @@ public interface ActorProxy {
|
|||
*/
|
||||
<T> Mono<T> invokeActorMethod(String methodName, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* Invokes an Actor method on Dapr.
|
||||
*
|
||||
* @param methodName Method name to invoke.
|
||||
* @param data Object with the data.
|
||||
* @param type The type of the return class.
|
||||
* @param <T> The type to be returned.
|
||||
* @return Asynchronous result with the Actor's response.
|
||||
*/
|
||||
<T> Mono<T> invokeActorMethod(String methodName, Object data, TypeRef<T> type);
|
||||
|
||||
/**
|
||||
* Invokes an Actor method on Dapr.
|
||||
*
|
||||
|
|
|
@ -8,6 +8,7 @@ package io.dapr.actors.client;
|
|||
import io.dapr.actors.ActorId;
|
||||
import io.dapr.actors.ActorMethod;
|
||||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -72,10 +73,28 @@ class ActorProxyImpl implements ActorProxy, InvocationHandler {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeActorMethod(String methodName, Object data, Class<T> clazz) {
|
||||
public <T> Mono<T> invokeActorMethod(String methodName, Object data, TypeRef<T> type) {
|
||||
return this.daprClient.invokeActorMethod(actorType, actorId.toString(), methodName, this.serialize(data))
|
||||
.filter(s -> s.length > 0)
|
||||
.map(s -> deserialize(s, clazz));
|
||||
.map(s -> deserialize(s, type));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeActorMethod(String methodName, Object data, Class<T> clazz) {
|
||||
return this.invokeActorMethod(methodName, data, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeActorMethod(String methodName, TypeRef<T> type) {
|
||||
return this.daprClient.invokeActorMethod(actorType, actorId.toString(), methodName, null)
|
||||
.filter(s -> s.length > 0)
|
||||
.map(s -> deserialize(s, type));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,9 +102,7 @@ class ActorProxyImpl implements ActorProxy, InvocationHandler {
|
|||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeActorMethod(String methodName, Class<T> clazz) {
|
||||
return this.daprClient.invokeActorMethod(actorType, actorId.toString(), methodName, null)
|
||||
.filter(s -> s.length > 0)
|
||||
.map(s -> deserialize(s, clazz));
|
||||
return this.invokeActorMethod(methodName, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,14 +164,14 @@ class ActorProxyImpl implements ActorProxy, InvocationHandler {
|
|||
* Extracts the response object from the Actor's method result.
|
||||
*
|
||||
* @param response response returned by API.
|
||||
* @param clazz Expected response class.
|
||||
* @param type Expected response type.
|
||||
* @param <T> Expected response type.
|
||||
* @return Response object or null.
|
||||
* @throws RuntimeException In case it cannot generate Object.
|
||||
*/
|
||||
private <T> T deserialize(final byte[] response, Class<T> clazz) {
|
||||
private <T> T deserialize(final byte[] response, TypeRef<T> type) {
|
||||
try {
|
||||
return this.serializer.deserialize(response, clazz);
|
||||
return this.serializer.deserialize(response, type);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package io.dapr.actors.runtime;
|
||||
|
||||
import io.dapr.actors.ActorId;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -253,7 +254,7 @@ class ActorManager<T extends AbstractActor> {
|
|||
if (method.getParameterCount() == 1) {
|
||||
// Actor methods must have a one or no parameter, which is guaranteed at this point.
|
||||
Class<?> inputClass = method.getParameterTypes()[0];
|
||||
input = this.runtimeContext.getObjectSerializer().deserialize(request, inputClass);
|
||||
input = this.runtimeContext.getObjectSerializer().deserialize(request, TypeRef.get(inputClass));
|
||||
}
|
||||
|
||||
if (method.getReturnType().equals(Mono.class)) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package io.dapr.actors.runtime;
|
||||
|
||||
import io.dapr.actors.ActorId;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -101,6 +102,18 @@ public class ActorStateManager {
|
|||
* @return Asynchronous response with fetched object.
|
||||
*/
|
||||
public <T> Mono<T> get(String stateName, Class<T> clazz) {
|
||||
return this.get(stateName, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the most recent value for the given state, including cached value.
|
||||
*
|
||||
* @param stateName Name of the state.
|
||||
* @param type Class type for the value being fetched.
|
||||
* @param <T> Type being fetched.
|
||||
* @return Asynchronous response with fetched object.
|
||||
*/
|
||||
public <T> Mono<T> get(String stateName, TypeRef<T> type) {
|
||||
return Mono.fromSupplier(() -> {
|
||||
if (stateName == null) {
|
||||
throw new IllegalArgumentException("State's name cannot be null.");
|
||||
|
@ -118,7 +131,7 @@ public class ActorStateManager {
|
|||
|
||||
return (T) null;
|
||||
}).switchIfEmpty(
|
||||
this.stateProvider.load(this.actorTypeName, this.actorId, stateName, clazz)
|
||||
this.stateProvider.load(this.actorTypeName, this.actorId, stateName, type)
|
||||
.switchIfEmpty(Mono.error(new NoSuchElementException("State not found: " + stateName)))
|
||||
.map(v -> {
|
||||
this.stateChangeTracker.put(stateName, new StateChangeMetadata(ActorStateChangeKind.NONE, v));
|
||||
|
|
|
@ -11,6 +11,7 @@ import io.dapr.actors.ActorId;
|
|||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
import io.dapr.utils.Properties;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
@ -59,12 +60,12 @@ class DaprStateAsyncProvider {
|
|||
this.isStateSerializerDefault = stateSerializer.getClass() == DefaultObjectSerializer.class;
|
||||
}
|
||||
|
||||
<T> Mono<T> load(String actorType, ActorId actorId, String stateName, Class<T> clazz) {
|
||||
<T> Mono<T> load(String actorType, ActorId actorId, String stateName, TypeRef<T> type) {
|
||||
Mono<byte[]> result = this.daprClient.getActorState(actorType, actorId.toString(), stateName);
|
||||
|
||||
return result.flatMap(s -> {
|
||||
try {
|
||||
T response = this.stateSerializer.deserialize(s, clazz);
|
||||
T response = this.stateSerializer.deserialize(s, type);
|
||||
if (response == null) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
package io.dapr.actors.runtime;
|
||||
|
||||
import io.dapr.utils.TypeRef;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.Duration;
|
||||
|
@ -15,11 +16,11 @@ import java.time.Duration;
|
|||
public interface Remindable<T> {
|
||||
|
||||
/**
|
||||
* Gets the class for state object.
|
||||
* Gets the type for state object.
|
||||
*
|
||||
* @return Class for state object.
|
||||
*/
|
||||
Class<T> getStateType();
|
||||
TypeRef<T> getStateType();
|
||||
|
||||
/**
|
||||
* The reminder call back invoked when an actor reminder is triggered.
|
||||
|
|
|
@ -11,6 +11,8 @@ import io.dapr.serializer.DefaultObjectSerializer;
|
|||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import io.dapr.utils.TypeRef;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
@ -96,8 +98,8 @@ public class ActorManagerTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Class<String> getStateType() {
|
||||
return String.class;
|
||||
public TypeRef<String> getStateType() {
|
||||
return TypeRef.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -124,8 +126,8 @@ public class ActorManagerTest {
|
|||
this.manager.activateActor(actorId).block();
|
||||
byte[] response = this.manager.invokeMethod(actorId, "say", message).block();
|
||||
Assert.assertEquals(executeSayMethod(
|
||||
this.context.getObjectSerializer().deserialize(message, String.class)),
|
||||
this.context.getObjectSerializer().deserialize(response, String.class));
|
||||
this.context.getObjectSerializer().deserialize(message, TypeRef.STRING)),
|
||||
this.context.getObjectSerializer().deserialize(response, TypeRef.STRING));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -192,8 +194,8 @@ public class ActorManagerTest {
|
|||
this.manager.activateActor(actorId).block();
|
||||
byte[] response = this.manager.invokeMethod(actorId, "say", message).block();
|
||||
Assert.assertEquals(executeSayMethod(
|
||||
this.context.getObjectSerializer().deserialize(message, String.class)),
|
||||
this.context.getObjectSerializer().deserialize(response, String.class));
|
||||
this.context.getObjectSerializer().deserialize(message, TypeRef.STRING)),
|
||||
this.context.getObjectSerializer().deserialize(response, TypeRef.STRING));
|
||||
|
||||
this.manager.deactivateActor(actorId).block();
|
||||
this.manager.invokeMethod(actorId, "say", message).block();
|
||||
|
|
|
@ -11,6 +11,7 @@ import io.dapr.actors.client.ActorProxy;
|
|||
import io.dapr.actors.client.ActorProxyForTestsImpl;
|
||||
import io.dapr.actors.client.DaprClientStub;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
@ -247,9 +248,9 @@ public class ActorStatefulTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Class<String> getStateType() {
|
||||
public TypeRef<String> getStateType() {
|
||||
// Remindable type.
|
||||
return String.class;
|
||||
return TypeRef.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package io.dapr.actors.runtime;
|
||||
|
||||
import io.dapr.actors.ActorType;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
@ -64,7 +65,7 @@ public class ActorTypeInformationTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Class getStateType() {
|
||||
public TypeRef getStateType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ package io.dapr.actors.runtime;
|
|||
|
||||
import io.dapr.actors.ActorId;
|
||||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -28,7 +29,7 @@ public class DaprInMemoryStateProvider extends DaprStateAsyncProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
<T> Mono<T> load(String actorType, ActorId actorId, String stateName, Class<T> clazz) {
|
||||
<T> Mono<T> load(String actorType, ActorId actorId, String stateName, TypeRef<T> type) {
|
||||
return Mono.fromSupplier(() -> {
|
||||
try {
|
||||
String stateId = this.buildId(actorType, actorId, stateName);
|
||||
|
@ -36,7 +37,7 @@ public class DaprInMemoryStateProvider extends DaprStateAsyncProvider {
|
|||
throw new IllegalStateException("State not found.");
|
||||
}
|
||||
|
||||
return this.serializer.deserialize(this.stateStore.get(stateId), clazz);
|
||||
return this.serializer.deserialize(this.stateStore.get(stateId), type);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
import io.dapr.actors.ActorId;
|
||||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
@ -170,23 +171,24 @@ public class DaprStateAsyncProviderTest {
|
|||
DaprStateAsyncProvider provider = new DaprStateAsyncProvider(daprClient, SERIALIZER);
|
||||
|
||||
Assert.assertEquals("Jon Doe",
|
||||
provider.load("MyActor", new ActorId("123"), "name", String.class).block());
|
||||
provider.load("MyActor", new ActorId("123"), "name", TypeRef.STRING).block());
|
||||
Assert.assertEquals(98021,
|
||||
(int)provider.load("MyActor", new ActorId("123"), "zipcode", int.class).block());
|
||||
(int)provider.load("MyActor", new ActorId("123"), "zipcode", TypeRef.INT).block());
|
||||
Assert.assertEquals(98,
|
||||
(int) provider.load("MyActor", new ActorId("123"), "goals", int.class).block());
|
||||
(int) provider.load("MyActor", new ActorId("123"), "goals", TypeRef.INT).block());
|
||||
Assert.assertEquals(98,
|
||||
(int) provider.load("MyActor", new ActorId("123"), "goals", int.class).block());
|
||||
(int) provider.load("MyActor", new ActorId("123"), "goals", TypeRef.INT).block());
|
||||
Assert.assertEquals(46.55,
|
||||
(double) provider.load("MyActor", new ActorId("123"), "balance", double.class).block(),
|
||||
(double) provider.load("MyActor", new ActorId("123"), "balance", TypeRef.DOUBLE).block(),
|
||||
EPSILON);
|
||||
Assert.assertEquals(true,
|
||||
(boolean) provider.load("MyActor", new ActorId("123"), "active", boolean.class).block());
|
||||
(boolean) provider.load("MyActor", new ActorId("123"), "active", TypeRef.BOOLEAN).block());
|
||||
Assert.assertEquals(new Customer().setId(1000).setName("Roxane"),
|
||||
provider.load("MyActor", new ActorId("123"), "customer", Customer.class).block());
|
||||
provider.load("MyActor", new ActorId("123"), "customer", TypeRef.get(Customer.class)).block());
|
||||
Assert.assertNotEquals(new Customer().setId(1000).setName("Roxane"),
|
||||
provider.load("MyActor", new ActorId("123"), "anotherCustomer", Customer.class).block());
|
||||
Assert.assertNull(provider.load("MyActor", new ActorId("123"), "nullCustomer", Customer.class).block());
|
||||
provider.load("MyActor", new ActorId("123"), "anotherCustomer", TypeRef.get(Customer.class)).block());
|
||||
Assert.assertNull(
|
||||
provider.load("MyActor", new ActorId("123"), "nullCustomer", TypeRef.get(Customer.class)).block());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package io.dapr.actors.runtime;
|
||||
|
||||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.utils.TypeRef;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
|
@ -32,7 +33,7 @@ public class JavaSerializer implements DaprObjectSerializer {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> T deserialize(byte[] data, Class<T> clazz) throws IOException {
|
||||
public <T> T deserialize(byte[] data, TypeRef<T> type) throws IOException {
|
||||
try (ByteArrayInputStream bis = new ByteArrayInputStream(data)) {
|
||||
try (ObjectInputStream ois = new ObjectInputStream(bis)) {
|
||||
try {
|
||||
|
|
|
@ -11,6 +11,7 @@ import io.dapr.actors.runtime.AbstractActor;
|
|||
import io.dapr.actors.runtime.ActorRuntimeContext;
|
||||
import io.dapr.actors.runtime.Remindable;
|
||||
import io.dapr.it.actors.MethodEntryTracker;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.text.DateFormat;
|
||||
|
@ -146,8 +147,8 @@ public class MyActorImpl extends AbstractActor implements MyActor, Remindable<St
|
|||
}
|
||||
|
||||
@Override
|
||||
public Class<String> getStateType() {
|
||||
return String.class;
|
||||
public TypeRef<String> getStateType() {
|
||||
return TypeRef.STRING;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,12 +5,10 @@
|
|||
|
||||
package io.dapr.client;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.dapr.client.domain.State;
|
||||
import io.dapr.client.domain.StateOptions;
|
||||
import io.dapr.client.domain.Verb;
|
||||
import io.dapr.v1.DaprProtos;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -45,14 +43,29 @@ public interface DaprClient {
|
|||
/**
|
||||
* Invoke a service with all possible parameters, using serialization.
|
||||
*
|
||||
* @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value.
|
||||
* @param appId The Application ID where the service is.
|
||||
* @param method The actual Method to be call in the application.
|
||||
* @param request The request to be sent to invoke the service, use byte[] to skip serialization.
|
||||
* @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value.
|
||||
* @param appId The Application ID where the service is.
|
||||
* @param method The actual Method to be call in the application.
|
||||
* @param request The request to be sent to invoke the service, use byte[] to skip serialization.
|
||||
* @param metadata Metadata (in GRPC) or headers (in HTTP) to be send in request.
|
||||
* @param clazz the Type needed as return for the call.
|
||||
* @param <T> the Type of the return, use byte[] to skip serialization.
|
||||
* @return A Mono Plan of type clazz.
|
||||
* @param type The Type needed as return for the call.
|
||||
* @param <T> The Type of the return, use byte[] to skip serialization.
|
||||
* @return A Mono Plan of type type .
|
||||
*/
|
||||
<T> Mono<T> invokeService(
|
||||
Verb verb, String appId, String method, Object request, Map<String, String> metadata, TypeRef<T> type);
|
||||
|
||||
/**
|
||||
* Invoke a service with all possible parameters, using serialization.
|
||||
*
|
||||
* @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value.
|
||||
* @param appId The Application ID where the service is.
|
||||
* @param method The actual Method to be call in the application.
|
||||
* @param request The request to be sent to invoke the service, use byte[] to skip serialization.
|
||||
* @param metadata Metadata (in GRPC) or headers (in HTTP) to be send in request.
|
||||
* @param clazz The type needed as return for the call.
|
||||
* @param <T> The type of the return, use byte[] to skip serialization.
|
||||
* @return A Mono Plan of type type .
|
||||
*/
|
||||
<T> Mono<T> invokeService(
|
||||
Verb verb, String appId, String method, Object request, Map<String, String> metadata, Class<T> clazz);
|
||||
|
@ -64,22 +77,48 @@ public interface DaprClient {
|
|||
* @param appId The Application ID where the service is.
|
||||
* @param method The actual Method to be call in the application.
|
||||
* @param request The request to be sent to invoke the service, use byte[] to skip serialization.
|
||||
* @param clazz the Type needed as return for the call.
|
||||
* @param <T> the Type of the return, use byte[] to skip serialization.
|
||||
* @return A Mono Plan of type clazz.
|
||||
* @param type The type needed as return for the call.
|
||||
* @param <T> The type of the return, use byte[] to skip serialization.
|
||||
* @return A Mono Plan of type type .
|
||||
*/
|
||||
<T> Mono<T> invokeService(Verb verb, String appId, String method, Object request, TypeRef<T> type);
|
||||
|
||||
/**
|
||||
* Invoke a service without metadata, using serialization.
|
||||
*
|
||||
* @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value.
|
||||
* @param appId The Application ID where the service is.
|
||||
* @param method The actual Method to be call in the application.
|
||||
* @param request The request to be sent to invoke the service, use byte[] to skip serialization.
|
||||
* @param clazz The type needed as return for the call.
|
||||
* @param <T> The type of the return, use byte[] to skip serialization.
|
||||
* @return A Mono Plan of type type .
|
||||
*/
|
||||
<T> Mono<T> invokeService(Verb verb, String appId, String method, Object request, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* Invoke a service without input, using serialization for response.
|
||||
*
|
||||
* @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value.
|
||||
* @param appId The Application ID where the service is.
|
||||
* @param method The actual Method to be call in the application.
|
||||
* @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value.
|
||||
* @param appId The Application ID where the service is.
|
||||
* @param method The actual Method to be call in the application.
|
||||
* @param metadata Metadata (in GRPC) or headers (in HTTP) to be send in request.
|
||||
* @param clazz the Type needed as return for the call.
|
||||
* @param <T> the Type of the return, use byte[] to skip serialization.
|
||||
* @return A Mono plan of type clazz.
|
||||
* @param type The type needed as return for the call.
|
||||
* @param <T> The type of the return, use byte[] to skip serialization.
|
||||
* @return A Mono plan of type type .
|
||||
*/
|
||||
<T> Mono<T> invokeService(Verb verb, String appId, String method, Map<String, String> metadata, TypeRef<T> type);
|
||||
|
||||
/**
|
||||
* Invoke a service without input, using serialization for response.
|
||||
*
|
||||
* @param verb The Verb to be used for HTTP will be the HTTP Verb, for GRPC is just a metadata value.
|
||||
* @param appId The Application ID where the service is.
|
||||
* @param method The actual Method to be call in the application.
|
||||
* @param metadata Metadata (in GRPC) or headers (in HTTP) to be send in request.
|
||||
* @param clazz The type needed as return for the call.
|
||||
* @param <T> The type of the return, use byte[] to skip serialization.
|
||||
* @return A Mono plan of type type .
|
||||
*/
|
||||
<T> Mono<T> invokeService(Verb verb, String appId, String method, Map<String, String> metadata, Class<T> clazz);
|
||||
|
||||
|
@ -150,6 +189,18 @@ public interface DaprClient {
|
|||
*/
|
||||
Mono<byte[]> invokeBinding(String name, String operation, byte[] data, Map<String, String> metadata);
|
||||
|
||||
/**
|
||||
* Invokes a Binding operation.
|
||||
*
|
||||
* @param name The name of the biding to call.
|
||||
* @param operation The operation to be performed by the binding request processor.
|
||||
* @param data The data to be processed, use byte[] to skip serialization.
|
||||
* @param type The type being returned.
|
||||
* @param <T> The type of the return
|
||||
* @return a Mono plan of type T.
|
||||
*/
|
||||
<T> Mono<T> invokeBinding(String name, String operation, Object data, TypeRef<T> type);
|
||||
|
||||
/**
|
||||
* Invokes a Binding operation.
|
||||
*
|
||||
|
@ -162,6 +213,19 @@ public interface DaprClient {
|
|||
*/
|
||||
<T> Mono<T> invokeBinding(String name, String operation, Object data, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* Invokes a Binding operation.
|
||||
*
|
||||
* @param name The name of the biding to call.
|
||||
* @param operation The operation to be performed by the binding request processor.
|
||||
* @param data The data to be processed, use byte[] to skip serialization.
|
||||
* @param metadata The metadata map.
|
||||
* @param type The type being returned.
|
||||
* @param <T> The type of the return
|
||||
* @return a Mono plan of type T.
|
||||
*/
|
||||
<T> Mono<T> invokeBinding(String name, String operation, Object data, Map<String, String> metadata, TypeRef<T> type);
|
||||
|
||||
/**
|
||||
* Invokes a Binding operation.
|
||||
*
|
||||
|
@ -180,8 +244,19 @@ public interface DaprClient {
|
|||
*
|
||||
* @param stateStoreName The name of the state store.
|
||||
* @param state State to be re-retrieved.
|
||||
* @param clazz The Type of State needed as return.
|
||||
* @param <T> The Type of the return.
|
||||
* @param type The type of State needed as return.
|
||||
* @param <T> The type of the return.
|
||||
* @return A Mono Plan for the requested State.
|
||||
*/
|
||||
<T> Mono<State<T>> getState(String stateStoreName, State<T> state, TypeRef<T> type);
|
||||
|
||||
/**
|
||||
* Retrieve a State based on their key.
|
||||
*
|
||||
* @param stateStoreName The name of the state store.
|
||||
* @param state State to be re-retrieved.
|
||||
* @param clazz The type of State needed as return.
|
||||
* @param <T> The type of the return.
|
||||
* @return A Mono Plan for the requested State.
|
||||
*/
|
||||
<T> Mono<State<T>> getState(String stateStoreName, State<T> state, Class<T> clazz);
|
||||
|
@ -191,8 +266,19 @@ public interface DaprClient {
|
|||
*
|
||||
* @param stateStoreName The name of the state store.
|
||||
* @param key The key of the State to be retrieved.
|
||||
* @param clazz The Type of State needed as return.
|
||||
* @param <T> The Type of the return.
|
||||
* @param type The type of State needed as return.
|
||||
* @param <T> The type of the return.
|
||||
* @return A Mono Plan for the requested State.
|
||||
*/
|
||||
<T> Mono<State<T>> getState(String stateStoreName, String key, TypeRef<T> type);
|
||||
|
||||
/**
|
||||
* Retrieve a State based on their key.
|
||||
*
|
||||
* @param stateStoreName The name of the state store.
|
||||
* @param key The key of the State to be retrieved.
|
||||
* @param clazz The type of State needed as return.
|
||||
* @param <T> The type of the return.
|
||||
* @return A Mono Plan for the requested State.
|
||||
*/
|
||||
<T> Mono<State<T>> getState(String stateStoreName, String key, Class<T> clazz);
|
||||
|
@ -204,10 +290,23 @@ public interface DaprClient {
|
|||
* @param key The key of the State to be retrieved.
|
||||
* @param etag Optional etag for conditional get
|
||||
* @param options Optional settings for retrieve operation.
|
||||
* @param clazz The Type of State needed as return.
|
||||
* @param type The Type of State needed as return.
|
||||
* @param <T> The Type of the return.
|
||||
* @return A Mono Plan for the requested State.
|
||||
*/
|
||||
<T> Mono<State<T>> getState(String stateStoreName, String key, String etag, StateOptions options, TypeRef<T> type);
|
||||
|
||||
/**
|
||||
* Retrieve a State based on their key.
|
||||
*
|
||||
* @param stateStoreName The name of the state store.
|
||||
* @param key The key of the State to be retrieved.
|
||||
* @param etag Optional etag for conditional get
|
||||
* @param options Optional settings for retrieve operation.
|
||||
* @param clazz The type of State needed as return.
|
||||
* @param <T> The type of the return.
|
||||
* @return A Mono Plan for the requested State.
|
||||
*/
|
||||
<T> Mono<State<T>> getState(String stateStoreName, String key, String etag, StateOptions options, Class<T> clazz);
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,6 +14,7 @@ import io.dapr.client.domain.State;
|
|||
import io.dapr.client.domain.StateOptions;
|
||||
import io.dapr.client.domain.Verb;
|
||||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import io.dapr.v1.CommonProtos;
|
||||
import io.dapr.v1.DaprGrpc;
|
||||
import io.dapr.v1.DaprProtos;
|
||||
|
@ -139,27 +140,58 @@ public class DaprClientGrpc implements DaprClient {
|
|||
String method,
|
||||
Object request,
|
||||
Map<String, String> metadata,
|
||||
Class<T> clazz) {
|
||||
TypeRef<T> type) {
|
||||
try {
|
||||
DaprProtos.InvokeServiceRequest envelope = buildInvokeServiceRequest(verb.toString(), appId, method, request);
|
||||
return Mono.fromCallable(() -> {
|
||||
ListenableFuture<CommonProtos.InvokeResponse> futureResponse =
|
||||
client.invokeService(envelope);
|
||||
|
||||
return objectSerializer.deserialize(futureResponse.get().getData().getValue().toByteArray(), clazz);
|
||||
return objectSerializer.deserialize(futureResponse.get().getData().getValue().toByteArray(), type);
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
return Mono.error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeService(
|
||||
Verb verb,
|
||||
String appId,
|
||||
String method,
|
||||
Object request,
|
||||
Map<String, String> metadata,
|
||||
Class<T> clazz) {
|
||||
return this.invokeService(verb, appId, method, request, metadata, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeService(
|
||||
Verb verb, String appId, String method, Map<String, String> metadata, TypeRef<T> type) {
|
||||
return this.invokeService(verb, appId, method, null, metadata, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeService(
|
||||
Verb verb, String appId, String method, Map<String, String> metadata, Class<T> clazz) {
|
||||
return this.invokeService(verb, appId, method, null, metadata, clazz);
|
||||
return this.invokeService(verb, appId, method, null, metadata, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeService(Verb verb, String appId, String method, Object request, TypeRef<T> type) {
|
||||
return this.invokeService(verb, appId, method, request, null, type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -167,7 +199,7 @@ public class DaprClientGrpc implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeService(Verb verb, String appId, String method, Object request, Class<T> clazz) {
|
||||
return this.invokeService(verb, appId, method, request, null, clazz);
|
||||
return this.invokeService(verb, appId, method, request, null, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,7 +207,7 @@ public class DaprClientGrpc implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public Mono<Void> invokeService(Verb verb, String appId, String method, Object request) {
|
||||
return this.invokeService(verb, appId, method, request, null, byte[].class).then();
|
||||
return this.invokeService(verb, appId, method, request, null, TypeRef.BYTE_ARRAY).then();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,7 +216,7 @@ public class DaprClientGrpc implements DaprClient {
|
|||
@Override
|
||||
public Mono<Void> invokeService(
|
||||
Verb verb, String appId, String method, Object request, Map<String, String> metadata) {
|
||||
return this.invokeService(verb, appId, method, request, metadata, byte[].class).then();
|
||||
return this.invokeService(verb, appId, method, request, metadata, TypeRef.BYTE_ARRAY).then();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -193,7 +225,7 @@ public class DaprClientGrpc implements DaprClient {
|
|||
@Override
|
||||
public Mono<Void> invokeService(
|
||||
Verb verb, String appId, String method, Map<String, String> metadata) {
|
||||
return this.invokeService(verb, appId, method, null, metadata, byte[].class).then();
|
||||
return this.invokeService(verb, appId, method, null, metadata, TypeRef.BYTE_ARRAY).then();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -202,7 +234,7 @@ public class DaprClientGrpc implements DaprClient {
|
|||
@Override
|
||||
public Mono<byte[]> invokeService(
|
||||
Verb verb, String appId, String method, byte[] request, Map<String, String> metadata) {
|
||||
return this.invokeService(verb, appId, method, request, metadata, byte[].class);
|
||||
return this.invokeService(verb, appId, method, request, metadata, TypeRef.BYTE_ARRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,7 +242,7 @@ public class DaprClientGrpc implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public Mono<Void> invokeBinding(String name, String operation, Object data) {
|
||||
return this.invokeBinding(name, operation, data, null, byte[].class).then();
|
||||
return this.invokeBinding(name, operation, data, null, TypeRef.BYTE_ARRAY).then();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -218,7 +250,15 @@ public class DaprClientGrpc implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public Mono<byte[]> invokeBinding(String name, String operation, byte[] data, Map<String, String> metadata) {
|
||||
return this.invokeBinding(name, operation, data, metadata, byte[].class);
|
||||
return this.invokeBinding(name, operation, data, metadata, TypeRef.BYTE_ARRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(String name, String operation, Object data, TypeRef<T> type) {
|
||||
return this.invokeBinding(name, operation, data, null, type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,7 +266,7 @@ public class DaprClientGrpc implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(String name, String operation, Object data, Class<T> clazz) {
|
||||
return this.invokeBinding(name, operation, data, null, clazz);
|
||||
return this.invokeBinding(name, operation, data, null, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -234,7 +274,7 @@ public class DaprClientGrpc implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(
|
||||
String name, String operation, Object data, Map<String, String> metadata, Class<T> clazz) {
|
||||
String name, String operation, Object data, Map<String, String> metadata, TypeRef<T> type) {
|
||||
try {
|
||||
if (name == null || name.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("Binding name cannot be null or empty.");
|
||||
|
@ -256,19 +296,44 @@ public class DaprClientGrpc implements DaprClient {
|
|||
DaprProtos.InvokeBindingRequest envelope = builder.build();
|
||||
return Mono.fromCallable(() -> {
|
||||
ListenableFuture<DaprProtos.InvokeBindingResponse> futureResponse = client.invokeBinding(envelope);
|
||||
return objectSerializer.deserialize(futureResponse.get().getData().toByteArray(), clazz);
|
||||
return objectSerializer.deserialize(futureResponse.get().getData().toByteArray(), type);
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
return Mono.error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(
|
||||
String name, String operation, Object data, Map<String, String> metadata, Class<T> clazz) {
|
||||
return this.invokeBinding(name, operation, data, metadata, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String stateStoreName, State<T> state, TypeRef<T> type) {
|
||||
return this.getState(stateStoreName, state.getKey(), state.getEtag(), state.getOptions(), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String stateStoreName, State<T> state, Class<T> clazz) {
|
||||
return this.getState(stateStoreName, state.getKey(), state.getEtag(), state.getOptions(), clazz);
|
||||
return this.getState(stateStoreName, state.getKey(), state.getEtag(), state.getOptions(), TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String stateStoreName, String key, TypeRef<T> type) {
|
||||
return this.getState(stateStoreName, key, null, null, type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -276,7 +341,7 @@ public class DaprClientGrpc implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String stateStoreName, String key, Class<T> clazz) {
|
||||
return this.getState(stateStoreName, key, null, null, clazz);
|
||||
return this.getState(stateStoreName, key, null, null, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -284,7 +349,7 @@ public class DaprClientGrpc implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(
|
||||
String stateStoreName, String key, String etag, StateOptions options, Class<T> clazz) {
|
||||
String stateStoreName, String key, String etag, StateOptions options, TypeRef<T> type) {
|
||||
try {
|
||||
if ((stateStoreName == null) || (stateStoreName.trim().isEmpty())) {
|
||||
throw new IllegalArgumentException("State store name cannot be null or empty.");
|
||||
|
@ -308,21 +373,30 @@ public class DaprClientGrpc implements DaprClient {
|
|||
} catch (NullPointerException npe) {
|
||||
return null;
|
||||
}
|
||||
return buildStateKeyValue(response, key, options, clazz);
|
||||
return buildStateKeyValue(response, key, options, type);
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
return Mono.error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(
|
||||
String stateStoreName, String key, String etag, StateOptions options, Class<T> clazz) {
|
||||
return this.getState(stateStoreName, key, etag, options, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
private <T> State<T> buildStateKeyValue(
|
||||
DaprProtos.GetStateResponse response,
|
||||
String requestedKey,
|
||||
StateOptions stateOptions,
|
||||
Class<T> clazz) throws IOException {
|
||||
TypeRef<T> type) throws IOException {
|
||||
ByteString payload = response.getData();
|
||||
byte[] data = payload == null ? null : payload.toByteArray();
|
||||
T value = stateSerializer.deserialize(data, clazz);
|
||||
T value = stateSerializer.deserialize(data, type);
|
||||
String etag = response.getEtag();
|
||||
String key = requestedKey;
|
||||
return new State<>(value, key, etag, stateOptions);
|
||||
|
|
|
@ -11,6 +11,7 @@ import io.dapr.client.domain.Verb;
|
|||
import io.dapr.serializer.DaprObjectSerializer;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
import io.dapr.utils.Constants;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -123,7 +124,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeService(
|
||||
Verb verb, String appId, String method, Object request, Map<String, String> metadata, Class<T> clazz) {
|
||||
Verb verb, String appId, String method, Object request, Map<String, String> metadata, TypeRef<T> type) {
|
||||
try {
|
||||
if (verb == null) {
|
||||
throw new IllegalArgumentException("Verb cannot be null.");
|
||||
|
@ -140,7 +141,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
Mono<DaprHttp.Response> response = this.client.invokeApi(httMethod, path, metadata, serializedRequestBody, null);
|
||||
return response.flatMap(r -> {
|
||||
try {
|
||||
T object = objectSerializer.deserialize(r.getBody(), clazz);
|
||||
T object = objectSerializer.deserialize(r.getBody(), type);
|
||||
if (object == null) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
@ -155,13 +156,44 @@ public class DaprClientHttp implements DaprClient {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeService(
|
||||
Verb verb,
|
||||
String appId,
|
||||
String method,
|
||||
Object request,
|
||||
Map<String, String> metadata,
|
||||
Class<T> clazz) {
|
||||
return this.invokeService(verb, appId, method, request, metadata, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeService(
|
||||
Verb verb, String appId, String method, Map<String, String> metadata, TypeRef<T> type) {
|
||||
return this.invokeService(verb, appId, method, null, metadata, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeService(
|
||||
Verb verb, String appId, String method, Map<String, String> metadata, Class<T> clazz) {
|
||||
return this.invokeService(verb, appId, method, null, metadata, clazz);
|
||||
return this.invokeService(verb, appId, method, null, metadata, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeService(Verb verb, String appId, String method, Object request, TypeRef<T> type) {
|
||||
return this.invokeService(verb, appId, method, request, null, type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -169,7 +201,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeService(Verb verb, String appId, String method, Object request, Class<T> clazz) {
|
||||
return this.invokeService(verb, appId, method, request, null, clazz);
|
||||
return this.invokeService(verb, appId, method, request, null, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -177,7 +209,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public Mono<Void> invokeService(Verb verb, String appId, String method, Object request) {
|
||||
return this.invokeService(verb, appId, method, request, null, byte[].class).then();
|
||||
return this.invokeService(verb, appId, method, request, null, TypeRef.BYTE_ARRAY).then();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -186,7 +218,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
@Override
|
||||
public Mono<Void> invokeService(
|
||||
Verb verb, String appId, String method, Object request, Map<String, String> metadata) {
|
||||
return this.invokeService(verb, appId, method, request, metadata, byte[].class).then();
|
||||
return this.invokeService(verb, appId, method, request, metadata, TypeRef.BYTE_ARRAY).then();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -195,7 +227,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
@Override
|
||||
public Mono<Void> invokeService(
|
||||
Verb verb, String appId, String method, Map<String, String> metadata) {
|
||||
return this.invokeService(verb, appId, method, null, metadata, byte[].class).then();
|
||||
return this.invokeService(verb, appId, method, null, metadata, TypeRef.BYTE_ARRAY).then();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -204,7 +236,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
@Override
|
||||
public Mono<byte[]> invokeService(
|
||||
Verb verb, String appId, String method, byte[] request, Map<String, String> metadata) {
|
||||
return this.invokeService(verb, appId, method, request, metadata, byte[].class);
|
||||
return this.invokeService(verb, appId, method, request, metadata, TypeRef.BYTE_ARRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -212,7 +244,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public Mono<Void> invokeBinding(String name, String operation, Object data) {
|
||||
return this.invokeBinding(name, operation, data, null, byte[].class).then();
|
||||
return this.invokeBinding(name, operation, data, null, TypeRef.BYTE_ARRAY).then();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -220,7 +252,15 @@ public class DaprClientHttp implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public Mono<byte[]> invokeBinding(String name, String operation, byte[] data, Map<String, String> metadata) {
|
||||
return this.invokeBinding(name, operation, data, metadata, byte[].class);
|
||||
return this.invokeBinding(name, operation, data, metadata, TypeRef.BYTE_ARRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(String name, String operation, Object data, TypeRef<T> type) {
|
||||
return this.invokeBinding(name, operation, data, null, type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -228,7 +268,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(String name, String operation, Object data, Class<T> clazz) {
|
||||
return this.invokeBinding(name, operation, data, null, clazz);
|
||||
return this.invokeBinding(name, operation, data, null, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -236,7 +276,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(
|
||||
String name, String operation, Object data, Map<String, String> metadata, Class<T> clazz) {
|
||||
String name, String operation, Object data, Map<String, String> metadata, TypeRef<T> type) {
|
||||
try {
|
||||
if (name == null || name.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("Binding name cannot be null or empty.");
|
||||
|
@ -279,7 +319,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
Mono<DaprHttp.Response> response = this.client.invokeApi(httpMethod, url.toString(), null, payload, null);
|
||||
return response.flatMap(r -> {
|
||||
try {
|
||||
T object = objectSerializer.deserialize(r.getBody(), clazz);
|
||||
T object = objectSerializer.deserialize(r.getBody(), type);
|
||||
if (object == null) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
@ -294,12 +334,38 @@ public class DaprClientHttp implements DaprClient {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> invokeBinding(
|
||||
String name, String operation, Object data, Map<String, String> metadata, Class<T> clazz) {
|
||||
return this.invokeBinding(name, operation, data, metadata, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String stateStoreName, State<T> state, TypeRef<T> type) {
|
||||
return this.getState(stateStoreName, state.getKey(), state.getEtag(), state.getOptions(), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String stateStoreName, State<T> state, Class<T> clazz) {
|
||||
return this.getState(stateStoreName, state.getKey(), state.getEtag(), state.getOptions(), clazz);
|
||||
return this.getState(stateStoreName, state.getKey(), state.getEtag(), state.getOptions(), TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String stateStoreName, String key, TypeRef<T> type) {
|
||||
return this.getState(stateStoreName, key, null, null, type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -307,7 +373,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(String stateStoreName, String key, Class<T> clazz) {
|
||||
return this.getState(stateStoreName, key, null, null, clazz);
|
||||
return this.getState(stateStoreName, key, null, null, TypeRef.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -315,7 +381,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
*/
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(
|
||||
String stateStoreName, String key, String etag, StateOptions options, Class<T> clazz) {
|
||||
String stateStoreName, String key, String etag, StateOptions options, TypeRef<T> type) {
|
||||
try {
|
||||
if ((stateStoreName == null) || (stateStoreName.trim().isEmpty())) {
|
||||
throw new IllegalArgumentException("State store name cannot be null or empty.");
|
||||
|
@ -341,7 +407,7 @@ public class DaprClientHttp implements DaprClient {
|
|||
.invokeApi(DaprHttp.HttpMethods.GET.name(), url.toString(), urlParameters, headers)
|
||||
.flatMap(s -> {
|
||||
try {
|
||||
return Mono.just(buildStateKeyValue(s, key, options, clazz));
|
||||
return Mono.just(buildStateKeyValue(s, key, options, type));
|
||||
} catch (Exception ex) {
|
||||
return Mono.error(ex);
|
||||
}
|
||||
|
@ -351,6 +417,12 @@ public class DaprClientHttp implements DaprClient {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Mono<State<T>> getState(
|
||||
String stateStoreName, String key, String etag, StateOptions options, Class<T> clazz) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -453,15 +525,15 @@ public class DaprClientHttp implements DaprClient {
|
|||
*
|
||||
* @param response The response of the HTTP Call
|
||||
* @param requestedKey The Key Requested.
|
||||
* @param clazz The Class of the Value of the state
|
||||
* @param type 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> State<T> buildStateKeyValue(
|
||||
DaprHttp.Response response, String requestedKey, StateOptions stateOptions, Class<T> clazz) throws IOException {
|
||||
DaprHttp.Response response, String requestedKey, StateOptions stateOptions, TypeRef<T> type) throws IOException {
|
||||
// The state is in the body directly, so we use the state serializer here.
|
||||
T value = stateSerializer.deserialize(response.getBody(), clazz);
|
||||
T value = stateSerializer.deserialize(response.getBody(), type);
|
||||
String key = requestedKey;
|
||||
String etag = null;
|
||||
if (response.getHeaders() != null && response.getHeaders().containsKey("Etag")) {
|
||||
|
|
|
@ -7,10 +7,13 @@ package io.dapr.client;
|
|||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.dapr.client.domain.CloudEvent;
|
||||
import io.dapr.utils.TypeRef;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Serializes and deserializes an internal object.
|
||||
|
@ -55,6 +58,19 @@ public class ObjectSerializer {
|
|||
return OBJECT_MAPPER.writeValueAsBytes(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the byte array into the original object.
|
||||
*
|
||||
* @param content Content to be parsed.
|
||||
* @param type Type of the object being deserialized.
|
||||
* @param <T> Generic type of the object being deserialized.
|
||||
* @return Object of type T.
|
||||
* @throws IOException In case content cannot be deserialized.
|
||||
*/
|
||||
public <T> T deserialize(byte[] content, TypeRef<T> type) throws IOException {
|
||||
return deserialize(content, OBJECT_MAPPER.constructType(type.getType()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the byte array into the original object.
|
||||
*
|
||||
|
@ -65,12 +81,16 @@ public class ObjectSerializer {
|
|||
* @throws IOException In case content cannot be deserialized.
|
||||
*/
|
||||
public <T> T deserialize(byte[] content, Class<T> clazz) throws IOException {
|
||||
if ((clazz == null) || (clazz == Void.class)) {
|
||||
return deserialize(content, OBJECT_MAPPER.constructType(clazz));
|
||||
}
|
||||
|
||||
private <T> T deserialize(byte[] content, JavaType javaType) throws IOException {
|
||||
if ((javaType == null) || javaType.isTypeOrSubTypeOf(Void.class)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (clazz.isPrimitive()) {
|
||||
return deserializePrimitives(content, clazz);
|
||||
if (javaType.isPrimitive()) {
|
||||
return deserializePrimitives(content, javaType);
|
||||
}
|
||||
|
||||
if (content == null) {
|
||||
|
@ -78,7 +98,7 @@ public class ObjectSerializer {
|
|||
}
|
||||
|
||||
// Deserialization of GRPC response fails without this check since it does not come as base64 encoded byte[].
|
||||
if (clazz == byte[].class) {
|
||||
if (javaType.hasRawClass(byte[].class)) {
|
||||
return (T) content;
|
||||
}
|
||||
|
||||
|
@ -86,59 +106,59 @@ public class ObjectSerializer {
|
|||
return (T) null;
|
||||
}
|
||||
|
||||
if (clazz == CloudEvent.class) {
|
||||
if (javaType.hasRawClass(CloudEvent.class)) {
|
||||
return (T) CloudEvent.deserialize(content);
|
||||
}
|
||||
|
||||
return OBJECT_MAPPER.readValue(content, clazz);
|
||||
return OBJECT_MAPPER.readValue(content, javaType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a given String to the corresponding object defined by class.
|
||||
*
|
||||
* @param content Value to be parsed.
|
||||
* @param clazz Class of the expected result type.
|
||||
* @param <T> Result type.
|
||||
* @param content Value to be parsed.
|
||||
* @param javaType Type of the expected result type.
|
||||
* @param <T> Result type.
|
||||
* @return Result as corresponding type.
|
||||
* @throws Exception if cannot deserialize primitive time.
|
||||
*/
|
||||
private static <T> T deserializePrimitives(byte[] content, Class<T> clazz) throws IOException {
|
||||
private static <T> T deserializePrimitives(byte[] content, JavaType javaType) throws IOException {
|
||||
if ((content == null) || (content.length == 0)) {
|
||||
if (boolean.class == clazz) {
|
||||
if (javaType.hasRawClass(boolean.class)) {
|
||||
return (T) Boolean.FALSE;
|
||||
}
|
||||
|
||||
if (byte.class == clazz) {
|
||||
if (javaType.hasRawClass(byte.class)) {
|
||||
return (T) Byte.valueOf((byte) 0);
|
||||
}
|
||||
|
||||
if (short.class == clazz) {
|
||||
if (javaType.hasRawClass(short.class)) {
|
||||
return (T) Short.valueOf((short) 0);
|
||||
}
|
||||
|
||||
if (int.class == clazz) {
|
||||
if (javaType.hasRawClass(int.class)) {
|
||||
return (T) Integer.valueOf(0);
|
||||
}
|
||||
|
||||
if (long.class == clazz) {
|
||||
if (javaType.hasRawClass(long.class)) {
|
||||
return (T) Long.valueOf(0L);
|
||||
}
|
||||
|
||||
if (float.class == clazz) {
|
||||
if (javaType.hasRawClass(float.class)) {
|
||||
return (T) Float.valueOf(0);
|
||||
}
|
||||
|
||||
if (double.class == clazz) {
|
||||
if (javaType.hasRawClass(double.class)) {
|
||||
return (T) Double.valueOf(0);
|
||||
}
|
||||
|
||||
if (char.class == clazz) {
|
||||
if (javaType.hasRawClass(char.class)) {
|
||||
return (T) Character.valueOf(Character.MIN_VALUE);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return OBJECT_MAPPER.readValue(content, clazz);
|
||||
return OBJECT_MAPPER.readValue(content, javaType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
package io.dapr.serializer;
|
||||
|
||||
import io.dapr.utils.TypeRef;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
|
@ -13,7 +15,7 @@ import java.io.IOException;
|
|||
public interface DaprObjectSerializer {
|
||||
|
||||
/**
|
||||
* Serializes the given object as a String to be saved.
|
||||
* Serializes the given object as byte[].
|
||||
*
|
||||
* @param o Object to be serialized.
|
||||
* @return Serialized object.
|
||||
|
@ -22,13 +24,13 @@ public interface DaprObjectSerializer {
|
|||
byte[] serialize(Object o) throws IOException;
|
||||
|
||||
/**
|
||||
* Deserializes the given String into a object.
|
||||
* Deserializes the given byte[] into a object.
|
||||
*
|
||||
* @param data Data to be deserialized.
|
||||
* @param clazz Class of object to be deserialized.
|
||||
* @param type Type of object to be deserialized.
|
||||
* @param <T> Type of object to be deserialized.
|
||||
* @return Deserialized object.
|
||||
* @throws IOException If cannot deserialize object.
|
||||
*/
|
||||
<T> T deserialize(byte[] data, Class<T> clazz) throws IOException;
|
||||
<T> T deserialize(byte[] data, TypeRef<T> type) throws IOException;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
package io.dapr.serializer;
|
||||
|
||||
import io.dapr.client.ObjectSerializer;
|
||||
import io.dapr.utils.TypeRef;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Default serializer/deserializer for request/response objects and for state objects too.
|
||||
|
@ -26,7 +28,7 @@ public class DefaultObjectSerializer extends ObjectSerializer implements DaprObj
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> T deserialize(byte[] data, Class<T> clazz) throws IOException {
|
||||
return super.deserialize(data, clazz);
|
||||
public <T> T deserialize(byte[] data, TypeRef<T> type) throws IOException {
|
||||
return super.deserialize(data, type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
package io.dapr.utils;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Used to reference a type.
|
||||
*
|
||||
* <p>Usage: new TypeRef<MyClass>(){}</p>
|
||||
* @param <T> Type to be deserialized.
|
||||
*/
|
||||
public abstract class TypeRef<T> {
|
||||
|
||||
public static final TypeRef<String> STRING = new TypeRef<String>() {};
|
||||
|
||||
public static final TypeRef<Boolean> BOOLEAN = new TypeRef(boolean.class) {};
|
||||
|
||||
public static final TypeRef<Integer> INT = new TypeRef(int.class) {};
|
||||
|
||||
public static final TypeRef<Long> LONG = new TypeRef(long.class) {};
|
||||
|
||||
public static final TypeRef<Character> CHAR = new TypeRef(char.class) {};
|
||||
|
||||
public static final TypeRef<Byte> BYTE = new TypeRef(byte.class) {};
|
||||
|
||||
public static final TypeRef<Void> VOID = new TypeRef(void.class) {};
|
||||
|
||||
public static final TypeRef<Float> FLOAT = new TypeRef(float.class) {};
|
||||
|
||||
public static final TypeRef<Double> DOUBLE = new TypeRef(double.class) {};
|
||||
|
||||
public static final TypeRef<byte[]> BYTE_ARRAY = new TypeRef<byte[]>() {};
|
||||
|
||||
public static final TypeRef<int[]> INT_ARRAY = new TypeRef<int[]>() {};
|
||||
|
||||
public static final TypeRef<String[]> STRING_ARRAY = new TypeRef<String[]>() {};
|
||||
|
||||
private final Type type;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public TypeRef() {
|
||||
Type superClass = this.getClass().getGenericSuperclass();
|
||||
if (superClass instanceof Class) {
|
||||
throw new IllegalArgumentException("TypeReference requires type.");
|
||||
}
|
||||
|
||||
this.type = ((ParameterizedType)superClass).getActualTypeArguments()[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for reflection.
|
||||
*
|
||||
* @param clazz Class type to be referenced.
|
||||
*/
|
||||
private TypeRef(Class<T> clazz) {
|
||||
this.type = clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type referenced.
|
||||
*
|
||||
* @return type referenced.
|
||||
*/
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a reference to a given class type.
|
||||
* @param clazz Class type to be referenced.
|
||||
* @param <T> Type to be referenced.
|
||||
* @return Class type reference.
|
||||
*/
|
||||
public static <T> TypeRef<T> get(Class<T> clazz) {
|
||||
if (clazz == String.class) {
|
||||
return (TypeRef<T>) STRING;
|
||||
}
|
||||
if (clazz == boolean.class) {
|
||||
return (TypeRef<T>) BOOLEAN;
|
||||
}
|
||||
if (clazz == int.class) {
|
||||
return (TypeRef<T>) INT;
|
||||
}
|
||||
if (clazz == long.class) {
|
||||
return (TypeRef<T>) LONG;
|
||||
}
|
||||
if (clazz == char.class) {
|
||||
return (TypeRef<T>) CHAR;
|
||||
}
|
||||
if (clazz == byte.class) {
|
||||
return (TypeRef<T>) BYTE;
|
||||
}
|
||||
if (clazz == void.class) {
|
||||
return (TypeRef<T>) VOID;
|
||||
}
|
||||
if (clazz == float.class) {
|
||||
return (TypeRef<T>) FLOAT;
|
||||
}
|
||||
if (clazz == double.class) {
|
||||
return (TypeRef<T>) DOUBLE;
|
||||
}
|
||||
if (clazz == byte[].class) {
|
||||
return (TypeRef<T>) BYTE_ARRAY;
|
||||
}
|
||||
if (clazz == int[].class) {
|
||||
return (TypeRef<T>) INT_ARRAY;
|
||||
}
|
||||
if (clazz == String[].class) {
|
||||
return (TypeRef<T>) STRING_ARRAY;
|
||||
}
|
||||
|
||||
return new TypeRef<T>(clazz) {};
|
||||
}
|
||||
}
|
|
@ -99,7 +99,7 @@ public class DaprClientHttpTest {
|
|||
String event = "{ \"message\": \"This is a test\" }";
|
||||
daprHttp = new DaprHttp(3000, okHttpClient);
|
||||
daprClientHttp = new DaprClientHttp(daprHttp);
|
||||
Mono<Void> mono = daprClientHttp.invokeService(null, "", "", null, null, null);
|
||||
Mono<Void> mono = daprClientHttp.invokeService(null, "", "", null, null, (Class)null);
|
||||
assertNull(mono.block());
|
||||
}
|
||||
|
||||
|
@ -112,19 +112,19 @@ public class DaprClientHttpTest {
|
|||
daprHttp = new DaprHttp(3000, okHttpClient);
|
||||
daprClientHttp = new DaprClientHttp(daprHttp);
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprClientHttp.invokeService(null, "", "", null, null, null).block();
|
||||
daprClientHttp.invokeService(null, "", "", null, null, (Class)null).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprClientHttp.invokeService(Verb.POST, null, "", null, null, null).block();
|
||||
daprClientHttp.invokeService(Verb.POST, null, "", null, null, (Class)null).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprClientHttp.invokeService(Verb.POST, "", "", null, null, null).block();
|
||||
daprClientHttp.invokeService(Verb.POST, "", "", null, null, (Class)null).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprClientHttp.invokeService(Verb.POST, "1", null, null, null, null).block();
|
||||
daprClientHttp.invokeService(Verb.POST, "1", null, null, null, (Class)null).block();
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
daprClientHttp.invokeService(Verb.POST, "1", "", null, null, null).block();
|
||||
daprClientHttp.invokeService(Verb.POST, "1", "", null, null, (Class)null).block();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ public class DaprClientHttpTest {
|
|||
String event = "{ \"message\": \"This is a test\" }";
|
||||
daprHttp = new DaprHttp(3000, okHttpClient);
|
||||
daprClientHttp = new DaprClientHttp(daprHttp);
|
||||
Mono<Void> mono = daprClientHttp.invokeService(Verb.POST, "1", "", null, null, null);
|
||||
Mono<Void> mono = daprClientHttp.invokeService(Verb.POST, "1", "", null, null, (Class)null);
|
||||
assertNull(mono.block());
|
||||
}
|
||||
|
||||
|
@ -237,6 +237,78 @@ public class DaprClientHttpTest {
|
|||
assertEquals("OK", mono.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeBindingResponseDouble() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
mockInterceptor.addRule()
|
||||
.post("http://127.0.0.1:3000/v1.0/bindings/sample-topic")
|
||||
.respond("1.5");
|
||||
daprHttp = new DaprHttp(3000, okHttpClient);
|
||||
daprClientHttp = new DaprClientHttp(daprHttp);
|
||||
Mono<Double> mono = daprClientHttp.invokeBinding("sample-topic", "myoperation", "", null, double.class);
|
||||
assertEquals(1.5, mono.block(), 0.0001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeBindingResponseFloat() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
mockInterceptor.addRule()
|
||||
.post("http://127.0.0.1:3000/v1.0/bindings/sample-topic")
|
||||
.respond("1.5");
|
||||
daprHttp = new DaprHttp(3000, okHttpClient);
|
||||
daprClientHttp = new DaprClientHttp(daprHttp);
|
||||
Mono<Float> mono = daprClientHttp.invokeBinding("sample-topic", "myoperation", "", null, float.class);
|
||||
assertEquals(1.5, mono.block(), 0.0001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeBindingResponseChar() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
mockInterceptor.addRule()
|
||||
.post("http://127.0.0.1:3000/v1.0/bindings/sample-topic")
|
||||
.respond("\"a\"");
|
||||
daprHttp = new DaprHttp(3000, okHttpClient);
|
||||
daprClientHttp = new DaprClientHttp(daprHttp);
|
||||
Mono<Character> mono = daprClientHttp.invokeBinding("sample-topic", "myoperation", "", null, char.class);
|
||||
assertEquals('a', (char)mono.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeBindingResponseByte() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
mockInterceptor.addRule()
|
||||
.post("http://127.0.0.1:3000/v1.0/bindings/sample-topic")
|
||||
.respond("\"2\"");
|
||||
daprHttp = new DaprHttp(3000, okHttpClient);
|
||||
daprClientHttp = new DaprClientHttp(daprHttp);
|
||||
Mono<Byte> mono = daprClientHttp.invokeBinding("sample-topic", "myoperation", "", null, byte.class);
|
||||
assertEquals((byte)0x2, (byte)mono.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeBindingResponseLong() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
mockInterceptor.addRule()
|
||||
.post("http://127.0.0.1:3000/v1.0/bindings/sample-topic")
|
||||
.respond("1");
|
||||
daprHttp = new DaprHttp(3000, okHttpClient);
|
||||
daprClientHttp = new DaprClientHttp(daprHttp);
|
||||
Mono<Long> mono = daprClientHttp.invokeBinding("sample-topic", "myoperation", "", null, long.class);
|
||||
assertEquals(1, (long)mono.block());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeBindingResponseInt() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
mockInterceptor.addRule()
|
||||
.post("http://127.0.0.1:3000/v1.0/bindings/sample-topic")
|
||||
.respond("1");
|
||||
daprHttp = new DaprHttp(3000, okHttpClient);
|
||||
daprClientHttp = new DaprClientHttp(daprHttp);
|
||||
Mono<Integer> mono = daprClientHttp.invokeBinding("sample-topic", "myoperation", "", null, int.class);
|
||||
assertEquals(1, (int)mono.block());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void invokeBindingNullName() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
|
|
|
@ -5,15 +5,22 @@
|
|||
|
||||
package io.dapr.serializer;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.dapr.serializer.DefaultObjectSerializer;
|
||||
import io.dapr.client.domain.CloudEvent;
|
||||
import io.dapr.utils.TypeRef;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
@ -389,15 +396,38 @@ public class DefaultObjectSerializerTest {
|
|||
expectedResult.setFloatValue(1.0f);
|
||||
expectedResult.setDoubleValue(1000.0);
|
||||
MyObjectTestToSerialize result;
|
||||
|
||||
|
||||
try {
|
||||
result = SERIALIZER.deserialize(jsonToDeserialize.getBytes(), MyObjectTestToSerialize.class);
|
||||
result = SERIALIZER.deserialize(jsonToDeserialize.getBytes(), TypeRef.get(MyObjectTestToSerialize.class));
|
||||
assertEquals("The expected value is different than the actual result", expectedResult, result);
|
||||
} catch (IOException exception) {
|
||||
fail(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeArrayObjectTest() {
|
||||
String jsonToDeserialize = "[{\"stringValue\":\"A String\",\"intValue\":2147483647,\"boolValue\":true,\"charValue\":\"a\",\"byteValue\":65,\"shortValue\":32767,\"longValue\":9223372036854775807,\"floatValue\":1.0,\"doubleValue\":1000.0}]";
|
||||
MyObjectTestToSerialize expectedResult = new MyObjectTestToSerialize();
|
||||
expectedResult.setStringValue("A String");
|
||||
expectedResult.setIntValue(2147483647);
|
||||
expectedResult.setBoolValue(true);
|
||||
expectedResult.setCharValue('a');
|
||||
expectedResult.setByteValue((byte) 65);
|
||||
expectedResult.setShortValue((short) 32767);
|
||||
expectedResult.setLongValue(9223372036854775807L);
|
||||
expectedResult.setFloatValue(1.0f);
|
||||
expectedResult.setDoubleValue(1000.0);
|
||||
List<MyObjectTestToSerialize> result;
|
||||
|
||||
try {
|
||||
result = SERIALIZER.deserialize(jsonToDeserialize.getBytes(), new TypeRef<List<MyObjectTestToSerialize>>(){});
|
||||
assertEquals("The expected value is different than the actual result", expectedResult, result.get(0));
|
||||
} catch (IOException exception) {
|
||||
fail(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeBytesTest() {
|
||||
|
||||
|
@ -414,12 +444,10 @@ public class DefaultObjectSerializerTest {
|
|||
public void deserializeNullObjectOrPrimitiveTest() {
|
||||
|
||||
try {
|
||||
MyObjectTestToSerialize expectedObj = null;
|
||||
MyObjectTestToSerialize objResult = SERIALIZER.deserialize(null, MyObjectTestToSerialize.class);
|
||||
assertEquals(expectedObj, objResult);
|
||||
boolean expectedBoolResutl = false;
|
||||
assertNull(objResult);
|
||||
boolean boolResult = SERIALIZER.deserialize(null, boolean.class);
|
||||
assertEquals(expectedBoolResutl, boolResult);
|
||||
assertEquals(false, boolResult);
|
||||
byte expectedByteResult = Byte.valueOf((byte) 0);
|
||||
byte byteResult = SERIALIZER.deserialize(null, byte.class);
|
||||
assertEquals(expectedByteResult, byteResult);
|
||||
|
@ -785,6 +813,17 @@ public class DefaultObjectSerializerTest {
|
|||
deserializeData.apply(new ObjectMapper().writeValueAsString("{\"id\": \"123:\", \"name\": \"Jon Doe\"}")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeListOfString() throws IOException {
|
||||
List<String> r = SERIALIZER.deserialize("[\"1\", \"2\", \"3\"]".getBytes(), new ArrayList<String>().getClass());
|
||||
|
||||
assertNotNull(r);
|
||||
assertEquals(3, r.size());
|
||||
assertEquals("1", r.get(0));
|
||||
assertEquals("2", r.get(1));
|
||||
assertEquals("3", r.get(2));
|
||||
}
|
||||
|
||||
private static String quote(String content) {
|
||||
if (content == null) {
|
||||
return null;
|
||||
|
|
Loading…
Reference in New Issue