Skip to content

Commit 0399fe0

Browse files
authored
Merge pull request #290384 from jlian/release-aio-ga
Docs scrub
2 parents fe1c6a3 + 48a4f99 commit 0399fe0

13 files changed

+320
-203
lines changed

articles/iot-operations/connect-to-cloud/concept-dataflow-conversions.md

Lines changed: 18 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ author: PatAltimore
55
ms.author: patricka
66
ms.subservice: azure-data-flows
77
ms.topic: concept-article
8-
ms.date: 10/30/2024
8+
ms.date: 11/11/2024
99

1010
#CustomerIntent: As an operator, I want to understand how to use dataflow conversions to transform data.
1111
ms.service: azure-iot-operations
@@ -84,7 +84,7 @@ In this example, the conversion results in an array containing the values of `[M
8484

8585
## Data types
8686

87-
Different serialization formats support various data types. For instance, JSON offers a few primitive types: string, number, Boolean, and null. Also included are arrays of these primitive types. In contrast, other serialization formats like Avro have a more complex type system, including integers with multiple bit field lengths and timestamps with different resolutions. Examples are milliseconds and microseconds.
87+
Different serialization formats support various data types. For instance, JSON offers a few primitive types: string, number, Boolean, and null. It also includes arrays of these primitive types.
8888

8989
When the mapper reads an input property, it converts it into an internal type. This conversion is necessary for holding the data in memory until it's written out into an output field. The conversion to an internal type happens regardless of whether the input and output serialization formats are the same.
9090

@@ -105,11 +105,7 @@ The internal representation utilizes the following data types:
105105

106106
### Input record fields
107107

108-
When an input record field is read, its underlying type is converted into one of these internal type variants. The internal representation is versatile enough to handle most input types with minimal or no conversion. However, some input types require conversion or are unsupported. Some examples:
109-
110-
* **Avro** `UUID` **type**: It's converted to a `string` because there's no specific `UUID` type in the internal representation.
111-
* **Avro** `decimal` **type**: It isn't supported by the mapper, so fields of this type can't be included in mappings.
112-
* **Avro** `duration` **type**: Conversion can vary. If the `months` field is set, it's unsupported. If only `days` and `milliseconds` are set, it's converted to the internal `duration` representation.
108+
When an input record field is read, its underlying type is converted into one of these internal type variants. The internal representation is versatile enough to handle most input types with minimal or no conversion.
113109

114110
For some formats, surrogate types are used. For example, JSON doesn't have a `datetime` type and instead stores `datetime` values as strings formatted according to ISO8601. When the mapper reads such a field, the internal representation remains a string.
115111

@@ -126,10 +122,6 @@ The mapper is designed to be flexible by converting internal types into output t
126122
* Converted to `0`/`1` if the output field is numerical.
127123
* Converted to `true`/`false` if the output field is string.
128124

129-
### Explicit type conversions
130-
131-
Although the automatic conversions operate as you might expect based on common implementation practices, there are instances where the right conversion can't be determined automatically and results in an *unsupported* error. To address these situations, several conversion functions are available to explicitly define how data should be transformed. These functions provide more control over how data is converted and help maintain data integrity even when automatic methods fall short.
132-
133125
### Use a conversion formula with types
134126

135127
In mappings, an optional formula can specify how data from the input is processed before being written to the output field. If no formula is specified, the mapper copies the input field to the output by using the internal type and conversion rules.
@@ -186,29 +178,6 @@ expression: 'min($1)'
186178

187179
This configuration selects the smallest value from the `Measurements` array for the output field.
188180

189-
It's also possible to use functions that result in a new array:
190-
191-
# [Bicep](#tab/bicep)
192-
193-
```bicep
194-
inputs: [
195-
'Measurements' // - $1
196-
]
197-
output: 'Measurements'
198-
expression: 'take($1, 10)' // taking at max 10 items
199-
```
200-
201-
# [Kubernetes (preview)](#tab/kubernetes)
202-
203-
```yaml
204-
- inputs:
205-
- Measurements # - $1
206-
output: Measurements
207-
expression: take($1, 10) # taking at max 10 items
208-
```
209-
210-
---
211-
212181
Arrays can also be created from multiple single values:
213182

214183
# [Bicep](#tab/bicep)
@@ -302,17 +271,22 @@ The `conversion` uses the `if` function that has three parameters:
302271

303272
## Available functions
304273

305-
Functions can be used in the conversion formula to perform various operations:
274+
Dataflows provide a set of built-in functions that can be used in conversion formulas. These functions can be used to perform common operations like arithmetic, comparison, and string manipulation. The available functions are:
306275

307-
* `min` to select a single item from an array
308-
* `if` to select between values
309-
* String manipulation (for example, `uppercase()`)
310-
* Explicit conversion (for example, `ISO8601_datetime`)
311-
* Aggregation (for example, `avg()`)
276+
| Function | Description | Examples |
277+
|----------|-------------|---------|
278+
| `min` | Return the minimum value from an array. | `min(2, 3, 1)` returns `1`, `min($1)` returns the minimum value from the array `$1` |
279+
| `max` | Return the maximum value from an array. | `max(2, 3, 1)` returns `3`, `max($1)` returns the maximum value from the array `$1` |
280+
| `if` | Return between values based on a condition. | `if($1 > 10, 'High', 'Low')` returns `'High'` if `$1` is greater than `10`, otherwise `'Low'` |
281+
| `len` | Return the character length of a string or the number of elements in a tuple. | `len("Azure")` returns `5`, `len(1, 2, 3)` returns `3`, `len($1)` returns the number of elements in the array `$1` |
282+
| `floor` | Return the largest integer less than or equal to a number. | `floor(2.9)` returns `2` |
283+
| `round` | Return the nearest integer to a number, rounding half-way cases away from 0.0. | `round(2.5)` returns `3` |
284+
| `ceil` | Return the smallest integer greater than or equal to a number. | `ceil(2.1)` returns `3` |
285+
| `scale` | Scale a value from one range to another. | `scale($1, 0, 10, 0, 100)` scales the input value from the range 0 to 10 to the range 0 to 100 |
312286

313-
## Available operations
287+
### Conversion functions
314288

315-
Dataflows offer a wide range of out-of-the-box conversion functions that allow users to easily perform unit conversions without the need for complex calculations. These predefined functions cover common conversions such as temperature, pressure, length, weight, and volume. The following list shows the available conversion functions, along with their corresponding formulas and function names:
289+
Dataflows provide several built-in conversion functions for common unit conversions like temperature, pressure, length, weight, and volume. Here are some examples:
316290

317291
| Conversion | Formula | Function name |
318292
| --- | --- | --- |
@@ -323,7 +297,7 @@ Dataflows offer a wide range of out-of-the-box conversion functions that allow u
323297
| Lbs to kg | Kg = lbs * 0.453592 | `lbToKg` |
324298
| Gallons to liters | Liters = gallons * 3.78541 | `galToL` |
325299

326-
In addition to these unidirectional conversions, we also support the reverse calculations:
300+
Reverse conversions are also supported:
327301

328302
| Conversion | Formula | Function name |
329303
| --- | --- | --- |
@@ -334,13 +308,7 @@ In addition to these unidirectional conversions, we also support the reverse cal
334308
| Kg to lbs | Lbs = kg / 0.453592 | `kgToLb` |
335309
| Liters to gallons | Gallons = liters / 3.78541 | `lToGal` |
336310

337-
These functions are designed to simplify the conversion process. They allow users to input values in one unit and receive the corresponding value in another unit effortlessly.
338-
339-
We also provide a scaling function to scale the range of value to the user-defined range. For the example `scale($1,0,10,0,100)`, the input value is scaled from the range 0 to 10 to the range 0 to 100.
340-
341-
Moreover, users have the flexibility to define their own conversion functions by using simple mathematical formulas. Our system supports basic operators such as addition (`+`), subtraction (`-`), multiplication (`*`), and division (`/`). These operators follow standard rules of precedence. For example, multiplication and division are performed before addition and subtraction. Precedence can be adjusted by using parentheses to ensure the correct order of operations. This capability empowers users to customize their unit conversions to meet specific needs or preferences, enhancing the overall utility and versatility of the system.
342-
343-
For more complex calculations, functions like `sqrt` (which finds the square root of a number) are also available.
311+
Additionally, you can define your own conversion functions using basic mathematical formulas. The system supports operators like addition (`+`), subtraction (`-`), multiplication (`*`), and division (`/`). These operators follow standard rules of precedence, which can be adjusted using parentheses to ensure the correct order of operations. This allows you to customize unit conversions to meet specific needs.
344312

345313
## Available operators by precedence
346314

articles/iot-operations/connect-to-cloud/concept-dataflow-mapping.md

Lines changed: 87 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ author: PatAltimore
55
ms.author: patricka
66
ms.subservice: azure-data-flows
77
ms.topic: concept-article
8-
ms.date: 10/30/2024
8+
ms.date: 11/11/2024
99
ai-usage: ai-assisted
1010

1111
#CustomerIntent: As an operator, I want to understand how to use the dataflow mapping language to transform data.
@@ -118,11 +118,22 @@ The example maps:
118118

119119
Field references show how to specify paths in the input and output by using dot notation like `Employee.DateOfBirth` or accessing data from a contextual dataset via `$context(position)`.
120120

121-
### MQTT user properties
121+
### MQTT and Kafka metadata properties
122122

123-
When you use MQTT as a source or destination, you can access MQTT user properties in the mapping language. User properties can be mapped in the input or output.
123+
When you use MQTT or Kafka as a source or destination, you can access various metadata properties in the mapping language. These properties can be mapped in the input or output.
124124

125-
In the following example, the MQTT `topic` property is mapped to the `origin_topic` field in the output.
125+
#### Metadata properties
126+
127+
* **Topic**: Works for both MQTT and Kafka. It contains the string where the message was published. Example: `$metadata.topic`.
128+
* **User property**: In MQTT, this refers to the free-form key/value pairs an MQTT message can carry. For example, if the MQTT message was published with a user property with key "priority" and value "high", then the `$metadata.user_property.priority` reference hold the value "high". User property keys can be arbitrary strings and may require escaping: `$metadata.user_property."weird key"` uses the key "weird key" (with a space).
129+
* **System property**: This term is used for every property that is not a user property. Currently, only a single system property is supported: `$metadata.system_property.content_type`, which reads the content type property of the MQTT message (if set).
130+
* **Header**: This is the Kafka equivalent of the MQTT user property. Kafka can use any binary value for a key, but dataflow supports only UTF-8 string keys. Example: `$metadata.header.priority`. This functionality is similar to user properties.
131+
132+
#### Mapping metadata properties
133+
134+
##### Input mapping
135+
136+
In the following example, the MQTT `topic` property is mapped to the `origin_topic` field in the output:
126137

127138
# [Bicep](#tab/bicep)
128139

@@ -143,7 +154,30 @@ output: origin_topic
143154

144155
---
145156

146-
You can also map MQTT properties to an output header. In the following example, the MQTT `topic` is mapped to the `origin_topic` field in the output's user property:
157+
If the user property `priority` is present in the MQTT message, the following example demonstrates how to map it to an output field:
158+
159+
# [Bicep](#tab/bicep)
160+
161+
```bicep
162+
inputs: [
163+
'$metadata.user_property.priority'
164+
]
165+
output: 'priority'
166+
```
167+
168+
# [Kubernetes (preview)](#tab/kubernetes)
169+
170+
```yaml
171+
inputs:
172+
- $metadata.user_property.priority
173+
output: priority
174+
```
175+
176+
---
177+
178+
##### Output mapping
179+
180+
You can also map metadata properties to an output header or user property. In the following example, the MQTT `topic` is mapped to the `origin_topic` field in the output's user property:
147181

148182
# [Bicep](#tab/bicep)
149183

@@ -164,6 +198,48 @@ output: $metadata.user_property.origin_topic
164198

165199
---
166200

201+
If the incoming payload contains a `priority` field, the following example demonstrates how to map it to an MQTT user property:
202+
203+
# [Bicep](#tab/bicep)
204+
205+
```bicep
206+
inputs: [
207+
'priority'
208+
]
209+
output: '$metadata.user_property.priority'
210+
```
211+
212+
# [Kubernetes (preview)](#tab/kubernetes)
213+
214+
```yaml
215+
inputs:
216+
- priority
217+
output: $metadata.user_property.priority
218+
```
219+
220+
---
221+
222+
The same example for Kafka:
223+
224+
# [Bicep](#tab/bicep)
225+
226+
```bicep
227+
inputs: [
228+
'priority'
229+
]
230+
output: '$metadata.header.priority'
231+
```
232+
233+
# [Kubernetes (preview)](#tab/kubernetes)
234+
235+
```yaml
236+
inputs:
237+
- priority
238+
output: $metadata.header.priority
239+
```
240+
241+
---
242+
167243
## Contextualization dataset selectors
168244

169245
These selectors allow mappings to integrate extra data from external databases, which are referred to as *contextualization datasets*.
@@ -371,6 +447,7 @@ output: '*'
371447
```
372448
373449
---
450+
This configuration shows a basic mapping where every field in the input is directly mapped to the same field in the output without any changes. The asterisk (`*`) serves as a wildcard that matches any field in the input record.
374451

