mirror of https://github.com/dapr/docs.git
updates per mark review
Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
This commit is contained in:
parent
d48caef391
commit
52289a9499
|
@ -110,19 +110,64 @@ spec:
|
|||
|
||||
### Shape the outbox pattern message
|
||||
|
||||
You can override the outbox pattern message published to the pub/sub broker by setting a different message. This is done via a projected transaction payload, which is ignored, but used as the outbox pattern message published to the user topic.
|
||||
You can override the outbox pattern message published to the pub/sub broker by setting a different message. This is done via a projected transaction payload, called `outboxProjections`, which is ignored when the state is written and is used as the outbox pattern message published to the user topic.
|
||||
|
||||
In order to override, the `key` values must match between the operation on the state store and the message projection. If the keys do not match, the whole transaction fails.
|
||||
To set the `outboxProjections` to `true`, the `key` values must match between the operation on the state store and the message projection. If the keys do not match, the whole transaction fails.
|
||||
|
||||
If you have two or more `outboxProjections` for the same key, the first one defined is used and the others are ignored.
|
||||
|
||||
{{< tabs JavaScript ".NET" Java Go HTTP >}}
|
||||
[Learn more about default and custom CloudEvent messages.]({{< ref pubsub-cloudevents.md >}})
|
||||
|
||||
{{< tabs Python JavaScript ".NET" Java Go HTTP >}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
<!--python-->
|
||||
|
||||
In the following Python SDK example of a state transaction, the value of `"2"` is saved to the database, but the value of `"3"` is published to the end-user topic.
|
||||
|
||||
```python
|
||||
DAPR_STORE_NAME = "statestore"
|
||||
|
||||
async def main():
|
||||
client = DaprClient()
|
||||
|
||||
# Define the first state operation to save the value "2"
|
||||
op1 = StateItem(
|
||||
key="key1",
|
||||
value=b"2"
|
||||
)
|
||||
|
||||
# Define the second state operation to publish the value "3" with metadata
|
||||
op2 = StateItem(
|
||||
key="key1",
|
||||
value=b"3",
|
||||
options=StateOptions(
|
||||
metadata={
|
||||
"outbox.projection": "true"
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
# Create the list of state operations
|
||||
ops = [op1, op2]
|
||||
|
||||
# Execute the state transaction
|
||||
await client.state.transaction(DAPR_STORE_NAME, operations=ops)
|
||||
print("State transaction executed.")
|
||||
```
|
||||
|
||||
By setting the metadata item `"outbox.projection"` to `"true"` and making sure the `key` values match (`key1`):
|
||||
- The first operation is written to the state store and no message is written to the message broker.
|
||||
- The second operation value is published to the configured pub/sub topic.
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
<!--javascript-->
|
||||
|
||||
In the following .NET SDK example of a state transaction, the value of `"2"` is saved to the database, but the value of `"3"` is published to the end-user topic.
|
||||
In the following JavaScript SDK example of a state transaction, the value of `"2"` is saved to the database, but the value of `"3"` is published to the end-user topic.
|
||||
|
||||
```javascript
|
||||
const { DaprClient, StateOperationType } = require('@dapr/dapr');
|
||||
|
@ -166,7 +211,10 @@ main().catch(err => {
|
|||
});
|
||||
```
|
||||
|
||||
By setting the metadata item `"outbox.projection"` to `"true"`, the first transaction value published to the broker is ignored, while the second value is published to the configured pub/sub topic.
|
||||
By setting the metadata item `"outbox.projection"` to `"true"` and making sure the `key` values match (`key1`):
|
||||
- The first operation is written to the state store and no message is written to the message broker.
|
||||
- The second operation value is published to the configured pub/sub topic.
|
||||
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
|
@ -214,7 +262,9 @@ public class Program
|
|||
}
|
||||
```
|
||||
|
||||
By setting the metadata item `"outbox.projection"` to `"true"`, the first transaction value published to the broker is ignored, while the second value is published to the configured pub/sub topic.
|
||||
By setting the metadata item `"outbox.projection"` to `"true"` and making sure the `key` values match (`key1`):
|
||||
- The first operation is written to the state store and no message is written to the message broker.
|
||||
- The second operation value is published to the configured pub/sub topic.
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
|
@ -222,7 +272,7 @@ By setting the metadata item `"outbox.projection"` to `"true"`, the first transa
|
|||
|
||||
<!--java-->
|
||||
|
||||
In the following Go SDK example of a state transaction, the value of `"2"` is saved to the database, but the value of `"3"` is published to the end-user topic.
|
||||
In the following Java SDK example of a state transaction, the value of `"2"` is saved to the database, but the value of `"3"` is published to the end-user topic.
|
||||
|
||||
```java
|
||||
public class Main {
|
||||
|
@ -263,7 +313,10 @@ public class Main {
|
|||
}
|
||||
```
|
||||
|
||||
By setting the metadata item `"outbox.projection"` to `"true"`, the first transaction value published to the broker is ignored, while the second value is published to the configured pub/sub topic.
|
||||
By setting the metadata item `"outbox.projection"` to `"true"` and making sure the `key` values match (`key1`):
|
||||
- The first operation is written to the state store and no message is written to the message broker.
|
||||
- The second operation value is published to the configured pub/sub topic.
|
||||
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
|
@ -299,7 +352,9 @@ meta := map[string]string{}
|
|||
err := testClient.ExecuteStateTransaction(ctx, store, meta, ops)
|
||||
```
|
||||
|
||||
By setting the metadata item `"outbox.projection"` to `"true"`, the first transaction value published to the broker is ignored, while the second value is published to the configured pub/sub topic.
|
||||
By setting the metadata item `"outbox.projection"` to `"true"` and making sure the `key` values match (`key1`):
|
||||
- The first operation is written to the state store and no message is written to the message broker.
|
||||
- The second operation value is published to the configured pub/sub topic.
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
|
@ -335,7 +390,9 @@ curl -X POST http://localhost:3500/v1.0/state/starwars/transaction \
|
|||
}'
|
||||
```
|
||||
|
||||
By setting the metadata item `"outboxProjection"` to `"true"`, the first transaction value published to the broker is ignored, while the second value is published to the configured pub/sub topic.
|
||||
By setting the metadata item `"outbox.projection"` to `"true"` and making sure the `key` values match (`key1`):
|
||||
- The first operation is written to the state store and no message is written to the message broker.
|
||||
- The second operation value is published to the configured pub/sub topic.
|
||||
|
||||
{{% /codetab %}}
|
||||
|
||||
|
@ -343,9 +400,50 @@ By setting the metadata item `"outboxProjection"` to `"true"`, the first transa
|
|||
|
||||
### Override Dapr-generated CloudEvent fields
|
||||
|
||||
You can also override the [Dapr-generated CloudEvent fields]({{< ref "pubsub-cloudevents.md#dapr-generated-cloudevents-example" >}}) on the published outbox event with custom CloudEvent metadata.
|
||||
You can override the [Dapr-generated CloudEvent fields]({{< ref "pubsub-cloudevents.md#dapr-generated-cloudevents-example" >}}) on the published outbox event with custom CloudEvent metadata.
|
||||
|
||||
{{< tabs JavaScript ".NET" Java Go HTTP >}}
|
||||
{{< tabs Python JavaScript ".NET" Java Go HTTP >}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
<!--python-->
|
||||
|
||||
```python
|
||||
async def execute_state_transaction():
|
||||
async with DaprClient() as client:
|
||||
# Define state operations
|
||||
ops = []
|
||||
|
||||
op1 = {
|
||||
'operation': 'upsert',
|
||||
'request': {
|
||||
'key': 'key1',
|
||||
'value': b'2', # Convert string to byte array
|
||||
'metadata': {
|
||||
'cloudevent.id': 'unique-business-process-id',
|
||||
'cloudevent.source': 'CustomersApp',
|
||||
'cloudevent.type': 'CustomerCreated',
|
||||
'cloudevent.subject': '123',
|
||||
'my-custom-ce-field': 'abc'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ops.append(op1)
|
||||
|
||||
# Execute state transaction
|
||||
store_name = 'your-state-store-name'
|
||||
try:
|
||||
await client.execute_state_transaction(store_name, ops)
|
||||
print('State transaction executed.')
|
||||
except Exception as e:
|
||||
print('Error executing state transaction:', e)
|
||||
|
||||
# Run the async function
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(execute_state_transaction())
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
|
||||
|
@ -398,32 +496,41 @@ public class StateOperationExample
|
|||
{
|
||||
var daprClient = new DaprClientBuilder().Build();
|
||||
|
||||
// Define state operations
|
||||
var ops = new List<StateOperation>();
|
||||
// Define the value "2" as a string and serialize it to a byte array
|
||||
var value = "2";
|
||||
var valueBytes = JsonSerializer.SerializeToUtf8Bytes(value);
|
||||
|
||||
var op1 = new StateOperation
|
||||
// Define the first state operation to save the value "2" with metadata
|
||||
// Override Cloudevent metadata
|
||||
var metadata = new Dictionary<string, string>
|
||||
{
|
||||
OperationType = StateOperationType.Upsert,
|
||||
Request = new SetStateRequest
|
||||
{
|
||||
Key = "key1",
|
||||
Value = new byte[] { 50 }, // []byte("2") in Go is equivalent to new byte[] { 50 } in C#
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
{ "id", "unique-business-process-id" },
|
||||
{ "source", "CustomersApp" },
|
||||
{ "type", "CustomerCreated" },
|
||||
{ "subject", "123" },
|
||||
{ "my-custom-ce-field", "abc" }
|
||||
}
|
||||
}
|
||||
{ "cloudevent.id", "unique-business-process-id" },
|
||||
{ "cloudevent.source", "CustomersApp" },
|
||||
{ "cloudevent.type", "CustomerCreated" },
|
||||
{ "cloudevent.subject", "123" },
|
||||
{ "my-custom-ce-field", "abc" }
|
||||
};
|
||||
|
||||
ops.Add(op1);
|
||||
var op1 = new StateTransactionRequest(
|
||||
key: "key1",
|
||||
value: valueBytes,
|
||||
operationType: StateOperationType.Upsert,
|
||||
metadata: metadata
|
||||
);
|
||||
|
||||
// Execute state transaction
|
||||
// Create the list of state operations
|
||||
var ops = new List<StateTransactionRequest> { op1 };
|
||||
|
||||
// Execute the state transaction
|
||||
var storeName = "your-state-store-name";
|
||||
var metadata = new Dictionary<string, string>();
|
||||
await daprClient.ExecuteStateTransactionAsync(storeName, ops);
|
||||
Console.WriteLine("State transaction executed.");
|
||||
}
|
||||
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
var example = new StateOperationExample();
|
||||
await example.ExecuteStateTransactionAsync();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -442,27 +549,36 @@ public class StateOperationExample {
|
|||
|
||||
public static void executeStateTransaction() {
|
||||
// Build Dapr client
|
||||
DaprClient daprClient = new DaprClientBuilder().build();
|
||||
try (DaprClient daprClient = new DaprClientBuilder().build()) {
|
||||
|
||||
// Define state operations
|
||||
List<StateOperation<?>> ops = new ArrayList<>();
|
||||
// Define the value "2"
|
||||
String value = "2";
|
||||
|
||||
State<String> op1 = new State<>(
|
||||
"key1",
|
||||
"2",
|
||||
new StateOptions<>(StateOperation.Type.UPSERT, new HashMap<String, String>() {{
|
||||
put("id", "unique-business-process-id");
|
||||
put("source", "CustomersApp");
|
||||
put("type", "CustomerCreated");
|
||||
put("subject", "123");
|
||||
put("my-custom-ce-field", "abc");
|
||||
}})
|
||||
);
|
||||
ops.add(op1);
|
||||
// Override CloudEvent metadata
|
||||
Map<String, String> metadata = new HashMap<>();
|
||||
metadata.put("cloudevent.id", "unique-business-process-id");
|
||||
metadata.put("cloudevent.source", "CustomersApp");
|
||||
metadata.put("cloudevent.type", "CustomerCreated");
|
||||
metadata.put("cloudevent.subject", "123");
|
||||
metadata.put("my-custom-ce-field", "abc");
|
||||
|
||||
// Execute state transaction
|
||||
String storeName = "your-state-store-name";
|
||||
Map<String, String> metadata = new HashMap<>();
|
||||
// Define state operations
|
||||
List<StateOperation<?>> ops = new ArrayList<>();
|
||||
StateOperation<String> op1 = new StateOperation<>(
|
||||
StateOperationType.UPSERT,
|
||||
"key1",
|
||||
value,
|
||||
metadata
|
||||
);
|
||||
ops.add(op1);
|
||||
|
||||
// Execute state transaction
|
||||
String storeName = "your-state-store-name";
|
||||
daprClient.executeStateTransaction(storeName, ops).block();
|
||||
System.out.println("State transaction executed.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -473,26 +589,47 @@ public class StateOperationExample {
|
|||
<!--go-->
|
||||
|
||||
```go
|
||||
ops := make([]*dapr.StateOperation, 0)
|
||||
func main() {
|
||||
// Create a Dapr client
|
||||
client, err := dapr.NewClient()
|
||||
if err != nil {
|
||||
log.Fatalf("failed to create Dapr client: %v", err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
op1 := &dapr.StateOperation{
|
||||
Type: dapr.StateOperationTypeUpsert,
|
||||
Item: &dapr.SetStateItem{
|
||||
Key: "key1",
|
||||
Value: []byte("2"),
|
||||
// Override the data payload saved to the database
|
||||
Metadata: map[string]string{
|
||||
"id": "unique-business-process-id",
|
||||
"source": "CustomersApp",
|
||||
"type": "CustomerCreated",
|
||||
"subject": "123",
|
||||
"my-custom-ce-field": "abc",
|
||||
},
|
||||
},
|
||||
ctx := context.Background()
|
||||
store := "your-state-store-name"
|
||||
|
||||
// Define state operations
|
||||
ops := make([]*dapr.StateOperation, 0)
|
||||
op1 := &dapr.StateOperation{
|
||||
Type: dapr.StateOperationTypeUpsert,
|
||||
Item: &dapr.SetStateItem{
|
||||
Key: "key1",
|
||||
Value: []byte("2"),
|
||||
// Override Cloudevent metadata
|
||||
Metadata: map[string]string{
|
||||
"cloudevent.id": "unique-business-process-id",
|
||||
"cloudevent.source": "CustomersApp",
|
||||
"cloudevent.type": "CustomerCreated",
|
||||
"cloudevent.subject": "123",
|
||||
"my-custom-ce-field": "abc",
|
||||
},
|
||||
},
|
||||
}
|
||||
ops = append(ops, op1)
|
||||
|
||||
// Metadata for the transaction (if any)
|
||||
meta := map[string]string{}
|
||||
|
||||
// Execute state transaction
|
||||
err = client.ExecuteStateTransaction(ctx, store, meta, ops)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to execute state transaction: %v", err)
|
||||
}
|
||||
|
||||
log.Println("State transaction executed.")
|
||||
}
|
||||
ops = append(ops, op1, op2)
|
||||
meta := map[string]string{}
|
||||
err := testClient.ExecuteStateTransaction(ctx, store, meta, ops)
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
|
|
Loading…
Reference in New Issue