Descriptor¶
A streamlet's descriptor is its declaration — name, inlets, outlets, contracts and parameters — as a
JSON file, conventionally flow/descriptor.json. The streamlet's SDK writes it at build time; it is
never written by hand. It is the protocol's discovery Spec message in canonical form, so the same
declaration produces the same bytes in every language.
It is read in three places:
flow verifyandflow generatecheck a blueprint against the descriptors of its streamlets.flow generatecopies each descriptor'sstreamletobject into theAnkkaFlowresource, and the operator mounts it into the sidecar.- The sidecar compares the process's answer to
Discoverwith the deployed descriptor'sstreamletobject, field by field, and refuses to start on any difference.
Fields¶
| field | meaning |
|---|---|
protocol_version |
MAJOR.MINOR of the streamlet protocol the SDK speaks, 1.0 |
sdk.name, sdk.version |
the SDK that wrote the file, such as ankka-flow-python |
streamlet.name |
the name a blueprint refers to |
streamlet.description |
free text |
streamlet.inlets[], streamlet.outlets[] |
ports: name and contract |
contract.format |
json, the only format |
contract.schema_name |
the contract's name, such as cart-events.v1 |
contract.fingerprint |
Base64 of the SHA-256 of the UTF-8 schema name, standard alphabet, padded |
streamlet.config_parameters[] |
parameters: key, description, type, default_value |
type |
STRING, INTEGER, DOUBLE, BOOLEAN, DURATION or MEMORY_SIZE |
default_value |
the default as text; absent when the parameter must be set at deploy time |
The fingerprint is computed from the schema's name, not from any schema content: two ports connect when their format and fingerprint are equal. See Contracts.
Canonical JSON¶
- Field names are the proto field names, in snake_case:
protocol_version,schema_name,config_parameters,default_value. - Object keys are sorted lexicographically, in byte order, at every level.
inletsandoutletsare sorted byname, andconfig_parametersbykey. Declaration order is never meaningful.- Enums are written as their names (
"INTEGER"), never as numbers. - A field at its proto3 default is omitted: an empty string,
0,false, an empty list, an unset optional field. ASTRINGparameter therefore has notypefield, and a parameter with no default has nodefault_value. - Two-space indentation,
": "and,plus newline as separators, LF line endings, UTF-8 with no byte-order mark, and exactly one trailing newline.
In Python this is
json.dumps(MessageToDict(spec, preserving_proto_field_name=True), sort_keys=True, indent=2, ensure_ascii=False) + "\n".
Example¶
The cart router's descriptor: one inlet, two outlets sharing its contract, one integer parameter.
{
"protocol_version": "1.0",
"sdk": {
"name": "fixture",
"version": "0.0.0"
},
"streamlet": {
"config_parameters": [
{
"default_value": "100",
"description": "Carts with a total above this go to the review outlet.",
"key": "review-threshold",
"type": "INTEGER"
}
],
"description": "Routes cart events to the valid or review outlet.",
"inlets": [
{
"contract": {
"fingerprint": "nXhoFwNZSB7DKScFuZUtZ1gnAYkIxadumsXNHWwbLfM=",
"format": "json",
"schema_name": "cart-events.v1"
},
"name": "in"
}
],
"name": "cart-router",
"outlets": [
{
"contract": {
"fingerprint": "nXhoFwNZSB7DKScFuZUtZ1gnAYkIxadumsXNHWwbLfM=",
"format": "json",
"schema_name": "cart-events.v1"
},
"name": "review"
},
{
"contract": {
"fingerprint": "nXhoFwNZSB7DKScFuZUtZ1gnAYkIxadumsXNHWwbLfM=",
"format": "json",
"schema_name": "cart-events.v1"
},
"name": "valid"
}
]
}
}
This is the fixture every SDK must reproduce, so its sdk block is pinned to
{"name": "fixture", "version": "0.0.0"}. A descriptor written for a real streamlet names its SDK
and version.
Validation¶
The CLI and the sidecar apply the same rules and report every problem at once:
streamlet.nameis 1 to 63 of[a-z0-9-]and does not start or end with-.- Port names match
[a-z][a-z0-9-]{0,62}and are unique across inlets and outlets together. contract.formatisjson, andcontract.fingerprintequals the fingerprint ofschema_name.- Parameter keys match
[a-z][a-z0-9-]*and are unique; adefault_valueparses as itstype, withDURATIONandMEMORY_SIZEin HOCON's duration and size syntax. protocol_versionisMAJOR.MINOR, both unsigned integers.
Fixtures¶
The repository's
protocol/fixtures/descriptors
holds the exact bytes each declaration in protocol/fixtures/declarations must produce. Every SDK
declares each streamlet in its own language and asserts that its writer produces these bytes.
| fixture | declares |
|---|---|
minimal |
one inlet, one outlet, no parameters, no description |
cart-router |
the example on this page |
every-type |
one parameter of every type, one of them required, Unicode in a description |
many-ports |
five inlets and five outlets declared out of order, to prove sorting |
sink |
inlets only, no outlets |
conformance |
the reference streamlet of the conformance suite |