mirror of https://github.com/dapr/java-sdk.git
Add metadata for state save operation (#397)
* add metadata for state save * add test case for state hashcode() and equals() * add metadata for state tansactional Co-authored-by: Artur Souza <artursouza.ms@outlook.com>
This commit is contained in:
parent
8cc33b5598
commit
912ff7a781
|
@ -426,6 +426,9 @@ public class DaprClientGrpc extends AbstractDaprClient {
|
||||||
if (state.getEtag() != null) {
|
if (state.getEtag() != null) {
|
||||||
stateBuilder.setEtag(state.getEtag());
|
stateBuilder.setEtag(state.getEtag());
|
||||||
}
|
}
|
||||||
|
if (state.getMetadata() != null) {
|
||||||
|
stateBuilder.putAllMetadata(state.getMetadata());
|
||||||
|
}
|
||||||
if (bytes != null) {
|
if (bytes != null) {
|
||||||
stateBuilder.setValue(ByteString.copyFrom(bytes));
|
stateBuilder.setValue(ByteString.copyFrom(bytes));
|
||||||
}
|
}
|
||||||
|
|
|
@ -411,7 +411,7 @@ public class DaprClientHttp extends AbstractDaprClient {
|
||||||
byte[] data = this.stateSerializer.serialize(state.getValue());
|
byte[] data = this.stateSerializer.serialize(state.getValue());
|
||||||
// Custom serializer, so everything is byte[].
|
// Custom serializer, so everything is byte[].
|
||||||
operations.add(new TransactionalStateOperation<>(operation.getOperation(),
|
operations.add(new TransactionalStateOperation<>(operation.getOperation(),
|
||||||
new State<>(data, state.getKey(), state.getEtag(), state.getOptions())));
|
new State<>(data, state.getKey(), state.getEtag(), state.getMetadata(), state.getOptions())));
|
||||||
}
|
}
|
||||||
TransactionalStateRequest<Object> req = new TransactionalStateRequest<>(internalOperationObjects, metadata);
|
TransactionalStateRequest<Object> req = new TransactionalStateRequest<>(internalOperationObjects, metadata);
|
||||||
byte[] serializedOperationBody = INTERNAL_SERIALIZER.serialize(req);
|
byte[] serializedOperationBody = INTERNAL_SERIALIZER.serialize(req);
|
||||||
|
@ -461,7 +461,8 @@ public class DaprClientHttp extends AbstractDaprClient {
|
||||||
|
|
||||||
byte[] data = this.stateSerializer.serialize(state.getValue());
|
byte[] data = this.stateSerializer.serialize(state.getValue());
|
||||||
// Custom serializer, so everything is byte[].
|
// Custom serializer, so everything is byte[].
|
||||||
internalStateObjects.add(new State<>(data, state.getKey(), state.getEtag(), state.getOptions()));
|
internalStateObjects.add(new State<>(data, state.getKey(), state.getEtag(), state.getMetadata(),
|
||||||
|
state.getOptions()));
|
||||||
}
|
}
|
||||||
byte[] serializedStateBody = INTERNAL_SERIALIZER.serialize(internalStateObjects);
|
byte[] serializedStateBody = INTERNAL_SERIALIZER.serialize(internalStateObjects);
|
||||||
return this.client.invokeApi(
|
return this.client.invokeApi(
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
package io.dapr.client.domain;
|
package io.dapr.client.domain;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class reprent what a State is.
|
* This class reprent what a State is.
|
||||||
*
|
*
|
||||||
|
@ -28,6 +30,11 @@ public class State<T> {
|
||||||
*/
|
*/
|
||||||
private final String etag;
|
private final String etag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The metadata which will be passed to state store component.
|
||||||
|
*/
|
||||||
|
private final Map<String, String> metadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The error in case the key could not be retrieved.
|
* The error in case the key could not be retrieved.
|
||||||
*/
|
*/
|
||||||
|
@ -48,6 +55,7 @@ public class State<T> {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.value = null;
|
this.value = null;
|
||||||
this.etag = null;
|
this.etag = null;
|
||||||
|
this.metadata = null;
|
||||||
this.options = null;
|
this.options = null;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
}
|
}
|
||||||
|
@ -65,6 +73,7 @@ public class State<T> {
|
||||||
this.value = null;
|
this.value = null;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.etag = etag;
|
this.etag = etag;
|
||||||
|
this.metadata = null;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
}
|
}
|
||||||
|
@ -82,6 +91,26 @@ public class State<T> {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.etag = etag;
|
this.etag = etag;
|
||||||
|
this.metadata = null;
|
||||||
|
this.options = options;
|
||||||
|
this.error = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an immutable state.
|
||||||
|
* This Constructor CAN be used anytime you want the state to be saved.
|
||||||
|
*
|
||||||
|
* @param value - The value of the state.
|
||||||
|
* @param key - The key of the state.
|
||||||
|
* @param etag - The etag of the state - for some state stores (like redis) only numbers are supported.
|
||||||
|
* @param metadata - The metadata of the state.
|
||||||
|
* @param options - REQUIRED when saving a state.
|
||||||
|
*/
|
||||||
|
public State(T value, String key, String etag, Map<String, String> metadata, StateOptions options) {
|
||||||
|
this.value = value;
|
||||||
|
this.key = key;
|
||||||
|
this.etag = etag;
|
||||||
|
this.metadata = metadata;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
}
|
}
|
||||||
|
@ -98,6 +127,7 @@ public class State<T> {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.etag = etag;
|
this.etag = etag;
|
||||||
|
this.metadata = null;
|
||||||
this.options = null;
|
this.options = null;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
}
|
}
|
||||||
|
@ -113,6 +143,7 @@ public class State<T> {
|
||||||
this.value = null;
|
this.value = null;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.etag = null;
|
this.etag = null;
|
||||||
|
this.metadata = null;
|
||||||
this.options = null;
|
this.options = null;
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
|
@ -144,6 +175,14 @@ public class State<T> {
|
||||||
return etag;
|
return etag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the metadata of this state.
|
||||||
|
* @return the metadata of this state
|
||||||
|
*/
|
||||||
|
public Map<String, String> getMetadata() {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the error for this state.
|
* Retrieve the error for this state.
|
||||||
*
|
*
|
||||||
|
@ -191,6 +230,10 @@ public class State<T> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getMetadata() != null ? !getMetadata().equals(that.getMetadata()) : that.getMetadata() != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (getOptions() != null ? !getOptions().equals(that.getOptions()) : that.getOptions() != null) {
|
if (getOptions() != null ? !getOptions().equals(that.getOptions()) : that.getOptions() != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -203,6 +246,7 @@ public class State<T> {
|
||||||
int result = getValue() != null ? getValue().hashCode() : 0;
|
int result = getValue() != null ? getValue().hashCode() : 0;
|
||||||
result = 31 * result + (getKey() != null ? getKey().hashCode() : 0);
|
result = 31 * result + (getKey() != null ? getKey().hashCode() : 0);
|
||||||
result = 31 * result + (getEtag() != null ? getEtag().hashCode() : 0);
|
result = 31 * result + (getEtag() != null ? getEtag().hashCode() : 0);
|
||||||
|
result = 31 * result + (getMetadata() != null ? getMetadata().hashCode() : 0);
|
||||||
result = 31 * result + (getError() != null ? getError().hashCode() : 0);
|
result = 31 * result + (getError() != null ? getError().hashCode() : 0);
|
||||||
result = 31 * result + (getOptions() != null ? options.hashCode() : 0);
|
result = 31 * result + (getOptions() != null ? options.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
|
@ -214,6 +258,7 @@ public class State<T> {
|
||||||
+ "value=" + value
|
+ "value=" + value
|
||||||
+ ", key='" + key + "'"
|
+ ", key='" + key + "'"
|
||||||
+ ", etag='" + etag + "'"
|
+ ", etag='" + etag + "'"
|
||||||
|
+ ", metadata={'" + (metadata != null ? metadata.toString() : null) + "'}"
|
||||||
+ ", error='" + error + "'"
|
+ ", error='" + error + "'"
|
||||||
+ ", options={'" + (options != null ? options.toString() : null) + "'}"
|
+ ", options={'" + (options != null ? options.toString() : null) + "'}"
|
||||||
+ "}";
|
+ "}";
|
||||||
|
|
|
@ -5,11 +5,22 @@ import org.junit.Test;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class StateTest {
|
public class StateTest {
|
||||||
|
|
||||||
private static final String KEY = "key";
|
private static final String KEY = "key";
|
||||||
private static final String ETAG = "111";
|
private static final String ETAG = "111";
|
||||||
|
private static final Map<String, String> METADATA = new HashMap<>();
|
||||||
|
static {
|
||||||
|
METADATA.put("key1", "value1");
|
||||||
|
METADATA.put("key2", "value2");
|
||||||
|
METADATA.put("key3", "value3");
|
||||||
|
METADATA.put("key4", "value4");
|
||||||
|
}
|
||||||
private static final StateOptions OPTIONS = new StateOptions(StateOptions.Consistency.STRONG,
|
private static final StateOptions OPTIONS = new StateOptions(StateOptions.Consistency.STRONG,
|
||||||
StateOptions.Concurrency.FIRST_WRITE);
|
StateOptions.Concurrency.FIRST_WRITE);
|
||||||
|
|
||||||
|
@ -26,6 +37,7 @@ public class StateTest {
|
||||||
+ "value=value"
|
+ "value=value"
|
||||||
+ ", key='" + KEY + "'"
|
+ ", key='" + KEY + "'"
|
||||||
+ ", etag='" + ETAG + "'"
|
+ ", etag='" + ETAG + "'"
|
||||||
|
+ ", metadata={'null'}"
|
||||||
+ ", error='null'"
|
+ ", error='null'"
|
||||||
+ ", options={'null'}"
|
+ ", options={'null'}"
|
||||||
+ "}";
|
+ "}";
|
||||||
|
@ -45,6 +57,7 @@ public class StateTest {
|
||||||
+ "value=null"
|
+ "value=null"
|
||||||
+ ", key='" + KEY + "'"
|
+ ", key='" + KEY + "'"
|
||||||
+ ", etag='" + ETAG + "'"
|
+ ", etag='" + ETAG + "'"
|
||||||
|
+ ", metadata={'null'}"
|
||||||
+ ", error='null'"
|
+ ", error='null'"
|
||||||
+ ", options={'" + OPTIONS.toString() + "'}"
|
+ ", options={'" + OPTIONS.toString() + "'}"
|
||||||
+ "}";
|
+ "}";
|
||||||
|
@ -63,10 +76,34 @@ public class StateTest {
|
||||||
+ "value=value"
|
+ "value=value"
|
||||||
+ ", key='" + KEY + "'"
|
+ ", key='" + KEY + "'"
|
||||||
+ ", etag='" + ETAG + "'"
|
+ ", etag='" + ETAG + "'"
|
||||||
|
+ ", metadata={'null'}"
|
||||||
+ ", error='null'"
|
+ ", error='null'"
|
||||||
+ ", options={'" + OPTIONS.toString() + "'}"
|
+ ", options={'" + OPTIONS.toString() + "'}"
|
||||||
+ "}";
|
+ "}";
|
||||||
assertEquals(expected, state.toString());
|
assertEquals(expected, state.toString());
|
||||||
assertEquals("value", state.getValue());
|
assertEquals("value", state.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualsAndHashcode() {
|
||||||
|
State<String> state1 = new State<>("value", KEY, ETAG, new HashMap<>(METADATA), OPTIONS);
|
||||||
|
State<String> state2 = new State<>("value", KEY, ETAG, new HashMap<>(METADATA), OPTIONS);
|
||||||
|
assertEquals(state1.toString(), state2.toString());
|
||||||
|
assertEquals(state1.hashCode(), state2.hashCode());
|
||||||
|
assertEquals(state1, state2);
|
||||||
|
|
||||||
|
Map<String, String> metadata3 = new HashMap<>(METADATA);
|
||||||
|
metadata3.put("key5", "value5");
|
||||||
|
State<String> state3 = new State<>("value", KEY, ETAG, metadata3, OPTIONS);
|
||||||
|
assertNotEquals(state1.toString(), state3.toString());
|
||||||
|
assertNotEquals(state1.hashCode(), state3.hashCode());
|
||||||
|
assertNotEquals(state1, state3);
|
||||||
|
|
||||||
|
Map<String, String> metadata4 = new HashMap<>(METADATA);
|
||||||
|
metadata4.remove("key1");
|
||||||
|
State<String> state4 = new State<>("value", KEY, ETAG, metadata4, OPTIONS);
|
||||||
|
assertNotEquals(state1.toString(), state4.toString());
|
||||||
|
assertNotEquals(state1.hashCode(), state4.hashCode());
|
||||||
|
assertNotEquals(state1, state4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue