You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/quix-cloud/managed-services/dynamic-configuration.md
+332-8Lines changed: 332 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -132,14 +132,338 @@ This service can leverage a blob storage configured on our platform (see [blob s
132
132
133
133
The blob storage configuration is automatically injected only when `contentStore` is set to `file`.
134
134
135
-
## SDK Integration
135
+
## API Reference
136
136
137
-
The **Quix Streams SDK** provides built-in functionality to:
137
+
The Dynamic Configuration Manager provides a REST API for managing configurations. The API is available at the service endpoint once deployed.
138
138
139
-
- Subscribe to configuration change events.
140
-
- Download and cache the latest configuration from the API.
141
-
- Join configuration values with live data streams at the right time.
139
+
### Base URL
140
+
```
141
+
http://<service-name>:<port>/api/v1
142
+
```
143
+
144
+
### Authentication
145
+
All API requests require authentication via the `Authorization` header:
146
+
```
147
+
Authorization: Bearer <your-token>
148
+
```
149
+
150
+
### Create Configuration
151
+
152
+
Create a new configuration:
153
+
154
+
```http
155
+
POST /api/v1/configurations
156
+
Content-Type: application/json
157
+
158
+
{
159
+
"metadata": {
160
+
"type": "device-config",
161
+
"target_key": "sensor-001",
162
+
"valid_from": "2024-01-01T00:00:00Z",
163
+
"category": "sensors"
164
+
},
165
+
"content": {
166
+
"device": {
167
+
"name": "Temperature Sensor 001",
168
+
"model": "TS-2000",
169
+
"location": "Building A, Floor 2"
170
+
},
171
+
"calibration": {
172
+
"offset": 0.5,
173
+
"scale": 1.02,
174
+
"last_calibrated": "2024-01-01T00:00:00Z"
175
+
},
176
+
"firmware": {
177
+
"version": "2.1.3",
178
+
"features": ["temperature", "humidity"]
179
+
}
180
+
},
181
+
"replace": false
182
+
}
183
+
```
184
+
185
+
**Request Body:**
186
+
-`metadata.type` (string, required): Configuration type identifier
187
+
-`metadata.target_key` (string, required): Target key for configuration matching
188
+
-`metadata.valid_from` (ISO8601 datetime, optional): When this configuration becomes valid
189
+
-`metadata.category` (string, optional): Category for grouping configurations
190
+
-`content` (object, optional): The actual configuration data (JSON object)
191
+
-`replace` (boolean, optional): If true, creates a new version if configuration already exists (default: false)
192
+
193
+
**Note:** The configuration `id` is automatically generated from `type` and `target_key` using SHA-1 hash.
194
+
195
+
### Update Configuration
196
+
197
+
Update an existing configuration (creates a new version):
198
+
199
+
```http
200
+
PUT /api/v1/configurations/{id}
201
+
Content-Type: application/json
202
+
203
+
{
204
+
"metadata": {
205
+
"valid_from": "2024-01-15T00:00:00Z",
206
+
"category": "sensors"
207
+
},
208
+
"content": {
209
+
"device": {
210
+
"name": "Temperature Sensor 001",
211
+
"model": "TS-2000",
212
+
"location": "Building A, Floor 3"
213
+
},
214
+
"calibration": {
215
+
"offset": 0.3,
216
+
"scale": 1.01,
217
+
"last_calibrated": "2024-01-15T10:30:00Z"
218
+
}
219
+
}
220
+
}
221
+
```
222
+
223
+
**Request Body:**
224
+
-`metadata.valid_from` (ISO8601 datetime, optional): Update when this configuration becomes valid
225
+
-`metadata.category` (string, optional): Update the category
226
+
-`content` (object, optional): Updated configuration data
227
+
228
+
**Note:** Only fields you provide will be updated. Omitted fields remain unchanged.
229
+
230
+
### Upload Binary Configuration
231
+
232
+
For non-JSON configurations (firmware files, calibration data, etc.), use the file upload endpoint:
233
+
234
+
```http
235
+
POST /api/v1/configurations/{id}/versions/{version}/content
236
+
Content-Type: multipart/form-data
237
+
238
+
file: <binary-file-data>
239
+
```
240
+
241
+
**Note:** Binary content must be uploaded separately after creating the configuration metadata. The service automatically detects and stores binary content with appropriate `content_type`.
242
+
243
+
### Search Configurations
244
+
245
+
Search for configurations using various criteria:
246
+
247
+
```http
248
+
GET /api/v1/configurations/search?type=device-config&target_key=sensor-001&limit=10&offset=0
249
+
```
250
+
251
+
**Query Parameters:**
252
+
-`type` (string, optional): Filter by configuration type
253
+
-`target_key` (string, optional): Filter by target key
254
+
-`category` (string, optional): Filter by category
255
+
-`limit` (integer, optional): Maximum number of results (default: 20)
256
+
-`offset` (integer, optional): Number of results to skip (default: 0)
257
+
258
+
### Get Configuration
259
+
260
+
Retrieve a specific configuration:
261
+
262
+
```http
263
+
GET /api/v1/configurations/{id}
264
+
```
265
+
266
+
### Get Configuration Version
267
+
268
+
Retrieve a specific version of a configuration:
269
+
270
+
```http
271
+
GET /api/v1/configurations/{id}/versions/{version}
To use file mode, set `contentStore: file` in your deployment configuration.
297
+
298
+
## Using with Quix Streams join_lookup
299
+
300
+
The Dynamic Configuration Manager integrates seamlessly with Quix Streams' `join_lookup` feature to enrich streaming data with configuration data in real-time.
301
+
302
+
### Basic Integration
303
+
304
+
```python
305
+
from quixstreams import Application
306
+
from quixstreams.dataframe.joins.lookups import QuixConfigurationService
307
+
308
+
# Initialize the application
309
+
app = Application()
310
+
311
+
# Create a lookup instance pointing to your configuration topic
Use custom key matching logic for complex scenarios:
356
+
357
+
```python
358
+
defcustom_key_matcher(value, key):
359
+
"""Custom logic to determine configuration key"""
360
+
device_type = value.get("device_type", "unknown")
361
+
location = value.get("location", "default")
362
+
returnf"{device_type}-{location}"
363
+
364
+
# Use custom key matching
365
+
sdf = sdf.join_lookup(
366
+
lookup=lookup,
367
+
fields={
368
+
"config": lookup.json_field(
369
+
jsonpath="$",
370
+
type="location-config"
371
+
)
372
+
},
373
+
on=custom_key_matcher
374
+
)
375
+
```
376
+
377
+
### Binary Configuration Support
378
+
379
+
For non-JSON configurations (firmware files, calibration data, etc.):
380
+
381
+
```python
382
+
sdf = sdf.join_lookup(
383
+
lookup=lookup,
384
+
fields={
385
+
"firmware_binary": lookup.bytes_field(
386
+
type="firmware"
387
+
),
388
+
"calibration_data": lookup.bytes_field(
389
+
type="calibration"
390
+
)
391
+
},
392
+
on="device_id"
393
+
)
394
+
```
395
+
396
+
### How join_lookup Works with Dynamic Configuration
397
+
398
+
1.**Configuration Events**: When configurations are updated via the API, lightweight Kafka events are published to your configuration topic.
399
+
400
+
2.**Real-time Processing**: The `join_lookup` feature listens to these events, fetches the latest configuration content, and caches it locally.
401
+
402
+
3.**Stream Enrichment**: As your main data stream processes records, `join_lookup` automatically enriches each record with the appropriate configuration data based on the matching key and timestamp.
403
+
404
+
4.**Version Management**: The system automatically handles configuration versioning, ensuring that each record is enriched with the configuration version that was valid at the time the record was created.
405
+
406
+
5.**Performance Optimization**: Local caching minimizes API calls and reduces latency for high-throughput applications.
407
+
408
+
### Advanced Use Cases
409
+
410
+
#### Custom Target Key Matching
411
+
412
+
For complex matching logic that goes beyond simple field matching:
0 commit comments