375452
Here's how the asterisk (`*`) operates in this context:
376453

@@ -379,8 +456,6 @@ Here's how the asterisk (`*`) operates in this context:
379456
* **Captured segment**: The portion of the path that the asterisk matches is referred to as the `captured segment`.
380457
* **Output mapping**: In the output configuration, the `captured segment` is placed where the asterisk appears. This means that the structure of the input is preserved in the output, with the `captured segment` filling the placeholder provided by the asterisk.
381458

382-
This configuration demonstrates the most generic form of mapping, where every field in the input is directly mapped to a corresponding field in the output without modification.
383-
384459
Another example illustrates how wildcards can be used to match subsections and move them together. This example effectively flattens nested structures within a JSON object.
385460

386461
Original JSON:
@@ -454,9 +529,9 @@ Resulting JSON:
454529

455530
When you place a wildcard, you must follow these rules:
456531

457-
* **Single asterisk per dataDestination:** Only one asterisk (`*`) is allowed within a single path.
532+
* **Single asterisk per data reference:** Only one asterisk (`*`) is allowed within a single data reference.
458533
* **Full segment matching:** The asterisk must always match an entire segment of the path. It can't be used to match only a part of a segment, such as `path1.partial*.path3`.
459-
* **Positioning:** The asterisk can be positioned in various parts of `dataDestination`:
534+
* **Positioning:** The asterisk can be positioned in various parts of a data reference:
460535
* **At the beginning:** `*.path2.path3` - Here, the asterisk matches any segment that leads up to `path2.path3`.
461536
* **In the middle:** `path1.*.path3` - In this configuration, the asterisk matches any segment between `path1` and `path3`.
462537
* **At the end:** `path1.path2.*` - The asterisk at the end matches any segment that follows after `path1.path2`.
@@ -643,7 +718,7 @@ When you use the previous example from multi-input wildcards, consider the follo
643718
'*.Min' // - $2
644719
]
645720
output: 'ColorProperties.*.Diff'
646-
expression: 'abs($1 - $2)'
721+
expression: '$1 - $2'
647722
}
648723
```
649724

@@ -660,7 +735,7 @@ When you use the previous example from multi-input wildcards, consider the follo
660735
- '*.Max' # - $1
661736
- '*.Min' # - $2
662737
output: 'ColorProperties.*.Diff'
663-
expression: abs($1 - $2)
738+
expression: $1 - $2
664739
```
665740

