diff --git a/.github/workflows/validate-participant-configs.yml b/.github/workflows/validate-participant-configs.yml new file mode 100644 index 000000000..2e93e708f --- /dev/null +++ b/.github/workflows/validate-participant-configs.yml @@ -0,0 +1,24 @@ +name: 'Validate Participant Configuration Examples' +on: + workflow_call: + + workflow_dispatch: + + push: + branches: [ 'main' ] + +jobs: + validate-participant-configs: + name: Validate participant configuration examples against JSON schema + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v6 + with: + submodules: false + - name: Install Dependencies + run: | + python3 -m pip install --quiet jsonschema pyyaml + - name: Validate participant configuration examples + run: | + python3 ./SilKit/ci/validate_participant_configs.py + shell: bash diff --git a/Demos/tools/Benchmark/DemoBenchmarkDomainSocketsOff.silkit.yaml b/Demos/tools/Benchmark/DemoBenchmarkDomainSocketsOff.silkit.yaml index 1d658fb3f..0ec4c06ad 100644 --- a/Demos/tools/Benchmark/DemoBenchmarkDomainSocketsOff.silkit.yaml +++ b/Demos/tools/Benchmark/DemoBenchmarkDomainSocketsOff.silkit.yaml @@ -4,4 +4,4 @@ Logging: - Level: Error Type: Stdout Middleware: - EnableDomainSockets: 'False' + EnableDomainSockets: false diff --git a/Demos/tools/Benchmark/DemoBenchmarkTCPNagleOff.silkit.yaml b/Demos/tools/Benchmark/DemoBenchmarkTCPNagleOff.silkit.yaml index bda0a4567..5299d6f50 100644 --- a/Demos/tools/Benchmark/DemoBenchmarkTCPNagleOff.silkit.yaml +++ b/Demos/tools/Benchmark/DemoBenchmarkTCPNagleOff.silkit.yaml @@ -4,5 +4,5 @@ Logging: - Level: Error Type: Stdout Middleware: - EnableDomainSockets: 'False' - TcpNoDelay: 'True' + EnableDomainSockets: false + TcpNoDelay: true diff --git a/SilKit/ci/validate_participant_configs.py b/SilKit/ci/validate_participant_configs.py new file mode 100644 index 000000000..a520ce3ef --- /dev/null +++ b/SilKit/ci/validate_participant_configs.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 + +# SPDX-FileCopyrightText: 2026 Vector Informatik GmbH +# +# SPDX-License-Identifier: MIT + +""" +Validate SIL Kit participant configuration example files (JSON/YAML) against +SilKit/source/config/ParticipantConfiguration.schema.json. +""" + +from pathlib import Path + +import argparse +import json +import sys + +import jsonschema +import yaml + +sys.path.insert(0, str(Path(__file__).resolve().parent)) +from ci_utils import info, warn, die + +SCRIPT_DIR = Path(__file__).resolve().parent +REPO_ROOT = SCRIPT_DIR.parents[1] +SCHEMA_PATH = REPO_ROOT / "SilKit" / "source" / "config" / "ParticipantConfiguration.schema.json" + + +def find_config_files(repo_root: Path): + config_dir = repo_root / "SilKit" / "source" / "config" + + files = [] + files += sorted(p for p in config_dir.glob("*.json") if p != SCHEMA_PATH) + files += sorted(config_dir.glob("*.yaml")) + files += sorted((repo_root / "Demos").rglob("*.silkit.yaml")) + return files + + +def load_config(path: Path): + with path.open("r", encoding="utf-8") as f: + if path.suffix == ".json": + return json.load(f) + return yaml.safe_load(f) + + +def main(): + parser = argparse.ArgumentParser( + description="Validate SIL Kit participant configuration example files against the JSON schema") + parser.add_argument( + "--root", type=Path, default=REPO_ROOT, + help="Repository root (defaults to the checkout containing this script)") + args = parser.parse_args() + + schema_path = args.root / "SilKit" / "source" / "config" / "ParticipantConfiguration.schema.json" + with schema_path.open("r", encoding="utf-8") as f: + schema = json.load(f) + + validator_cls = jsonschema.validators.validator_for(schema) + validator_cls.check_schema(schema) + validator = validator_cls(schema) + + files = find_config_files(args.root) + if not files: + die(1, "No participant configuration example files found to validate!") + + info("Validating {} participant configuration file(s) against {}", len(files), schema_path) + + failed = 0 + for path in files: + try: + instance = load_config(path) + except Exception as ex: + warn("{}: failed to parse ({})", path, ex) + failed += 1 + continue + + errors = sorted(validator.iter_errors(instance), key=lambda e: [str(p) for p in e.absolute_path]) + if errors: + failed += 1 + for error in errors: + location = "/".join(str(p) for p in error.absolute_path) or "" + warn("{}: {}: {}", path, location, error.message) + else: + info("{}: OK", path) + + if failed: + die(64, "{} of {} configuration file(s) failed schema validation!", failed, len(files)) + + info("All {} participant configuration file(s) are valid!", len(files)) + + +if __name__ == "__main__": + main() diff --git a/SilKit/source/config/ParticipantConfiguration.schema.json b/SilKit/source/config/ParticipantConfiguration.schema.json index 8b0fcd4c1..55934f103 100644 --- a/SilKit/source/config/ParticipantConfiguration.schema.json +++ b/SilKit/source/config/ParticipantConfiguration.schema.json @@ -5,58 +5,70 @@ "Description": { "type": "string", "description": "Free text commenting on or summarizing this configuration. Optional", - "default": "" + "default": "", + "examples": ["My simulation configuration"] }, "Name": { "type": "string", - "description": "Name of the endpoint" + "description": "Name of the endpoint", + "examples": ["Endpoint1"] }, "Network": { "type": "string", - "description": "Name of the network. Optional; Defaults to the endpoint name" + "description": "Name of the network. Optional; Defaults to the endpoint name", + "examples": ["Network1"] }, "UseTraceSinks": { "type": "array", - "description": "Names of trace sinks to use" + "description": "Names of trace sinks to use", + "examples": ["Sink1"] }, "Replay": { "type": "object", "properties": { "UseTraceSource": { "type": "string", - "description": "Name of a trace source used as a simulation message source for this controller" + "description": "Name of a trace source used as a simulation message source for this controller", + "examples": ["Source1"] }, "Direction": { "type": "string", "description": "Filter messages to use from the trace source by their direction. May be Send, Receive or Both", - "enum": [ "Send", "Receive", "Both" ] + "enum": ["Send", "Receive", "Both"], + "examples": ["Send", "Receive", "Both"] }, "MdfChannel": { "type": "object", "properties": { "ChannelName": { "type": "string", - "description": "Name of an MDF channel in the trace source" + "description": "Name of an MDF channel in the trace source", + "examples": ["MyTestChannel1"] }, "ChannelSource": { "type": "string", - "description": "Name of an MDF channel's source information object" + "description": "Name of an MDF channel's source information object", + "examples": ["path/to/myTestChannel1"] }, "ChannelPath": { "type": "string", - "description": "Path of an MDF channel's source information object" + "description": "Path of an MDF channel's source information object", + "examples": ["MyTestChannel"] }, "GroupName": { "type": "string", - "description": "Name of an MDF channel group" + "description": "Name of an MDF channel group", + "examples": ["MyTestGroup"] }, "GroupSource": { "type": "string", - "description": "Name of an MDF channel group's source information object" + "description": "Name of an MDF channel group's source information object", + "examples": ["path/to/myTestGroup1"] }, "GroupPath": { "type": "string", - "description": "Path of an MDF channel group's source information object" + "description": "Path of an MDF channel group's source information object", + "examples": ["MyTestGroup"] } } } @@ -69,121 +81,141 @@ "type": "integer", "minimum": 2, "maximum": 31, - "description": "Number of attempts for a cold start before giving up (range 2-31)" + "description": "Number of attempts for a cold start before giving up (range 2-31)", + "examples": [8] }, "gCycleCountMax": { "type": "integer", "minimum": 7, "maximum": 63, - "description": "Max cycle count value in a given cluster (range 7-63, must be an odd integer)" + "description": "Max cycle count value in a given cluster (range 7-63, must be an odd integer)", + "examples": [63] }, "gdActionPointOffset": { "type": "integer", "minimum": 1, "maximum": 63, - "description": "Time offset for a static slot in macroticks (range 1 - 63)" + "description": "Time offset for a static slot in macroticks (range 1 - 63)", + "examples": [2] }, "gdDynamicSlotIdlePhase": { "type": "integer", "minimum": 0, "maximum": 2, - "description": "Duration of the idle phase within a dynamic slot in gdMiniSlots (range 0 - 2)" + "description": "Duration of the idle phase within a dynamic slot in gdMiniSlots (range 0 - 2)", + "examples": [1] }, "gdMiniSlot": { "type": "integer", "minimum": 2, "maximum": 63, - "description": "Duration of a mini slot in macroticks (2 - 63)" + "description": "Duration of a mini slot in macroticks (2 - 63)", + "examples": [5] }, "gdMiniSlotActionPointOffset": { "type": "integer", "minimum": 1, "maximum": 31, - "description": "Time offset for a mini slot in macroticks (range 1- 31)" + "description": "Time offset for a mini slot in macroticks (range 1- 31)", + "examples": [2] }, "gdStaticSlot": { "type": "integer", "minimum": 3, "maximum": 664, - "description": "Duration of a static slot in macroticks (range 3 - 664)" + "description": "Duration of a static slot in macroticks (range 3 - 664)", + "examples": [31] }, "gdSymbolWindow": { "type": "integer", "minimum": 0, "maximum": 162, - "description": "Duration of the symbol window in macroticks (range 0 - 162)" + "description": "Duration of the symbol window in macroticks (range 0 - 162)", + "examples": [1] }, "gdSymbolWindowActionPointOffset": { "type": "integer", "minimum": 1, "maximum": 63, - "description": "Time offset for a static symbol windows in macroticks (range 1 - 63)" + "description": "Time offset for a static symbol windows in macroticks (range 1 - 63)", + "examples": [1] }, "gdTSSTransmitter": { "type": "integer", "minimum": 1, "maximum": 15, - "description": "Duration of TSS (Transmission Start Sequence) in gdBits (range 1 - 15)" + "description": "Duration of TSS (Transmission Start Sequence) in gdBits (range 1 - 15)", + "examples": [9] }, "gdWakeupTxActive": { "type": "integer", "minimum": 15, "maximum": 60, - "description": "Duration of LOW Phase of a wakeup symbol in gdBit (range 15 - 60)" + "description": "Duration of LOW Phase of a wakeup symbol in gdBit (range 15 - 60)", + "examples": [60] }, "gdWakeupTxIdle": { "type": "integer", "minimum": 45, "maximum": 180, - "description": "Duration of the idle of a wakeup symbol in gdBit (45 - 180)" + "description": "Duration of the idle of a wakeup symbol in gdBit (45 - 180)", + "examples": [180] }, "gListenNoise": { "type": "integer", "minimum": 2, "maximum": 16, - "description": "Upper limit for the startup listen timeout and wakeup listen timeout in the presence of noise; Used as a multiplier of pdListenTimeout (range 2 - 16)" + "description": "Upper limit for the startup listen timeout and wakeup listen timeout in the presence of noise; Used as a multiplier of pdListenTimeout (range 2 - 16)", + "examples": [2] }, "gMacroPerCycle": { "type": "integer", "minimum": 8, "maximum": 16000, - "description": "Number of macroticks per cycle (range 8 - 16000)" + "description": "Number of macroticks per cycle (range 8 - 16000)", + "examples": [3636] }, "gMaxWithoutClockCorrectionFatal": { "type": "integer", "minimum": 1, "maximum": 15, - "description": "Threshold used for testing the vClockCorrectionFailed counter (range 1 - 15)" + "description": "Threshold used for testing the vClockCorrectionFailed counter (range 1 - 15)", + "examples": [2] }, "gMaxWithoutClockCorrectionPassive": { "type": "integer", "minimum": 1, "maximum": 15, - "description": "Threshold used for testing the vClockCorrectionFailed counter (range 1 - 15)" + "description": "Threshold used for testing the vClockCorrectionFailed counter (range 1 - 15)", + "examples": [2] }, "gNumberOfMiniSlots": { "type": "integer", "minimum": 0, "maximum": 7988, - "description": "Number of mini slots (range 0 - 7988)" + "description": "Number of mini slots (range 0 - 7988)", + "examples": [291] }, "gNumberOfStaticSlots": { "type": "integer", "minimum": 2, "maximum": 1023, - "description": "Number of static slots in a cycle (range 2 - 1023)" + "description": "Number of static slots in a cycle (range 2 - 1023)", + "examples": [70] }, "gPayloadLengthStatic": { "type": "integer", "minimum": 0, "maximum": 127, - "description": "Length of the payload of a static frame in 16-Bits words (range 0 - 127)" + "description": "Length of the payload of a static frame in 16-Bits words (range 0 - 127)", + "examples": [16] }, "gSyncFrameIDCountMax": { "type": "integer", "minimum": 2, "maximum": 15, - "description": "Maximum number of distinct sync frame identifiers present in a given cluster (range 2 - 15)" + "description": "Maximum number of distinct sync frame identifiers present in a given cluster (range 2 - 15)", + "examples": [15] } } }, @@ -194,136 +226,173 @@ "type": "integer", "minimum": 0, "maximum": 1, - "description": "Controls the transition to halt state due to clock synchronization errors. (values 0, 1)" + "description": "Controls the transition to halt state due to clock synchronization errors. (values 0, 1)", + "examples": [1] }, "pAllowPassiveToActive": { "type": "integer", "minimum": 0, "maximum": 31, - "description": "Required number of consecutive even / odd cycle pairs for normal passive to normal active (range 0 - 31)" + "description": "Required number of consecutive even / odd cycle pairs for normal passive to normal active (range 0 - 31)", + "examples": [0] }, "pChannels": { "type": "string", - "enum": [ "A", "B", "AB", "None" ], - "description": "Channel(s) to which the controller is connected" + "enum": ["A", "B", "AB", "None"], + "description": "Channel(s) to which the controller is connected", + "examples": ["AB"] }, "pClusterDriftDamping": { "type": "integer", "minimum": 0, "maximum": 10, - "description": "Cluster drift damping factor for rate correction in microticks (range 0 - 10)" + "description": "Cluster drift damping factor for rate correction in microticks (range 0 - 10)", + "examples": [2] }, "pdAcceptedStartupRange": { "type": "integer", "minimum": 29, "maximum": 2743, - "description": "Allowed deviation for startup frames during integration in microticks (range 29 - 2743)" + "description": "Allowed deviation for startup frames during integration in microticks (range 29 - 2743)", + "examples": [212] }, "pdListenTimeout": { "type": "integer", "minimum": 1926, "maximum": 2567692, - "description": "Duration of listen phase in microticks (range 1926 - 2567692)" + "description": "Duration of listen phase in microticks (range 1926 - 2567692)", + "examples": [400162] }, "pKeySlotId": { "type": "integer", "minimum": 0, "maximum": 1023, - "description": "Slot ID of the key slot (range 0 - 1023; value 0 means that there is no key slot)" + "description": "Slot ID of the key slot (range 0 - 1023; value 0 means that there is no key slot)", + "examples": [10] }, "pKeySlotOnlyEnabled": { "type": "integer", "minimum": 0, "maximum": 1, - "description": "Shall the node enter key slot only mode after startup. (values 0, 1) (AUTOSAR pSingleSlotEnabled)" + "description": "Shall the node enter key slot only mode after startup. (values 0, 1) (AUTOSAR pSingleSlotEnabled)", + "examples": [0] }, "pKeySlotUsedForStartup": { "type": "integer", "minimum": 0, "maximum": 1, - "description": "Key slot is used for startup (values 0, 1)" + "description": "Key slot is used for startup (values 0, 1)", + "examples": [1] }, "pKeySlotUsedForSync": { "type": "integer", "minimum": 0, "maximum": 1, - "description": "Key slot is used for sync (values 0, 1)" + "description": "Key slot is used for sync (values 0, 1)", + "examples": [0] }, "pLatestTx": { "type": "integer", "minimum": 0, "maximum": 7988, - "description": "Last mini slot which can be transmitted (range 0 - 7988)" + "description": "Last mini slot which can be transmitted (range 0 - 7988)", + "examples": [249] }, "pMacroInitialOffsetA": { "type": "integer", "minimum": 2, "maximum": 68, - "description": "Initial startup offset for frame reference point on channel A (range 2 - 68 macroticks)" + "description": "Initial startup offset for frame reference point on channel A (range 2 - 68 macroticks)", + "examples": [3] }, "pMacroInitialOffsetB": { "type": "integer", "minimum": 2, "maximum": 68, - "description": "Initial startup offset for frame reference point on channel B (range 2 - 68 macroticks)" + "description": "Initial startup offset for frame reference point on channel B (range 2 - 68 macroticks)", + "examples": [3] }, "pMicroInitialOffsetA": { "type": "integer", "minimum": 0, "maximum": 239, - "description": "Offset between secondary time reference and MT boundary (range 0 - 239 microticks)" + "description": "Offset between secondary time reference and MT boundary (range 0 - 239 microticks)", + "examples": [6] }, "pMicroInitialOffsetB": { "type": "integer", "minimum": 0, "maximum": 239, - "description": "Offset between secondary time reference and MT boundary (range 0 - 239 microticks)" + "description": "Offset between secondary time reference and MT boundary (range 0 - 239 microticks)", + "examples": [6] }, "pMicroPerCycle": { "type": "integer", "minimum": 960, "maximum": 1280000, - "description": "Nominal number of microticks in the communication cycle (range 960 - 1280000)" + "description": "Nominal number of microticks in the communication cycle (range 960 - 1280000)", + "examples": [200000] }, "pOffsetCorrectionOut": { "type": "integer", "minimum": 15, "maximum": 16082, - "description": "Maximum permissible offset correction value (range 15 - 16082 microticks)" + "description": "Maximum permissible offset correction value (range 15 - 16082 microticks)", + "examples": [127] }, "pOffsetCorrectionStart": { "type": "integer", "minimum": 7, "maximum": 15999, - "description": "Start of the offset correction phase within the NIT, (7 - 15999 macroticks)" + "description": "Start of the offset correction phase within the NIT, (7 - 15999 macroticks)", + "examples": [3632] }, "pRateCorrectionOut": { "type": "integer", "minimum": 3, "maximum": 3846, - "description": "Maximum permissible rate correction value (range 3 - 3846 microticks)" + "description": "Maximum permissible rate correction value (range 3 - 3846 microticks)", + "examples": [81] }, "pWakeupChannel": { "type": "string", - "enum": [ "A", "B" ], - "description": "Channel used by the node to send a wakeup pattern" + "enum": ["A", "B"], + "description": "Channel used by the node to send a wakeup pattern", + "examples": ["A"] }, "pWakeupPattern": { "type": "integer", "minimum": 0, "maximum": 63, - "description": "Number of repetitions of the wakeup symbol (range 0 - 63, value 0 or 1 prevents sending of WUP)" + "description": "Number of repetitions of the wakeup symbol (range 0 - 63, value 0 or 1 prevents sending of WUP)", + "examples": [33] }, "pdMicrotick": { "type": "string", - "enum": [ "12.5ns", "25ns", "50ns" ], - "description": "Duration of a FlexRay microtick" + "enum": ["12.5ns", "25ns", "50ns"], + "description": "Duration of a FlexRay microtick", + "examples": ["25ns"] }, "pSamplesPerMicrotick": { "type": "integer", "minimum": 1, "maximum": 2, - "description": "Number of samples per microtick (values 1, 2)" + "description": "Number of samples per microtick (values 1, 2)", + "examples": [2] + }, + "pSecondKeySlotId": { + "type": "integer", + "minimum": 0, + "maximum": 1023, + "description": "Second Key Slot ID of the key slot (range 0-1023, value 0 means that there is no key slot)", + "examples": [0] + }, + "pTwoKeySlotMode": { + "type": "integer", + "minimum": 0, + "maximum": 1, + "description": "Second Key slot is used for startup with a single cold start node (range 0, 1)", + "examples": [0] } } }, @@ -334,39 +403,46 @@ "properties": { "channels": { "type": "string", - "enum": [ "A", "B", "AB", "None" ], - "description": "Channel(s)" + "enum": ["A", "B", "AB", "None"], + "description": "Channel(s)", + "examples": ["A"] }, "slotId": { "type": "integer", "minimum": 0, "maximum": 65535, - "description": "The slot Id of frame" + "description": "The slot Id of frame", + "examples": [0] }, "offset": { "type": "integer", "minimum": 0, "maximum": 63, - "description": "Base offset for cycle multiplexing (values 0 - 63)" + "description": "Base offset for cycle multiplexing (values 0 - 63)", + "examples": [0] }, "repetition": { "type": "integer", "minimum": 0, "maximum": 64, - "description": "Repetition for cycle multiplexing (values 1, 2, 4, 8, 16, 32, 64)" + "description": "Repetition for cycle multiplexing (values 1, 2, 4, 8, 16, 32, 64)", + "examples": [0] }, "PPindicator": { "type": "boolean", - "description": "Set the PPindicator" + "description": "Set the PPindicator", + "examples": [false] }, "headerCrc": { "type": "integer", - "description": "Header CRC, 11 bits" + "description": "Header CRC, 11 bits", + "examples": [0] }, "transmissionMode": { "type": "string", - "enum": [ "SingleShot", "Continuous" ], - "description": "SingleShot or Continuous transmission mode" + "enum": ["SingleShot", "Continuous"], + "description": "SingleShot or Continuous transmission mode", + "examples": ["Continuous"] } } } @@ -375,10 +451,12 @@ "type": "object", "properties": { "Name": { - "$ref": "#/definitions/Name" + "$ref": "#/definitions/Name", + "examples": ["FlexRay1"] }, "Network": { - "$ref": "#/definitions/Network" + "$ref": "#/definitions/Network", + "examples": ["FlexRay1"] }, "UseTraceSinks": { "$ref": "#/definitions/UseTraceSinks" @@ -397,7 +475,7 @@ } }, "additionalProperties": false, - "required": [ "Name" ] + "required": ["Name"] }, "FlexrayControllers": { "type": "array", @@ -408,27 +486,32 @@ }, "Topic": { "type": "string", - "description": "Name of the communication channel between DataPublisher and DataSubscribers" + "description": "Name of the communication channel between DataPublisher and DataSubscribers", + "examples": ["Temperature"] }, "RpcFunctionName": { "type": "string", - "description": "Name of the RPC function called by RpcClients on RpcServers" + "description": "Name of the RPC function called by RpcClients on RpcServers", + "examples": ["Function1"] }, "MatchingLabel": { "type": "object", "properties": { "Key": { "type": "string", - "description": "Label key" + "description": "Label key", + "examples": ["Instance"] }, "Value": { "type": "string", - "description": "Label value" + "description": "Label value", + "examples": ["Vehicle1"] }, "Kind": { "type": "string", "description": "Label kind", - "enum": ["Mandatory", "Optional"] + "enum": ["Mandatory", "Optional"], + "examples": ["Mandatory", "Optional"] } } }, @@ -443,7 +526,38 @@ "type": "integer", "description": "Override the history length (must be `0` or `1`)", "minimum": 0, - "maximum": 1 + "maximum": 1, + "examples": [1] + }, + "LoggingTopic": { + "type": "string", + "description": "Name of a logging topic used to filter log messages", + "examples": ["User"], + "enum": [ + "None", + "User", + "LifeCycle", + "SystemState", + "MessageTracing", + "ServiceDiscovery", + "Asio", + "TimeSync", + "Participant", + "TimeConfig", + "RequestReply", + "SystemMonitor", + "Can", + "Ethernet", + "Flexray", + "Lin", + "Metrics", + "Pubsub", + "Rpc", + "Tracing", + "Dashboard", + "NetSim", + "Extension" + ] }, "Logging": { "type": "object", @@ -452,11 +566,21 @@ "LogFromRemotes": { "type": "boolean", "description": "Enables receiving of remote log messages from other participants", - "default": false + "default": false, + "examples": [false, true] }, "FlushLevel": { "type": "string", - "enum": [ "Critical", "Error", "Warn", "Info", "Debug", "Trace", "Off" ] + "enum": ["Critical", "Error", "Warn", "Info", "Debug", "Trace", "Off"], + "examples": [ + "Critical", + "Error", + "Warn", + "Info", + "Debug", + "Trace", + "Off" + ] }, "Sinks": { "type": "array", @@ -465,23 +589,14 @@ "properties": { "Type": { "type": "string", - "enum": [ "Remote", "File", "Stdout" ] + "enum": ["Remote", "File", "Stdout"], + "examples": ["Remote", "File", "Stdout"] }, "Format": { "type": "string", - "enum": [ "Simple", "Json" ] - }, - "DisabledTopics": { - "type": "array", - "items": { - "type": "string" - } - }, - "EnabledTopics": { - "type": "array", - "items": { - "type": "string" - } + "enum": ["Simple", "Json"], + "default": "Simple", + "examples": ["Simple", "Json"] }, "Level": { "type": "string", @@ -494,20 +609,97 @@ "Trace", "Off" ], + "examples": [ + "Critical", + "Error", + "Warn", + "Info", + "Debug", + "Trace", + "Off" + ], "default": "Info" }, "LogName": { "type": "string", - "description": "Log name; Results in the following filename: _%y-%m-%dT%h-%m-%s.txt" + "description": "Log name; Results in the following filename: _%y-%m-%dT%h-%m-%s.txt", + "examples": ["MyLog1"] + }, + "Experimental": { + "type": "object", + "description": "Experimental settings to filter log messages of this sink by topic", + "properties": { + "EnabledTopics": { + "type": "array", + "description": "Only log messages of these topics are passed to this sink. Optional; if empty, all topics except those in DisabledTopics are passed", + "items": { + "$ref": "#/definitions/LoggingTopic" + }, + "examples": ["User", "LifeCycle"] + }, + "DisabledTopics": { + "type": "array", + "description": "Log messages of these topics are not passed to this sink", + "items": { + "$ref": "#/definitions/LoggingTopic" + }, + "examples": ["Asio", "MessageTracing"] + } + }, + "additionalProperties": false } }, "additionalProperties": false, - "required": [ "Type" ] + "required": ["Type"] } } }, "additionalProperties": false, - "required": [ "Sinks" ] + "required": ["Sinks"] + }, + "MetricsSink": { + "type": "object", + "description": "Configures a sink to which collected metrics are written", + "properties": { + "Type": { + "type": "string", + "enum": ["JsonFile", "Remote"], + "description": "Type of the metrics sink", + "examples": ["JsonFile", "Remote"] + }, + "Name": { + "type": "string", + "description": "Name of the metrics sink; used e.g. as the output file name for a JsonFile sink", + "examples": ["MyMetrics1"] + } + }, + "additionalProperties": false, + "required": ["Type"] + }, + "Metrics": { + "type": "object", + "description": "Configures the collection and publication of participant metrics", + "properties": { + "Sinks": { + "type": "array", + "description": "Sinks to which collected metrics are written", + "items": { + "$ref": "#/definitions/MetricsSink" + } + }, + "CollectFromRemote": { + "type": "boolean", + "description": "Enables collecting metrics from other participants. Cannot be combined with a 'Remote' metrics sink", + "examples": [true] + }, + "UpdateInterval": { + "type": "integer", + "description": "Interval in seconds at which metrics are updated", + "default": 1, + "examples": [1] + } + }, + "additionalProperties": false } }, "description": "JSON schema for SIL Kit Participant configuration files", @@ -516,22 +708,25 @@ "type": "string", "description": "The schema file", "default": "", - "examples": [ "./ParticipantConfiguration.schema.json" ] + "examples": ["./ParticipantConfiguration.schema.json"] }, "SchemaVersion": { - "anyOf": [ - { "type": "integer" }, - { "type": "string" } - ], + "enum": [ 1, "1" ], + "description": "Version of the schema used to validate this document", + "examples": [ "1" ] + }, + "schemaVersion": { + "enum": [ 1, "1" ], "default": 0, - "description": "Version of the schema used to validate this document" + "description": "Legacy lowercase alias for SchemaVersion, kept for backwards compatibility. Prefer 'SchemaVersion'" }, "Description": { "$ref": "#/definitions/Description" }, "ParticipantName": { "type": "string", - "description": "Name of the participant" + "description": "Name of the participant", + "examples": ["Participant1"] }, "CanControllers": { "type": "array", @@ -540,10 +735,12 @@ "type": "object", "properties": { "Name": { - "$ref": "#/definitions/Name" + "$ref": "#/definitions/Name", + "examples": ["CAN1"] }, "Network": { - "$ref": "#/definitions/Network" + "$ref": "#/definitions/Network", + "examples": ["CAN1"] }, "UseTraceSinks": { "$ref": "#/definitions/UseTraceSinks" @@ -553,7 +750,7 @@ } }, "additionalProperties": false, - "required": [ "Name" ] + "required": ["Name"] } }, "LinControllers": { @@ -563,10 +760,12 @@ "type": "object", "properties": { "Name": { - "$ref": "#/definitions/Name" + "$ref": "#/definitions/Name", + "examples": ["LIN1"] }, "Network": { - "$ref": "#/definitions/Network" + "$ref": "#/definitions/Network", + "examples": ["LIN1"] }, "UseTraceSinks": { "$ref": "#/definitions/UseTraceSinks" @@ -576,7 +775,7 @@ } }, "additionalProperties": false, - "required": [ "Name" ] + "required": ["Name"] } }, "FlexrayControllers": { @@ -589,10 +788,12 @@ "type": "object", "properties": { "Name": { - "$ref": "#/definitions/Name" + "$ref": "#/definitions/Name", + "examples": ["ETH0"] }, "Network": { - "$ref": "#/definitions/Network" + "$ref": "#/definitions/Network", + "examples": ["ETH0"] }, "UseTraceSinks": { "$ref": "#/definitions/UseTraceSinks" @@ -602,7 +803,7 @@ } }, "additionalProperties": false, - "required": [ "Name" ] + "required": ["Name"] } }, "DataPublishers": { @@ -612,20 +813,29 @@ "type": "object", "properties": { "Name": { - "$ref": "#/definitions/Name" + "$ref": "#/definitions/Name", + "examples": ["Publisher1"] }, "Topic": { - "$ref": "#/definitions/Topic" + "$ref": "#/definitions/Topic", + "examples": ["Temperature"] }, "Labels": { "$ref": "#/definitions/Labels" }, "History": { "$ref": "#/definitions/History" + }, + "UseTraceSinks": { + "$ref": "#/definitions/UseTraceSinks", + "examples": ["Sink1"] + }, + "Replay": { + "$ref": "#/definitions/Replay" } }, "additionalProperties": false, - "required": [ "Name" ] + "required": ["Name"] } }, "DataSubscribers": { @@ -635,17 +845,26 @@ "type": "object", "properties": { "Name": { - "$ref": "#/definitions/Name" + "$ref": "#/definitions/Name", + "examples": ["Subscriber1"] }, "Topic": { - "$ref": "#/definitions/Topic" + "$ref": "#/definitions/Topic", + "examples": ["Temperature"] }, "Labels": { "$ref": "#/definitions/Labels" + }, + "UseTraceSinks": { + "$ref": "#/definitions/UseTraceSinks", + "examples": ["Sink1"] + }, + "Replay": { + "$ref": "#/definitions/Replay" } }, "additionalProperties": false, - "required": [ "Name" ] + "required": ["Name"] } }, "RpcClients": { @@ -655,17 +874,25 @@ "type": "object", "properties": { "Name": { - "$ref": "#/definitions/Name" + "$ref": "#/definitions/Name", + "examples": ["Client1"] }, "FunctionName": { - "$ref": "#/definitions/RpcFunctionName" + "$ref": "#/definitions/RpcFunctionName", + "examples": ["Function1"] }, "Labels": { "$ref": "#/definitions/Labels" + }, + "UseTraceSinks": { + "$ref": "#/definitions/UseTraceSinks" + }, + "Replay": { + "$ref": "#/definitions/Replay" } }, "additionalProperties": false, - "required": [ "Name" ] + "required": ["Name"] } }, "RpcServers": { @@ -675,17 +902,25 @@ "type": "object", "properties": { "Name": { - "$ref": "#/definitions/Name" + "$ref": "#/definitions/Name", + "examples": ["Server1"] }, "FunctionName": { - "$ref": "#/definitions/RpcFunctionName" + "$ref": "#/definitions/RpcFunctionName", + "examples": ["Function1"] }, "Labels": { "$ref": "#/definitions/Labels" + }, + "UseTraceSinks": { + "$ref": "#/definitions/UseTraceSinks" + }, + "Replay": { + "$ref": "#/definitions/Replay" } }, "additionalProperties": false, - "required": [ "Name" ] + "required": ["Name"] } }, "Logging": { @@ -697,11 +932,13 @@ "properties": { "SoftResponseTimeout": { "type": "integer", - "description": "If a simulation step is not finished before this limit, a warning is logged. Optional; Unit is in milliseconds" + "description": "If a simulation step is not finished before this limit, a warning is logged. Optional; Unit is in milliseconds", + "examples": [500] }, "HardResponseTimeout": { "type": "integer", - "description": "If a simulation step is not finished before this limit, the participant enters error state. Optional; Unit is in milliseconds" + "description": "If a simulation step is not finished before this limit, the participant enters error state. Optional; Unit is in milliseconds", + "examples": [5000] } }, "additionalProperties": false @@ -717,16 +954,19 @@ "properties": { "Name": { "type": "string", - "description": "Name of the trace sink" + "description": "Name of the trace sink", + "examples": ["SomeTraceSink"] }, "OutputPath": { "type": "string", - "description": "File path of output file" + "description": "File path of output file", + "examples": ["path/to/Output1.mf4"] }, "Type": { "type": "string", - "enum": [ "PcapFile", "PcapPipe", "Mdf4File" ], - "description": "File format specifier" + "enum": ["PcapFile", "PcapPipe", "Mdf4File"], + "description": "File format specifier", + "examples": ["PcapFile", "PcapPipe", "Mdf4File"] } }, "additionalProperties": false @@ -740,16 +980,18 @@ "Name": { "type": "string", "description": "Name of the trace source", - "examples": [ "SomeTraceSource" ] + "examples": ["SomeTraceSource"] }, "InputPath": { "type": "string", - "description": "File path of input file" + "description": "File path of input file", + "examples": ["path/to/Source1.mf4"] }, "Type": { "type": "string", - "enum": [ "PcapFile", "PcapPipe", "Mdf4File" ], - "description": "File format specifier" + "enum": ["PcapFile", "PcapPipe", "Mdf4File"], + "description": "File format specifier", + "examples": ["PcapFile", "PcapPipe", "Mdf4File"] } }, "additionalProperties": false @@ -766,7 +1008,8 @@ "items": { "type": "string", "description": "A filesystem path to additionally search for extensions" - } + }, + "examples": ["path/to/extensions1", "path/to/extensions2"] } }, "additionalProperties": false @@ -780,7 +1023,7 @@ "items": { "type": "string", "description": "A filesystem path to additionally search for files to be included", - "examples": [ "/urs/etc/sil-kit-configs/", "C:\\Temp\\sil-kit-configs\\" ] + "examples": ["/urs/etc/sil-kit-configs/", "C:\\Temp\\sil-kit-configs\\"] } }, "Files": { @@ -788,7 +1031,7 @@ "items": { "type": "string", "description": "Participant configuration files to be included", - "examples": [ "relative/path/to/included.silkit.yaml", "logging.silkit.yaml" ] + "examples": ["relative/path/to/included.silkit.yaml", "logging.silkit.yaml"] } } } @@ -799,34 +1042,62 @@ "properties": { "RegistryUri": { "type": "string", - "default": "silkit://localhost:8500" + "default": "silkit://localhost:8500", + "examples": ["silkit://0.0.0.0:8501", "silkit://localhost:8500"] }, "ConnectAttempts": { "type": "integer", - "default": "1" + "default": 1, + "examples": [1] }, "TcpNoDelay": { "type": "boolean", - "default": true + "default": true, + "examples": [true] }, "TcpQuickAck": { "type": "boolean", - "default": false + "default": false, + "examples": [false] }, "TcpSendBufferSize": { - "type": "integer" + "type": "integer", + "examples": [3456] }, "TcpReceiveBufferSize": { - "type": "integer" + "type": "integer", + "examples": [3456] }, "EnableDomainSockets": { "type": "boolean", - "default": true + "default": true, + "examples": [true] + }, + "AcceptorUris": { + "type": "array", + "description": "Explicit list of endpoints this participant will accept connections on", + "items": { + "type": "string" + }, + "examples": ["silkit://localhost:0"] + }, + "RegistryAsFallbackProxy": { + "type": "boolean", + "description": "Enables communication with other participants using the registry as a proxy", + "default": true, + "examples": [true] }, "ConnectTimeoutSeconds": { "type": "number", "minimum": 0.0, - "default": 5.0 + "default": 5.0, + "examples": [5.0] + }, + "ExperimentalRemoteParticipantConnection": { + "type": "boolean", + "description": "By default, requesting connection of other participants, and honoring these requests by other participants is enabled", + "default": true, + "examples": [true] } }, "additionalProperties": false @@ -843,20 +1114,32 @@ "type": "number", "description": "The animation factor describes how fast the simulation is allowed to run, relative to the local wall clock. For example, if the value is 0.1, SIL Kit will try to run the simulation 10 times faster than the wall clock. The default value 0.0 runs the simulation as fast as possible, i.e., the current behavior.", "minimum": 0.0, - "default": 0.0 + "default": 0.0, + "examples": [0.1] }, "EnableMessageAggregation": { "type": "string", - "enum": [ "Off", "On", "Auto" ], + "enum": ["Off", "On", "Auto"], "description": "Decide for simulations with time synchronization, if a message aggregation is performed. In case of the Auto mode, the message aggregation is enabled for simulations using the synchronous simulation step handler.", - "default": "Off" + "default": "Off", + "examples": ["Off", "On", "Auto"] } }, "additionalProperties": false + }, + "Metrics": { + "$ref": "#/definitions/Metrics" } }, "additionalProperties": false } }, + "not": { + "properties": { + "SchemaVersion": { "$ref": "#/properties/SchemaVersion" }, + "schemaVersion": { "$ref": "#/properties/schemaVersion" } + }, + "required": ["SchemaVersion", "schemaVersion"] + }, "type": "object" } diff --git a/SilKit/source/config/ParticipantConfiguration_Full.json b/SilKit/source/config/ParticipantConfiguration_Full.json index 6f04a8ed1..126ad7527 100644 --- a/SilKit/source/config/ParticipantConfiguration_Full.json +++ b/SilKit/source/config/ParticipantConfiguration_Full.json @@ -117,7 +117,7 @@ "pdAcceptedStartupRange": 212, "pdListenTimeout": 400162, "pdMicrotick": "25ns", - "pSecondKeySlotId": 1337, + "pSecondKeySlotId": 11, "pTwoKeySlotMode": 1 }, "TxBufferConfigurations": [ @@ -217,8 +217,13 @@ "Sinks": [ { "Type": "File", + "Format": "Simple", "Level": "Critical", - "LogName": "MyLog1" + "LogName": "MyLog1", + "Experimental": { + "EnabledTopics": [ "Can" ], + "DisabledTopics": [ "MessageTracing", "Flexray" ] + } } ], "FlushLevel": "Critical", @@ -258,13 +263,17 @@ "EnableDomainSockets": false, "TcpSendBufferSize": 3456, "TcpReceiveBufferSize": 3456, + "AcceptorUris": [ + "tcp://0.0.0.0:0" + ], "RegistryAsFallbackProxy": false, - "ConnectTimeoutSeconds": 1.234 + "ConnectTimeoutSeconds": 1.234, + "ExperimentalRemoteParticipantConnection": false }, "Experimental": { "TimeSynchronization": { "AnimationFactor": 1.5, - "EnableMessageAggregation": "Off" + "EnableMessageAggregation": "Off" }, "Metrics": { "CollectFromRemote": false, diff --git a/SilKit/source/config/ParticipantConfiguration_Full.yaml b/SilKit/source/config/ParticipantConfiguration_Full.yaml index 4c08d28a3..754e92970 100644 --- a/SilKit/source/config/ParticipantConfiguration_Full.yaml +++ b/SilKit/source/config/ParticipantConfiguration_Full.yaml @@ -89,7 +89,7 @@ FlexrayControllers: pOffsetCorrectionStart: 3632 pRateCorrectionOut: 81 pSamplesPerMicrotick: 2 - pSecondKeySlotId: 1337 + pSecondKeySlotId: 11 pTwoKeySlotMode: 1 pWakeupChannel: A pWakeupPattern: 33 @@ -157,8 +157,12 @@ RpcClients: Logging: Sinks: - Type: File + Format: Simple Level: Critical LogName: MyLog1 + Experimental: + EnabledTopics: [Can] + DisabledTopics: [MessageTracing, Flexray] FlushLevel: Critical LogFromRemotes: false HealthCheck: @@ -185,12 +189,15 @@ Middleware: EnableDomainSockets: false TcpSendBufferSize: 3456 TcpReceiveBufferSize: 3456 + AcceptorUris: + - silkit://localhost:0 RegistryAsFallbackProxy: false ConnectTimeoutSeconds: 1.234 + ExperimentalRemoteParticipantConnection: false Experimental: TimeSynchronization: AnimationFactor: 1.5 - EnableMessageAggregation: Off + EnableMessageAggregation: 'Off' Metrics: CollectFromRemote: false Sinks: diff --git a/SilKit/source/config/TestParticipantConfigs/AdditionalSubIncludes.yaml b/SilKit/source/config/TestParticipantConfigs/AdditionalSubIncludes.yaml index 6733fbcb0..993facbcc 100644 --- a/SilKit/source/config/TestParticipantConfigs/AdditionalSubIncludes.yaml +++ b/SilKit/source/config/TestParticipantConfigs/AdditionalSubIncludes.yaml @@ -1,6 +1,6 @@ --- Description: Additional Subs -schemaVersion: 1 +SchemaVersion: 1 DataSubscribers: - Name: Subscriber1 Topic: Temperature diff --git a/SilKit/source/config/TestParticipantConfigs/CanInclude2.yaml b/SilKit/source/config/TestParticipantConfigs/CanInclude2.yaml index 553824063..a4a236c9d 100644 --- a/SilKit/source/config/TestParticipantConfigs/CanInclude2.yaml +++ b/SilKit/source/config/TestParticipantConfigs/CanInclude2.yaml @@ -1,3 +1,3 @@ --- Description: Example include configuration for CAN Controllers -schemaVersion: 1 +SchemaVersion: 1 diff --git a/SilKit/source/config/TestParticipantConfigs/DuplicateEthernetControllerNames.yaml b/SilKit/source/config/TestParticipantConfigs/DuplicateEthernetControllerNames.yaml index 304a1ec92..833ba6442 100644 --- a/SilKit/source/config/TestParticipantConfigs/DuplicateEthernetControllerNames.yaml +++ b/SilKit/source/config/TestParticipantConfigs/DuplicateEthernetControllerNames.yaml @@ -1,6 +1,6 @@ --- Description: Example configuration EthernetControllers with name -schemaVersion: 1 +SchemaVersion: 1 EthernetControllers: - Name: ETH0 Replay: diff --git a/SilKit/source/config/TestParticipantConfigs/MiddlewareInclude.yaml b/SilKit/source/config/TestParticipantConfigs/MiddlewareInclude.yaml index f686a3f0b..b04f6d890 100644 --- a/SilKit/source/config/TestParticipantConfigs/MiddlewareInclude.yaml +++ b/SilKit/source/config/TestParticipantConfigs/MiddlewareInclude.yaml @@ -1,6 +1,6 @@ --- Description: Example Middleware config include to test YAML Parser -schemaVersion: 1 +SchemaVersion: 1 Includes: Files: - MoreMiddlewareIncludes.yaml diff --git a/SilKit/source/config/TestParticipantConfigs/MoreMiddlewareIncludes.yaml b/SilKit/source/config/TestParticipantConfigs/MoreMiddlewareIncludes.yaml index 6ee12c1ae..e3d645810 100644 --- a/SilKit/source/config/TestParticipantConfigs/MoreMiddlewareIncludes.yaml +++ b/SilKit/source/config/TestParticipantConfigs/MoreMiddlewareIncludes.yaml @@ -1,6 +1,6 @@ --- Description: Example Middleware config include to test YAML Parser -schemaVersion: 1 +SchemaVersion: 1 Middleware: TcpSendBufferSize: 3456 TcpReceiveBufferSize: 3456 diff --git a/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_DuplicateControllerNames.yaml b/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_DuplicateControllerNames.yaml index 7ca496de2..b8597e69f 100644 --- a/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_DuplicateControllerNames.yaml +++ b/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_DuplicateControllerNames.yaml @@ -1,6 +1,6 @@ --- Description: Example configuration to test a broken configuration with duplicate Controller Names -schemaVersion: 1 +SchemaVersion: 1 Includes: Files: - DuplicateEthernetControllerNames.yaml diff --git a/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_FullIncludes.yaml b/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_FullIncludes.yaml index 01055f90f..33750b800 100644 --- a/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_FullIncludes.yaml +++ b/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_FullIncludes.yaml @@ -1,6 +1,6 @@ --- Description: Example configuration to test YAML Parser -schemaVersion: 1 +SchemaVersion: 1 Includes: SearchPathHints: - ConfigSnippets/CAN diff --git a/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_FullIncludes_Reference.yaml b/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_FullIncludes_Reference.yaml index 2aaacaed0..2045b2dbc 100644 --- a/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_FullIncludes_Reference.yaml +++ b/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_FullIncludes_Reference.yaml @@ -1,6 +1,6 @@ --- Description: Example configuration to test YAML Parser -schemaVersion: 1 +SchemaVersion: 1 ParticipantName: Node0 CanControllers: - Name: CAN1 diff --git a/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_MultipleAcceptorUris.yaml b/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_MultipleAcceptorUris.yaml index 9a61d5526..e5db8bf93 100644 --- a/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_MultipleAcceptorUris.yaml +++ b/SilKit/source/config/TestParticipantConfigs/ParticipantConfiguration_MultipleAcceptorUris.yaml @@ -1,6 +1,6 @@ --- Description: Example configuration to test a broken configuration with multiple AcceptorURIs -schemaVersion: 1 +SchemaVersion: 1 Includes: Files: - MultipleAcceptorUrisInclude.yaml