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
+335-8Lines changed: 335 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -132,14 +132,341 @@ 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
+
187
+
-**metadata.type** (string, required): Configuration type identifier
188
+
-**metadata.target_key** (string, required): Target key for configuration matching
189
+
-**metadata.valid_from** (ISO8601 datetime, optional): When this configuration becomes valid
190
+
-**metadata.category** (string, optional): Category for grouping configurations
191
+
-**content** (object, optional): The actual configuration data (JSON object)
192
+
-**replace** (boolean, optional): If true, creates a new version if configuration already exists (default: false)
193
+
194
+
**Note:** The configuration `id` is automatically generated from `type` and `target_key` using SHA-1 hash.
195
+
196
+
### Update Configuration
197
+
198
+
Update an existing configuration (creates a new version):
199
+
200
+
```http
201
+
PUT /api/v1/configurations/{id}
202
+
Content-Type: application/json
203
+
204
+
{
205
+
"metadata": {
206
+
"valid_from": "2024-01-15T00:00:00Z",
207
+
"category": "sensors"
208
+
},
209
+
"content": {
210
+
"device": {
211
+
"name": "Temperature Sensor 001",
212
+
"model": "TS-2000",
213
+
"location": "Building A, Floor 3"
214
+
},
215
+
"calibration": {
216
+
"offset": 0.3,
217
+
"scale": 1.01,
218
+
"last_calibrated": "2024-01-15T10:30:00Z"
219
+
}
220
+
}
221
+
}
222
+
```
223
+
224
+
### Request Body
225
+
226
+
-**metadata.valid_from** (ISO8601 datetime, optional): Update when this configuration becomes valid
227
+
-**metadata.category** (string, optional): Update the category
228
+
-**content** (object, optional): Updated configuration data
229
+
230
+
**Note:** Only fields you provide will be updated. Omitted fields remain unchanged.
231
+
232
+
### Upload Binary Configuration
233
+
234
+
For non-JSON configurations (firmware files, calibration data, etc.), use the file upload endpoint:
235
+
236
+
```http
237
+
POST /api/v1/configurations/{id}/versions/{version}/content
238
+
Content-Type: multipart/form-data
239
+
240
+
file: <binary-file-data>
241
+
```
242
+
243
+
**Note:** Binary content must be uploaded separately after creating the configuration metadata. The service automatically detects and stores binary content with appropriate `content_type`.
244
+
245
+
### Search Configurations
246
+
247
+
Search for configurations using various criteria:
248
+
249
+
```http
250
+
GET /api/v1/configurations/search?type=device-config&target_key=sensor-001&limit=10&offset=0
251
+
```
252
+
253
+
### Query Parameters
254
+
255
+
-**type** (string, optional): Filter by configuration type
256
+
-**target_key** (string, optional): Filter by target key
257
+
-**category** (string, optional): Filter by category
258
+
-**limit** (integer, optional): Maximum number of results (default: 20)
259
+
-**offset** (integer, optional): Number of results to skip (default: 0)
260
+
261
+
### Get Configuration
262
+
263
+
Retrieve a specific configuration:
264
+
265
+
```http
266
+
GET /api/v1/configurations/{id}
267
+
```
268
+
269
+
### Get Configuration Version
270
+
271
+
Retrieve a specific version of a configuration:
272
+
273
+
```http
274
+
GET /api/v1/configurations/{id}/versions/{version}
To use file mode, set `contentStore: file` in your deployment configuration.
300
+
301
+
## Using with Quix Streams join_lookup
302
+
303
+
The Dynamic Configuration Manager integrates seamlessly with Quix Streams' `join_lookup` feature to enrich streaming data with configuration data in real-time.
304
+
305
+
### Basic Integration
306
+
307
+
```python
308
+
from quixstreams import Application
309
+
from quixstreams.dataframe.joins.lookups import QuixConfigurationService
310
+
311
+
# Initialize the application
312
+
app = Application()
313
+
314
+
# Create a lookup instance pointing to your configuration topic
Use custom key matching logic for complex scenarios:
359
+
360
+
```python
361
+
defcustom_key_matcher(value, key):
362
+
"""Custom logic to determine configuration key"""
363
+
device_type = value.get("device_type", "unknown")
364
+
location = value.get("location", "default")
365
+
returnf"{device_type}-{location}"
366
+
367
+
# Use custom key matching
368
+
sdf = sdf.join_lookup(
369
+
lookup=lookup,
370
+
fields={
371
+
"config": lookup.json_field(
372
+
jsonpath="$",
373
+
type="location-config"
374
+
)
375
+
},
376
+
on=custom_key_matcher
377
+
)
378
+
```
379
+
380
+
### Binary Configuration Support
381
+
382
+
For non-JSON configurations (firmware files, calibration data, etc.):
383
+
384
+
```python
385
+
sdf = sdf.join_lookup(
386
+
lookup=lookup,
387
+
fields={
388
+
"firmware_binary": lookup.bytes_field(
389
+
type="firmware"
390
+
),
391
+
"calibration_data": lookup.bytes_field(
392
+
type="calibration"
393
+
)
394
+
},
395
+
on="device_id"
396
+
)
397
+
```
398
+
399
+
### How join_lookup Works with Dynamic Configuration
400
+
401
+
1.**Configuration Events**: When configurations are updated via the API, lightweight Kafka events are published to your configuration topic.
402
+
403
+
2.**Real-time Processing**: The `join_lookup` feature listens to these events, fetches the latest configuration content, and caches it locally.
404
+
405
+
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.
406
+
407
+
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.
408
+
409
+
5.**Performance Optimization**: Local caching minimizes API calls and reduces latency for high-throughput applications.
410
+
411
+
### Advanced Use Cases
412
+
413
+
#### Custom Target Key Matching
414
+
415
+
For complex matching logic that goes beyond simple field matching:
0 commit comments