666741
---
@@ -752,6 +827,7 @@ Consider a special case for the same fields to help decide the right action:
752827
'Opacity.Max' // - $1
753828
'Opacity.Min' // - $2
754829
]
830+
output: ''
755831
}
756832
```
757833

articles/iot-operations/connect-to-cloud/howto-configure-dataflow-profile.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ms.author: patricka
66
ms.service: azure-iot-operations
77
ms.subservice: azure-data-flows
88
ms.topic: how-to
9-
ms.date: 10/30/2024
9+
ms.date: 11/11/2024
1010

1111
#CustomerIntent: As an operator, I want to understand how to I can configure a a dataflow profile to control a dataflow behavior.
1212
---
@@ -23,6 +23,8 @@ The most important setting is the instance count, which determines the number of
2323

2424
By default, a dataflow profile named "default" is created when Azure IoT Operations is deployed. This dataflow profile has a single instance count. You can use this dataflow profile to get started with Azure IoT Operations.
2525

26+
Currently, when using the [operations experience portal](https://iotoperations.azure.com/), the default dataflow profile is used for all dataflows.
27+
2628
# [Bicep](#tab/bicep)
2729

2830
```bicep
@@ -105,17 +107,13 @@ You can scale the dataflow profile to adjust the number of instances that run th
105107
106108
Scaling can also improve the resiliency of the dataflows by providing redundancy in case of failures.
107109
108-
To manually scale the dataflow profile, specify the maximum number of instances you want to run. For example, to set the instance count to 3:
110+
To manually scale the dataflow profile, specify the number of instances you want to run. For example, to set the instance count to 3:
109111
110112
# [Bicep](#tab/bicep)
111113
112114
```bicep
113-
resource dataflowProfile 'Microsoft.IoTOperations/instances/dataflowProfiles@2024-11-01' = {
114-
parent: aioInstance
115-
name: '<NAME>'
116-
properties: {
117-
instanceCount: 3
118-
}
115+
properties: {
116+
instanceCount: 3
119117
}
120118
```
121119

articles/iot-operations/connect-to-cloud/howto-configure-fabric-endpoint.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ms.author: patricka
66
ms.service: azure-iot-operations
77
ms.subservice: azure-data-flows
88
ms.topic: how-to
9-
ms.date: 11/04/2024
9+
ms.date: 11/11/2024
1010
ai-usage: ai-assisted
1111

1212
#CustomerIntent: As an operator, I want to understand how to configure dataflow endpoints for Microsoft Fabric OneLake in Azure IoT Operations so that I can send data to Microsoft Fabric OneLake.
@@ -116,7 +116,7 @@ apiVersion: connectivity.iotoperations.azure.com/v1
116116
kind: DataflowEndpoint
117117
metadata:
118118
name: <ENDPOINT_NAME>
119-
namespace: azure-iotoperations
119+
namespace: azure-iot-operations
120120
spec:
121121
endpointType: FabricOneLake
122122
fabricOneLakeSettings:
@@ -330,4 +330,4 @@ fabricOneLakeSettings:
330330

331331
## Next steps
332332

333-
To learn more about dataflows, see [Create a dataflow](howto-create-dataflow.md).
333+
To learn more about dataflows, see [Create dataflow](howto-create-dataflow.md).

0 commit comments

Comments
 (0)