mirror of https://github.com/dapr/docs.git
Merge branch 'v1.5' into add_redis_username
This commit is contained in:
commit
d0fc1bdb29
|
|
@ -201,6 +201,10 @@ url_latest_version = "https://docs.dapr.io"
|
|||
sidebar_menu_compact = true
|
||||
navbar_logo = true
|
||||
sidebar_search_disable = true
|
||||
[params.ui.feedback]
|
||||
enable = true
|
||||
yes = '<b>Glad to hear it!</b> Please <a href="https://github.com/dapr/docs/issues/new/choose">tell us how we can improve</a>.'
|
||||
no = '<b>Sorry to hear that.</b> Please <a href="https://github.com/dapr/docs/issues/new/choose">tell us how we can improve</a>.'
|
||||
|
||||
# Links
|
||||
## End user relevant links. These will show up on left side of footer and in the community page if you have one.
|
||||
|
|
|
|||
|
|
@ -7,16 +7,19 @@ no_list: true
|
|||
|
||||
Welcome to the Dapr documentation site!
|
||||
|
||||
### Sections
|
||||
|
||||
{{% alert title="What is Dapr?" color="primary" %}}
|
||||
Dapr is a portable, event-driven runtime that makes it easy for any developer to build resilient,
|
||||
stateless and stateful applications that run on the cloud and edge and embraces the diversity of
|
||||
languages and developer frameworks. Leveraging the benefits of a sidecar architecture, Dapr helps
|
||||
you tackle the challenges that come with building microservices and keeps your code platform agnostic.
|
||||
{{< button text="Get started" page="getting-started" >}}
|
||||
{{% /alert %}}
|
||||
|
||||
|
||||
### Start developing with Dapr
|
||||
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Concepts</b></h5>
|
||||
<p class="card-text">Learn about Dapr, including its main features and capabilities.</p>
|
||||
<a href="{{< ref concepts >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Getting started</b></h5>
|
||||
|
|
@ -24,6 +27,26 @@ Welcome to the Dapr documentation site!
|
|||
<a href="{{< ref getting-started >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Quickstarts</b></h5>
|
||||
<p class="card-text">A collection of tutorials with code samples to get you started quickly with Dapr.</p>
|
||||
<a href="{{< ref quickstarts >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Concepts</b></h5>
|
||||
<p class="card-text">Learn about Dapr, including its main features and capabilities.</p>
|
||||
<a href="{{< ref concepts >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
### Learn more about Dapr
|
||||
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Developing applications</b></h5>
|
||||
|
|
@ -31,9 +54,13 @@ Welcome to the Dapr documentation site!
|
|||
<a href="{{< ref developing-applications >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Building blocks</b></h5>
|
||||
<p class="card-text">Capabilities that solve common development challenges for distributed applications.</p>
|
||||
<a href="{{< ref building-blocks-concept >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Operations</b></h5>
|
||||
|
|
@ -41,6 +68,12 @@ Welcome to the Dapr documentation site!
|
|||
<a href="{{< ref operations >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
### Additional info
|
||||
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><b>Reference</b></h5>
|
||||
|
|
@ -58,64 +91,100 @@ Welcome to the Dapr documentation site!
|
|||
</div>
|
||||
|
||||
|
||||
### Tooling
|
||||
### Tooling and resources
|
||||
|
||||
<div class="media">
|
||||
<a class="pr-1" href="{{< ref ides >}}">
|
||||
<img class="mr-3" src="/images/homepage/vscode.svg" alt="Visual studio code icon" width=40>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>IDE Integrations</b></h5>
|
||||
<p>Learn how to get up and running with Dapr in your preferred integrated development environment.</p>
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/vscode.svg" alt="Visual studio code icon" width=40>
|
||||
<b>IDE Integrations</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Learn how to get up and running with Dapr in your preferred integrated development environment.
|
||||
</p>
|
||||
<a href="{{< ref ides >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media">
|
||||
<a class="pr-1" href="{{< ref sdks >}}">
|
||||
<img class="mr-3" src="/images/homepage/code.svg" alt="Code icon" width=40>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>Language SDKs</b></h5>
|
||||
<p>Create Dapr applications in your preferred language using the Dapr SDKs.</p>
|
||||
<div class="media mt-3">
|
||||
<a class="pr-3" href="{{< ref dotnet >}}">
|
||||
<br>
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/code.svg" alt="Code icon" width=40>
|
||||
<b>Language SDKs</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Create Dapr applications in your preferred language using the Dapr SDKs.
|
||||
</p>
|
||||
<a href="{{< ref sdks >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/dotnet.png" alt=".NET logo" width=30>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>.NET</b></h5>
|
||||
</div>
|
||||
<b>.NET</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Learn more about the .NET SDK.
|
||||
</p>
|
||||
<a href="{{< ref dotnet >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
<div class="media mt-3">
|
||||
<a class="pr-3" href="{{< ref python >}}">
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/python.png" alt="Python logo" width=30>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>Python</b></h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media mt-3">
|
||||
<a class="pr-4" href="{{< ref sdks >}}">
|
||||
<img src="/images/homepage/java.png" alt="Java logo" width=20>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>Java</b></h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media mt-3">
|
||||
<a class="pr-4" href="{{< ref go >}}">
|
||||
<img src="/images/homepage/golang.svg" alt="Go logo" width=30>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>Go</b></h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="media mt-3">
|
||||
<a class="pr-4" href="{{< ref php >}}">
|
||||
<img src="/images/homepage/php.png" alt="PHP logo" width=30>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0"><b>PHP</b></h5>
|
||||
</div>
|
||||
<b>Python</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Learn more about the Python SDK.
|
||||
</p>
|
||||
<a href="{{< ref python >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<br>
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/javalang.png" alt="Java logo" width=30>
|
||||
<b>Java</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Learn more about the Java SDK.
|
||||
</p>
|
||||
<a href="{{< ref java >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/golang.svg" alt="Go logo" width=30>
|
||||
<b>Go</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Learn more about the Go SDK.
|
||||
</p>
|
||||
<a href="{{< ref go >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<img src="/images/homepage/php.png" alt="PHP logo" width=30>
|
||||
<b>PHP</b>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
Learn more about the PHP SDK.
|
||||
</p>
|
||||
<a href="{{< ref php >}}" class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -4,4 +4,13 @@ title: "Dapr concepts"
|
|||
linkTitle: "Concepts"
|
||||
weight: 10
|
||||
description: "Learn about Dapr including its main features and capabilities"
|
||||
---
|
||||
---
|
||||
|
||||
Welcome to the Dapr concepts guide!
|
||||
|
||||
|
||||
{{% alert title="Getting started with Dapr" color="primary" %}}
|
||||
If you are ready to jump in and start developing with Dapr, please
|
||||
visit the [getting started section]({{<ref getting-started>}}).
|
||||
{{< button text="Install Dapr" page="getting-started" >}}
|
||||
{{% /alert %}}
|
||||
|
|
@ -42,14 +42,14 @@ metadata:
|
|||
name: myevent-subscription
|
||||
spec:
|
||||
pubsubname: pubsub
|
||||
topic: deathStarStatus
|
||||
topic: inventory
|
||||
routes:
|
||||
rules:
|
||||
- match: event.type == "rebels.attacking.v3"
|
||||
path: /dsstatus.v3
|
||||
- match: event.type == "rebels.attacking.v2"
|
||||
path: /dsstatus.v2
|
||||
default: /dsstatus
|
||||
- match: event.type == "widget"
|
||||
path: /widgets
|
||||
- match: event.type == "gadget"
|
||||
path: /gadgets
|
||||
default: /products
|
||||
scopes:
|
||||
- app1
|
||||
- app2
|
||||
|
|
@ -59,7 +59,7 @@ scopes:
|
|||
|
||||
Alternatively, the programattic approach varies slightly in that the `routes` structure is returned instead of `route`. The JSON structure matches the declarative YAML.
|
||||
|
||||
{{< tabs Python Node Go PHP>}}
|
||||
{{< tabs Python Node "C#" Go PHP>}}
|
||||
|
||||
{{% codetab %}}
|
||||
```python
|
||||
|
|
@ -77,24 +77,24 @@ def subscribe():
|
|||
subscriptions = [
|
||||
{
|
||||
'pubsubname': 'pubsub',
|
||||
'topic': 'deathStarStatus',
|
||||
'topic': 'inventory',
|
||||
'routes': {
|
||||
'rules': [
|
||||
{
|
||||
'match': 'event.type == "rebels.attacking.v3"',
|
||||
'path': '/dsstatus.v3'
|
||||
'match': 'event.type == "widget"',
|
||||
'path': '/widgets'
|
||||
},
|
||||
{
|
||||
'match': 'event.type == "rebels.attacking.v2"',
|
||||
'path': '/dsstatus.v2'
|
||||
'match': 'event.type == "gadget"',
|
||||
'path': '/gadgets'
|
||||
},
|
||||
],
|
||||
'default': '/dsstatus'
|
||||
'default': '/products'
|
||||
}
|
||||
}]
|
||||
return jsonify(subscriptions)
|
||||
|
||||
@app.route('/dsstatus', methods=['POST'])
|
||||
@app.route('/products', methods=['POST'])
|
||||
def ds_subscriber():
|
||||
print(request.json, flush=True)
|
||||
return json.dumps({'success':True}), 200, {'ContentType':'application/json'}
|
||||
|
|
@ -113,36 +113,64 @@ app.use(bodyParser.json({ type: 'application/*+json' }));
|
|||
const port = 3000
|
||||
|
||||
app.get('/dapr/subscribe', (req, res) => {
|
||||
res.json([
|
||||
{
|
||||
pubsubname: "pubsub",
|
||||
topic: "deathStarStatus",
|
||||
routes: {
|
||||
rules: [
|
||||
{
|
||||
match: 'event.type == "rebels.attacking.v3"',
|
||||
path: '/dsstatus.v3'
|
||||
},
|
||||
{
|
||||
match: 'event.type == "rebels.attacking.v2"',
|
||||
path: '/dsstatus.v2'
|
||||
},
|
||||
],
|
||||
default: '/dsstatus'
|
||||
}
|
||||
}
|
||||
]);
|
||||
res.json([
|
||||
{
|
||||
pubsubname: "pubsub",
|
||||
topic: "inventory",
|
||||
routes: {
|
||||
rules: [
|
||||
{
|
||||
match: 'event.type == "widget"',
|
||||
path: '/widgets'
|
||||
},
|
||||
{
|
||||
match: 'event.type == "gadget"',
|
||||
path: '/gadgets'
|
||||
},
|
||||
],
|
||||
default: '/products'
|
||||
}
|
||||
}
|
||||
]);
|
||||
})
|
||||
|
||||
app.post('/dsstatus', (req, res) => {
|
||||
console.log(req.body);
|
||||
res.sendStatus(200);
|
||||
app.post('/products', (req, res) => {
|
||||
console.log(req.body);
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
app.listen(port, () => console.log(`consumer app listening on port ${port}!`))
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```csharp
|
||||
[Topic("pubsub", "inventory", "event.type ==\"widget\"", 1)]
|
||||
[HttpPost("widgets")]
|
||||
public async Task<ActionResult<Stock>> HandleWidget(Widget widget, [FromServices] DaprClient daprClient)
|
||||
{
|
||||
// Logic
|
||||
return stock;
|
||||
}
|
||||
|
||||
[Topic("pubsub", "inventory", "event.type ==\"gadget\"", 2)]
|
||||
[HttpPost("gadgets")]
|
||||
public async Task<ActionResult<Stock>> HandleGadget(Gadget gadget, [FromServices] DaprClient daprClient)
|
||||
{
|
||||
// Logic
|
||||
return stock;
|
||||
}
|
||||
|
||||
[Topic("pubsub", "inventory")]
|
||||
[HttpPost("products")]
|
||||
public async Task<ActionResult<Stock>> HandleProduct(Product product, [FromServices] DaprClient daprClient)
|
||||
{
|
||||
// Logic
|
||||
return stock;
|
||||
}
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```golang
|
||||
package main
|
||||
|
|
@ -180,19 +208,19 @@ func configureSubscribeHandler(w http.ResponseWriter, _ *http.Request) {
|
|||
t := []subscription{
|
||||
{
|
||||
PubsubName: "pubsub",
|
||||
Topic: "deathStarStatus",
|
||||
Topic: "inventory",
|
||||
Routes: routes{
|
||||
Rules: []rule{
|
||||
{
|
||||
Match: `event.type == "rebels.attacking.v3"`,
|
||||
Path: "/dsstatus.v3",
|
||||
Match: `event.type == "widget"`,
|
||||
Path: "/widgets",
|
||||
},
|
||||
{
|
||||
Match: `event.type == "rebels.attacking.v2"`,
|
||||
Path: "/dsstatus.v2",
|
||||
Match: `event.type == "gadget"`,
|
||||
Path: "/gadgets",
|
||||
},
|
||||
},
|
||||
Default: "/dsstatus",
|
||||
Default: "/products",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -216,14 +244,14 @@ func main() {
|
|||
require_once __DIR__.'/vendor/autoload.php';
|
||||
|
||||
$app = \Dapr\App::create(configure: fn(\DI\ContainerBuilder $builder) => $builder->addDefinitions(['dapr.subscriptions' => [
|
||||
new \Dapr\PubSub\Subscription(pubsubname: 'pubsub', topic: 'deathStarStatus', routes: (
|
||||
new \Dapr\PubSub\Subscription(pubsubname: 'pubsub', topic: 'inventory', routes: (
|
||||
rules: => [
|
||||
('match': 'event.type == "rebels.attacking.v3"', path: '/dsstatus.v3'),
|
||||
('match': 'event.type == "rebels.attacking.v2"', path: '/dsstatus.v2'),
|
||||
('match': 'event.type == "widget"', path: '/widgets'),
|
||||
('match': 'event.type == "gadget"', path: '/gadgets'),
|
||||
]
|
||||
default: '/dsstatus')),
|
||||
default: '/products')),
|
||||
]]));
|
||||
$app->post('/dsstatus', function(
|
||||
$app->post('/products', function(
|
||||
#[\Dapr\Attributes\FromBody]
|
||||
\Dapr\PubSub\CloudEvent $cloudEvent,
|
||||
\Psr\Log\LoggerInterface $logger
|
||||
|
|
@ -238,11 +266,252 @@ $app->start();
|
|||
|
||||
{{< /tabs >}}
|
||||
|
||||
In these examples, depending on the type of the event (`event.type`), the application will be called on `/dsstatus.v3`, `/dsstatus.v2` or `/dsstatus`. The expressions are written as [Common Expression Language (CEL)](https://opensource.google/projects/cel) where `event` represents the cloud event. Any of the attributes from the [CloudEvents core specification](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md#required-attributes) can be referenced in the expression. One caveat is that it is only possible to access the attributes inside `event.data` if it is nested JSON
|
||||
## Common Expression Language (CEL)
|
||||
|
||||
In these examples, depending on the type of the event (`event.type`), the application will be called on `/widgets`, `/gadgets` or `/products`. The expressions are written as [Common Expression Language (CEL)](https://github.com/google/cel-spec) where `event` represents the cloud event. Any of the attributes from the [CloudEvents core specification](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md#required-attributes) can be referenced in the expression.
|
||||
|
||||
### Example expressions
|
||||
|
||||
Match "important" messages
|
||||
|
||||
```javascript
|
||||
has(event.data.important) && event.data.important == true
|
||||
```
|
||||
|
||||
Match deposits greater than $10000
|
||||
|
||||
```javascript
|
||||
event.type == "deposit" && event.data.amount > 10000
|
||||
```
|
||||
|
||||
Match multiple versions of a message
|
||||
|
||||
```javascript
|
||||
event.type == "mymessage.v1"
|
||||
```
|
||||
```javascript
|
||||
event.type == "mymessage.v2"
|
||||
```
|
||||
|
||||
## CloudEvent attributes
|
||||
|
||||
For reference, the following attributes are from the CloudEvents specification.
|
||||
|
||||
### Event Data
|
||||
|
||||
#### data
|
||||
|
||||
As defined by the term Data, CloudEvents MAY include domain-specific information about the occurrence. When present, this information will be encapsulated within `data`.
|
||||
|
||||
- Description: The event payload. This specification does not place any restriction on the type of this information. It is encoded into a media format which is specified by the `datacontenttype` attribute (e.g. application/json), and adheres to the `dataschema` format when those respective attributes are present.
|
||||
- Constraints:
|
||||
- OPTIONAL
|
||||
|
||||
{{% alert title="Limitation" color="warning" %}}
|
||||
Currently, it is only possible to access the attributes inside data if it is nested JSON values and not JSON escaped in a string.
|
||||
{{% /alert %}}
|
||||
|
||||
### REQUIRED Attributes
|
||||
|
||||
The following attributes are REQUIRED to be present in all CloudEvents:
|
||||
|
||||
#### id
|
||||
|
||||
- Type: `String`
|
||||
- Description: Identifies the event. Producers MUST ensure that `source` + `id`
|
||||
is unique for each distinct event. If a duplicate event is re-sent (e.g. due
|
||||
to a network error) it MAY have the same `id`. Consumers MAY assume that
|
||||
Events with identical `source` and `id` are duplicates.
|
||||
- Constraints:
|
||||
- REQUIRED
|
||||
- MUST be a non-empty string
|
||||
- MUST be unique within the scope of the producer
|
||||
- Examples:
|
||||
- An event counter maintained by the producer
|
||||
- A UUID
|
||||
|
||||
#### source
|
||||
|
||||
- Type: `URI-reference`
|
||||
- Description: Identifies the context in which an event happened. Often this
|
||||
will include information such as the type of the event source, the
|
||||
organization publishing the event or the process that produced the event. The
|
||||
exact syntax and semantics behind the data encoded in the URI is defined by
|
||||
the event producer.
|
||||
|
||||
Producers MUST ensure that `source` + `id` is unique for each distinct event.
|
||||
|
||||
An application MAY assign a unique `source` to each distinct producer, which
|
||||
makes it easy to produce unique IDs since no other producer will have the same
|
||||
source. The application MAY use UUIDs, URNs, DNS authorities or an
|
||||
application-specific scheme to create unique `source` identifiers.
|
||||
|
||||
A source MAY include more than one producer. In that case the producers MUST
|
||||
collaborate to ensure that `source` + `id` is unique for each distinct event.
|
||||
|
||||
- Constraints:
|
||||
- REQUIRED
|
||||
- MUST be a non-empty URI-reference
|
||||
- An absolute URI is RECOMMENDED
|
||||
- Examples
|
||||
- Internet-wide unique URI with a DNS authority.
|
||||
- https://github.com/cloudevents
|
||||
- mailto:cncf-wg-serverless@lists.cncf.io
|
||||
- Universally-unique URN with a UUID:
|
||||
- urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66
|
||||
- Application-specific identifiers
|
||||
- /cloudevents/spec/pull/123
|
||||
- /sensors/tn-1234567/alerts
|
||||
- 1-555-123-4567
|
||||
|
||||
#### specversion
|
||||
|
||||
- Type: `String`
|
||||
- Description: The version of the CloudEvents specification which the event
|
||||
uses. This enables the interpretation of the context. Compliant event
|
||||
producers MUST use a value of `1.0` when referring to this version of the
|
||||
specification.
|
||||
|
||||
Currently, this attribute will only have the 'major' and 'minor' version
|
||||
numbers included in it. This allows for 'patch' changes to the specification
|
||||
to be made without changing this property's value in the serialization.
|
||||
Note: for 'release candidate' releases a suffix might be used for testing
|
||||
purposes.
|
||||
|
||||
- Constraints:
|
||||
- REQUIRED
|
||||
- MUST be a non-empty string
|
||||
|
||||
#### type
|
||||
|
||||
- Type: `String`
|
||||
- Description: This attribute contains a value describing the type of event
|
||||
related to the originating occurrence. Often this attribute is used for
|
||||
routing, observability, policy enforcement, etc. The format of this is
|
||||
producer defined and might include information such as the version of the
|
||||
`type` - see
|
||||
[Versioning of CloudEvents in the Primer](https://github.com/cloudevents/spec/blob/v1.0.1/primer.md#versioning-of-cloudevents)
|
||||
for more information.
|
||||
- Constraints:
|
||||
- REQUIRED
|
||||
- MUST be a non-empty string
|
||||
- SHOULD be prefixed with a reverse-DNS name. The prefixed domain dictates the
|
||||
organization which defines the semantics of this event type.
|
||||
- Examples
|
||||
- com.github.pull_request.opened
|
||||
- com.example.object.deleted.v2
|
||||
|
||||
### OPTIONAL Attributes
|
||||
|
||||
The following attributes are OPTIONAL to appear in CloudEvents. See the
|
||||
[Notational Conventions](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md#notational-conventions) section for more information
|
||||
on the definition of OPTIONAL.
|
||||
|
||||
#### datacontenttype
|
||||
|
||||
- Type: `String` per [RFC 2046](https://tools.ietf.org/html/rfc2046)
|
||||
- Description: Content type of `data` value. This attribute enables `data` to
|
||||
carry any type of content, whereby format and encoding might differ from that
|
||||
of the chosen event format. For example, an event rendered using the
|
||||
[JSON envelope](https://github.com/cloudevents/spec/blob/v1.0.1/json-format.md#3-envelope) format might carry an XML payload
|
||||
in `data`, and the consumer is informed by this attribute being set to
|
||||
"application/xml". The rules for how `data` content is rendered for different
|
||||
`datacontenttype` values are defined in the event format specifications; for
|
||||
example, the JSON event format defines the relationship in
|
||||
[section 3.1](https://github.com/cloudevents/spec/blob/v1.0.1/json-format.md#31-handling-of-data).
|
||||
|
||||
For some binary mode protocol bindings, this field is directly mapped to the
|
||||
respective protocol's content-type metadata property. Normative rules for the
|
||||
binary mode and the content-type metadata mapping can be found in the
|
||||
respective protocol.
|
||||
|
||||
In some event formats the `datacontenttype` attribute MAY be omitted. For
|
||||
example, if a JSON format event has no `datacontenttype` attribute, then it is
|
||||
implied that the `data` is a JSON value conforming to the "application/json"
|
||||
media type. In other words: a JSON-format event with no `datacontenttype` is
|
||||
exactly equivalent to one with `datacontenttype="application/json"`.
|
||||
|
||||
When translating an event message with no `datacontenttype` attribute to a
|
||||
different format or protocol binding, the target `datacontenttype` SHOULD be
|
||||
set explicitly to the implied `datacontenttype` of the source.
|
||||
|
||||
- Constraints:
|
||||
- OPTIONAL
|
||||
- If present, MUST adhere to the format specified in
|
||||
[RFC 2046](https://tools.ietf.org/html/rfc2046)
|
||||
- For Media Type examples see
|
||||
[IANA Media Types](http://www.iana.org/assignments/media-types/media-types.xhtml)
|
||||
|
||||
#### dataschema
|
||||
|
||||
- Type: `URI`
|
||||
- Description: Identifies the schema that `data` adheres to. Incompatible
|
||||
changes to the schema SHOULD be reflected by a different URI. See
|
||||
[Versioning of CloudEvents in the Primer](https://github.com/cloudevents/spec/blob/v1.0.1/primer.md#versioning-of-cloudevents)
|
||||
for more information.
|
||||
- Constraints:
|
||||
- OPTIONAL
|
||||
- If present, MUST be a non-empty URI
|
||||
|
||||
#### subject
|
||||
|
||||
- Type: `String`
|
||||
- Description: This describes the subject of the event in the context of the
|
||||
event producer (identified by `source`). In publish-subscribe scenarios, a
|
||||
subscriber will typically subscribe to events emitted by a `source`, but the
|
||||
`source` identifier alone might not be sufficient as a qualifier for any
|
||||
specific event if the `source` context has internal sub-structure.
|
||||
|
||||
Identifying the subject of the event in context metadata (opposed to only in
|
||||
the `data` payload) is particularly helpful in generic subscription filtering
|
||||
scenarios where middleware is unable to interpret the `data` content. In the
|
||||
above example, the subscriber might only be interested in blobs with names
|
||||
ending with '.jpg' or '.jpeg' and the `subject` attribute allows for
|
||||
constructing a simple and efficient string-suffix filter for that subset of
|
||||
events.
|
||||
|
||||
- Constraints:
|
||||
- OPTIONAL
|
||||
- If present, MUST be a non-empty string
|
||||
- Example:
|
||||
- A subscriber might register interest for when new blobs are created inside a
|
||||
blob-storage container. In this case, the event `source` identifies the
|
||||
subscription scope (storage container), the `type` identifies the "blob
|
||||
created" event, and the `id` uniquely identifies the event instance to
|
||||
distinguish separate occurrences of a same-named blob having been created;
|
||||
the name of the newly created blob is carried in `subject`:
|
||||
- `source`: https://example.com/storage/tenant/container
|
||||
- `subject`: mynewfile.jpg
|
||||
|
||||
#### time
|
||||
|
||||
- Type: `Timestamp`
|
||||
- Description: Timestamp of when the occurrence happened. If the time of the
|
||||
occurrence cannot be determined then this attribute MAY be set to some other
|
||||
time (such as the current time) by the CloudEvents producer, however all
|
||||
producers for the same `source` MUST be consistent in this respect. In other
|
||||
words, either they all use the actual time of the occurrence or they all use
|
||||
the same algorithm to determine the value used.
|
||||
- Constraints:
|
||||
- OPTIONAL
|
||||
- If present, MUST adhere to the format specified in
|
||||
[RFC 3339](https://tools.ietf.org/html/rfc3339)
|
||||
|
||||
{{% alert title="Limitation" color="warning" %}}
|
||||
Currently, comparisons to time (e.g. before or after "now") are not supported.
|
||||
{{% /alert %}}
|
||||
|
||||
## Community call demo
|
||||
|
||||
Watch [this video](https://www.youtube.com/watch?v=QqJgRmbH82I&t=1063s) on how to use message routing with pub/sub:
|
||||
|
||||
<p class="embed-responsive embed-responsive-16by9">
|
||||
<iframe width="688" height="430" src="https://www.youtube.com/embed/QqJgRmbH82I?start=1063" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</p>
|
||||
|
||||
## Next steps
|
||||
|
||||
- Try the [Pub/Sub quickstart sample](https://github.com/dapr/quickstarts/tree/master/pub-sub)
|
||||
- Try the [Pub/Sub routing sample](https://github.com/dapr/samples/tree/master/pub-sub-routing)
|
||||
- Learn about [topic scoping]({{< ref pubsub-scopes.md >}})
|
||||
- Learn about [message time-to-live]({{< ref pubsub-message-ttl.md >}})
|
||||
- Learn [how to configure Pub/Sub components with multiple namespaces]({{< ref pubsub-namespaces.md >}})
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ Welcome to the Dapr getting started guide!
|
|||
|
||||
{{% alert title="Dapr Concepts" color="primary" %}}
|
||||
If you are looking for an introductory overview of Dapr and learn more about basic Dapr terminology, it is recommended to visit the [concepts section]({{<ref concepts>}}).
|
||||
{{< button text="Learn more" page="concepts" >}}
|
||||
{{% /alert %}}
|
||||
|
||||
This guide will walk you through a series of steps to install, initialize and start using Dapr. The recommended way to get started with Dapr is to setup a local development environment (also referred to as [_self-hosted_ mode]({{< ref self-hosted >}})) which includes the Dapr CLI, Dapr sidecar binaries, and some default components that can help you start using Dapr quickly.
|
||||
|
|
@ -23,3 +24,4 @@ The following steps in this guide are:
|
|||
1. Explore Dapr quickstarts
|
||||
|
||||
{{< button text="First step: Install the Dapr CLI >>" page="install-dapr-cli" >}}
|
||||
<br><br>
|
||||
|
|
@ -10,12 +10,6 @@ Access control enables the configuration of policies that restrict what operatio
|
|||
|
||||
An access control policy is specified in configuration and be applied to Dapr sidecar for the *called* application. Example access policies are shown below and access to the called app is based on the matched policy action. You can provide a default global action for all calling applications and if no access control policy is specified, the default behavior is to allow all calling applications to access to the called app.
|
||||
|
||||
Watch this [video](https://youtu.be/j99RN_nxExA?t=1108) on how to apply access control list for service invocation.
|
||||
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<iframe width="688" height="430" src="https://www.youtube.com/embed/j99RN_nxExA?start=1108" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
||||
|
||||
## Concepts
|
||||
|
||||
**TrustDomain** - A "trust domain" is a logical group to manage trust relationships. Every application is assigned a trust domain which can be specified in the access control list policy spec. If no policy spec is defined or an empty trust domain is specified, then a default value "public" is used. This trust domain is used to generate the identity of the application in the TLS cert.
|
||||
|
|
@ -357,3 +351,10 @@ spec:
|
|||
- name: python
|
||||
image: dapriosamples/hello-k8s-python:edge
|
||||
```
|
||||
|
||||
## Community call demo
|
||||
Watch this [video](https://youtu.be/j99RN_nxExA?t=1108) on how to apply access control list for service invocation.
|
||||
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<iframe width="688" height="430" src="https://www.youtube.com/embed/j99RN_nxExA?start=1108" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
||||
|
|
@ -95,14 +95,14 @@ Code | Description
|
|||
### Examples
|
||||
|
||||
```shell
|
||||
curl http://localhost:3500/v1.0/secrets/vault/db-secret \
|
||||
curl http://localhost:3500/v1.0/secrets/vault/db-secret
|
||||
```
|
||||
|
||||
```shell
|
||||
curl http://localhost:3500/v1.0/secrets/vault/db-secret?metadata.version_id=15&metadata.version_stage=AAA \
|
||||
curl http://localhost:3500/v1.0/secrets/vault/db-secret?metadata.version_id=15&metadata.version_stage=AAA
|
||||
```
|
||||
|
||||
> Note, in case of deploying into namespace other than default`, the above query will also have to include the namespace metadata (e.g. `production` below)
|
||||
> Note, in case of deploying into namespace other than default, the above query will also have to include the namespace metadata (e.g. `production` below)
|
||||
|
||||
```shell
|
||||
curl http://localhost:3500/v1.0/secrets/vault/db-secret?metadata.version_id=15&?metadata.namespace=production
|
||||
|
|
@ -165,7 +165,7 @@ Code | Description
|
|||
### Examples
|
||||
|
||||
```shell
|
||||
curl http://localhost:3500/v1.0/secrets/vault/bulk \
|
||||
curl http://localhost:3500/v1.0/secrets/vault/bulk
|
||||
```
|
||||
|
||||
```json
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ spec:
|
|||
value: https://www.googleapis.com/robot/v1/metadata/x509/<project-name>.iam.gserviceaccount.com
|
||||
- name: private_key
|
||||
value: PRIVATE KEY
|
||||
- name: decodeBase64
|
||||
value: <bool>
|
||||
- name: encodeBase64
|
||||
value: <bool>
|
||||
```
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
|
|
@ -65,12 +69,17 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
| token_uri | Y | Output | Google account token uri | `https://oauth2.googleapis.com/token`
|
||||
| auth_provider_x509_cert_url | Y | Output | GCP credentials cert url | `https://www.googleapis.com/oauth2/v1/certs`
|
||||
| client_x509_cert_url | Y | Output | GCP credentials project x509 cert url | `https://www.googleapis.com/robot/v1/metadata/x509/<PROJECT_NAME>.iam.gserviceaccount.com`
|
||||
| decodeBase64 | N | Output | Configuration to decode base64 file content before saving to bucket storage. (In case of saving a file with binary content). `true` is the only allowed positive value. Other positive variations like `"True", "1"` are not acceptable. Defaults to `false` | `true`, `false` |
|
||||
| encodeBase64 | N | Output | Configuration to encode base64 file content before return the content. (In case of opening a file with binary content). `true` is the only allowed positive value. Other positive variations like `"True", "1"` are not acceptable. Defaults to `false` | `true`, `false` |
|
||||
|
||||
## Binding support
|
||||
|
||||
This component supports **output binding** with the following operations:
|
||||
|
||||
- `create`
|
||||
- `create` : [Create file](#create-file)
|
||||
- `get` : [Get file](#get-file)
|
||||
- `delete` : [Delete file](#delete-file)
|
||||
- `list`: [List file](#list-files)
|
||||
|
||||
### Create file
|
||||
|
||||
|
|
@ -84,10 +93,11 @@ To perform a create operation, invoke the GCP Storage Bucket binding with a `POS
|
|||
"data": "YOUR_CONTENT"
|
||||
}
|
||||
```
|
||||
The metadata parameters are:
|
||||
- `key` - (optional) the name of the object
|
||||
- `decodeBase64` - (optional) configuration to decode base64 file content before saving to storage
|
||||
|
||||
#### Examples
|
||||
|
||||
|
||||
##### Save text to a random generated UUID file
|
||||
|
||||
{{< tabs Windows Linux >}}
|
||||
|
|
@ -113,14 +123,14 @@ To perform a create operation, invoke the GCP Storage Bucket binding with a `POS
|
|||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d "{ \"operation\": \"create\", \"data\": \"Hello World\", \"metadata\": { \"name\": \"my-test-file.txt\" } }" \
|
||||
curl -d "{ \"operation\": \"create\", \"data\": \"Hello World\", \"metadata\": { \"key\": \"my-test-file.txt\" } }" \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ "operation": "create", "data": "Hello World", "metadata": { "name": "my-test-file.txt" } }' \
|
||||
curl -d '{ "operation": "create", "data": "Hello World", "metadata": { "key": "my-test-file.txt" } }' \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
|
@ -138,19 +148,175 @@ Then you can upload it as you would normally:
|
|||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d "{ \"operation\": \"create\", \"data\": \"(YOUR_FILE_CONTENTS)\", \"metadata\": { \"name\": \"my-test-file.jpg\" } }" http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
curl -d "{ \"operation\": \"create\", \"data\": \"(YOUR_FILE_CONTENTS)\", \"metadata\": { \"key\": \"my-test-file.jpg\" } }" http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ "operation": "create", "data": "$(cat my-test-file.jpg)", "metadata": { "name": "my-test-file.jpg" } }' \
|
||||
curl -d '{ "operation": "create", "data": "$(cat my-test-file.jpg)", "metadata": { "key": "my-test-file.jpg" } }' \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
#### Response
|
||||
|
||||
The response body will contain the following JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"objectURL":"https://storage.googleapis.com/<your bucket>/<key>",
|
||||
}
|
||||
```
|
||||
|
||||
### Get object
|
||||
|
||||
To perform a get file operation, invoke the GCP bucket binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "get",
|
||||
"metadata": {
|
||||
"key": "my-test-file.txt"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The metadata parameters are:
|
||||
|
||||
- `key` - the name of the object
|
||||
- `encodeBase64` - (optional) configuration to encode base64 file content before return the content.
|
||||
|
||||
|
||||
#### Example
|
||||
|
||||
{{< tabs Windows Linux >}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ \"operation\": \"get\", \"metadata\": { \"key\": \"my-test-file.txt\" }}' http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ "operation": "get", "metadata": { "key": "my-test-file.txt" }}' \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
#### Response
|
||||
|
||||
The response body contains the value stored in the object.
|
||||
|
||||
|
||||
### Delete object
|
||||
|
||||
To perform a delete object operation, invoke the GCP bucket binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "delete",
|
||||
"metadata": {
|
||||
"key": "my-test-file.txt"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The metadata parameters are:
|
||||
|
||||
- `key` - the name of the object
|
||||
|
||||
|
||||
#### Examples
|
||||
|
||||
##### Delete object
|
||||
|
||||
{{< tabs Windows Linux >}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ \"operation\": \"delete\", \"metadata\": { \"key\": \"my-test-file.txt\" }}' http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{% codetab %}}
|
||||
```bash
|
||||
curl -d '{ "operation": "delete", "metadata": { "key": "my-test-file.txt" }}' \
|
||||
http://localhost:<dapr-port>/v1.0/bindings/<binding-name>
|
||||
```
|
||||
{{% /codetab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
#### Response
|
||||
An HTTP 204 (No Content) and empty body will be retuned if successful.
|
||||
|
||||
|
||||
### List objects
|
||||
|
||||
To perform a list object operation, invoke the S3 binding with a `POST` method and the following JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"operation": "list",
|
||||
"data": {
|
||||
"maxResults": 10,
|
||||
"prefix": "file",
|
||||
"delimiter": "i0FvxAn2EOEL6"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The data parameters are:
|
||||
|
||||
- `maxResults` - (optional) sets the maximum number of keys returned in the response. By default the action returns up to 1,000 key names. The response might contain fewer keys but will never contain more.
|
||||
- `prefix` - (optional) it can be used to filter objects starting with prefix.
|
||||
- `delimiter` - (optional) it can be used to restrict the results to only the kobjects in the given "directory". Without the delimiter, the entire tree under the prefix is returned
|
||||
|
||||
#### Response
|
||||
|
||||
The response body contains the list of found objects.
|
||||
|
||||
The list of objects will be returned as JSON array in the following form:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"Bucket": "<your bucket>",
|
||||
"Name": "02WGzEdsUWNlQ",
|
||||
"ContentType": "image/png",
|
||||
"ContentLanguage": "",
|
||||
"CacheControl": "",
|
||||
"EventBasedHold": false,
|
||||
"TemporaryHold": false,
|
||||
"RetentionExpirationTime": "0001-01-01T00:00:00Z",
|
||||
"ACL": null,
|
||||
"PredefinedACL": "",
|
||||
"Owner": "",
|
||||
"Size": 5187,
|
||||
"ContentEncoding": "",
|
||||
"ContentDisposition": "",
|
||||
"MD5": "aQdLBCYV0BxA51jUaxc3pQ==",
|
||||
"CRC32C": 1058633505,
|
||||
"MediaLink": "https://storage.googleapis.com/download/storage/v1/b/<your bucket>/o/02WGzEdsUWNlQ?generation=1631553155678071&alt=media",
|
||||
"Metadata": null,
|
||||
"Generation": 1631553155678071,
|
||||
"Metageneration": 1,
|
||||
"StorageClass": "STANDARD",
|
||||
"Created": "2021-09-13T17:12:35.679Z",
|
||||
"Deleted": "0001-01-01T00:00:00Z",
|
||||
"Updated": "2021-09-13T17:12:35.679Z",
|
||||
"CustomerKeySHA256": "",
|
||||
"KMSKeyName": "",
|
||||
"Prefix": "",
|
||||
"Etag": "CPf+mpK5/PICEAE="
|
||||
}
|
||||
]
|
||||
```
|
||||
## Related links
|
||||
|
||||
- [Basic schema for a Dapr component]({{< ref component-schema >}})
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ spec:
|
|||
value: false
|
||||
- name: maxPriority
|
||||
value: 5
|
||||
- name: contentType
|
||||
value: "text/plain"
|
||||
```
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
|
|
@ -56,6 +58,7 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
| prefetchCount | N | Input | Set the [Channel Prefetch Setting (QoS)](https://www.rabbitmq.com/confirms.html#channel-qos-prefetch). If this parameter is omiited, QoS would set value to 0 as no limit | `0` |
|
||||
| exclusive | N | Input/Output | Determines whether the topic will be an exclusive topic or not. Defaults to `"false"` | `"true"`, `"false"` |
|
||||
| maxPriority| N | Input/Output | Parameter to set the [priority queue](https://www.rabbitmq.com/priority.html). If this parameter is omitted, queue will be created as a general queue instead of a priority queue. Value between 1 and 255. See [also](#specifying-a-priority-per-message) | `"1"`, `"10"` |
|
||||
| contentType | N | Input/Output | The content type of the message. Defaults to "text/plain". | `"text/plain"`, `"application/cloudevent+json"` and so on |
|
||||
## Binding support
|
||||
|
||||
This component supports both **input and output** binding interfaces.
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ spec:
|
|||
value: "myqueue"
|
||||
- name: ttlInSeconds
|
||||
value: "60"
|
||||
- name: decodeBase64
|
||||
value: "false"
|
||||
```
|
||||
|
||||
{{% alert title="Warning" color="warning" %}}
|
||||
|
|
@ -44,6 +46,7 @@ The above example uses secrets as plain strings. It is recommended to use a secr
|
|||
| storageAccessKey | Y | Input/Output | The Azure Storage access key | `"accessKey"` |
|
||||
| queue | Y | Input/Output | The name of the Azure Storage queue | `"myqueue"` |
|
||||
| ttlInSeconds | N | Output | Parameter to set the default message time to live. If this parameter is omitted, messages will expire after 10 minutes. See [also](#specifying-a-ttl-per-message) | `"60"` |
|
||||
| decodeBase64 | N | Output | Configuration to decode base64 file content before saving to Blob Storage. (In case of saving a file with binary content). `true` is the only allowed positive value. Other positive variations like `"True", "1"` are not acceptable. Defaults to `false` | `true`, `false` |
|
||||
|
||||
## Binding support
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
<style>
|
||||
.feedback--title {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
.feedback--answer {
|
||||
display: inline-block;
|
||||
}
|
||||
.feedback--answer-no {
|
||||
margin-left: 1em;
|
||||
}
|
||||
.feedback--response {
|
||||
display: none;
|
||||
margin-top: 1em;
|
||||
}
|
||||
.feedback--response__visible {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<div class="d-print-none">
|
||||
<h2 class="feedback--title">Feedback</h2>
|
||||
<p class="feedback--question">Was this page helpful?</p>
|
||||
<button class="btn btn-primary mb-4 feedback--answer feedback--answer-yes">Yes</button>
|
||||
<button class="btn btn-primary mb-4 feedback--answer feedback--answer-no">No</button>
|
||||
<p class="feedback--response feedback--response-yes">
|
||||
{{ .yes | safeHTML }}
|
||||
</p>
|
||||
<p class="feedback--response feedback--response-no">
|
||||
{{ .no | safeHTML }}
|
||||
</p>
|
||||
</div>
|
||||
<script>
|
||||
const yesButton = document.querySelector('.feedback--answer-yes');
|
||||
const noButton = document.querySelector('.feedback--answer-no');
|
||||
const yesResponse = document.querySelector('.feedback--response-yes');
|
||||
const noResponse = document.querySelector('.feedback--response-no');
|
||||
const disableButtons = () => {
|
||||
yesButton.disabled = true;
|
||||
noButton.disabled = true;
|
||||
};
|
||||
const sendFeedback = (value) => {
|
||||
if (typeof ga !== 'function') return;
|
||||
const args = {
|
||||
command: 'send',
|
||||
hitType: 'event',
|
||||
category: 'Helpful',
|
||||
action: 'click',
|
||||
label: window.location.pathname,
|
||||
value: value
|
||||
};
|
||||
ga(args.command, args.hitType, args.category, args.action, args.label, args.value);
|
||||
};
|
||||
yesButton.addEventListener('click', () => {
|
||||
yesResponse.classList.add('feedback--response__visible');
|
||||
disableButtons();
|
||||
sendFeedback(1);
|
||||
});
|
||||
noButton.addEventListener('click', () => {
|
||||
noResponse.classList.add('feedback--response__visible');
|
||||
disableButtons();
|
||||
sendFeedback(0);
|
||||
});
|
||||
</script>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"globalHeaders": {
|
||||
"X-Frame-Options": "DENY"
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue