diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..fcc37b2b --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,37 @@ +# /******************************************************************************** +# * Copyright (c) 2024 Contributors to the Eclipse Foundation +# * +# * See the NOTICE file(s) distributed with this work for additional +# * information regarding copyright ownership. +# * +# * This program and the accompanying materials are made available under the +# * terms of the Apache License 2.0 which is available at +# * http://www.apache.org/licenses/LICENSE-2.0 +# * +# * SPDX-License-Identifier: Apache-2.0 +# ********************************************************************************/ + +FROM mcr.microsoft.com/devcontainers/rust:1-1-bookworm +ARG DEBIAN_FRONTEND=noninteractive +ENV CROSS_CONTAINER_IN_CONTAINER=true +ENV TZ=Europe/Berlin +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone +RUN apt-get update -y +RUN apt install software-properties-common build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev curl git libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev -y + +USER vscode +RUN cargo install cross cargo-license cargo-cyclonedx + +# Installing pyEnv to set up specific version of Python +ENV HOME=/home/vscode +WORKDIR ${HOME} +RUN git clone --depth=1 https://github.com/pyenv/pyenv.git .pyenv +ENV PYENV_ROOT="${HOME}/.pyenv" +ENV PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/bin:${PATH}" +ENV PYTHON_VERSION=3.12 +RUN pyenv install ${PYTHON_VERSION} +RUN pyenv global ${PYTHON_VERSION} + +# Fails due to gpg keyserver not accessible via corporate proxy +# Moved to postStartCommand.sh for DevContainer +# RUN pip install "git+https://github.com/eclipse-kuksa/kuksa-common.git@v1#subdirectory=sbom-tools" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..30f6768d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,19 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/rust +{ + "name": "Kuksa DevContainer", + "build": { + "dockerfile": "Dockerfile" + }, + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": {} + }, + "postStartCommand": "bash .devcontainer/postStartCommand.sh", + "mounts": [ + { + "target": "/var/run/docker.sock", + "source": "/var/run/docker.sock", + "type": "bind" + } + ] +} diff --git a/.devcontainer/postStartCommand.sh b/.devcontainer/postStartCommand.sh new file mode 100755 index 00000000..86fa2985 --- /dev/null +++ b/.devcontainer/postStartCommand.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# +# Copyright (c) 2024 Contributors to the Eclipse Foundation +# +# Building all currently supported targets for databroker-cli. +# Uses cross for cross-compiling. Needs to be executed +# before docker build, as docker collects the artifacts +# created by this script +# this needs the have cross, cargo-license and kuksa sbom helper +# installed +# +# SPDX-License-Identifier: Apache-2.0 + +pip install "git+https://github.com/eclipse-kuksa/kuksa-common.git@v1#subdirectory=sbom-tools" diff --git a/.github/workflows/create_draft_release.yml b/.github/workflows/create_draft_release.yml index 221d5f9d..c3c84e89 100644 --- a/.github/workflows/create_draft_release.yml +++ b/.github/workflows/create_draft_release.yml @@ -14,17 +14,9 @@ name: Create Draft Release on: - workflow_dispatch: # input version manually. Overrides push tag - inputs: - tag: - description: "Release version, eg:latest, 0.2.1" - required: true - default: "0.0.0" - - # As of today trigger only manually - #push: - # tags: - # - "*.*.*" + push: + tags: + - "*.*.*" # Needed if GITHUB_TOKEN by default do not have right to create release permissions: @@ -32,25 +24,6 @@ permissions: packages: write jobs: - get_version: - runs-on: ubuntu-latest - # Map a step output to a job output - outputs: - version: ${{ steps.eval_version.outputs.version }} - steps: - - name: Get tag or user release version - id: eval_version - run: | - GIT_VER="${GITHUB_REF/refs\/tags\//}" - echo "### Detected tag: $GIT_VER" - if [ -n "${{ github.event.inputs.tag }}" ]; then - GIT_VER="${{ github.event.inputs.tag }}" - echo "Forced release version: $GIT_VER" - echo "version=${GIT_VER}" >> $GITHUB_OUTPUT - else - echo "version=${GIT_VER}" >> $GITHUB_OUTPUT - fi - call_kuksa_databroker_build: uses: ./.github/workflows/kuksa_databroker_build.yml secrets: @@ -66,7 +39,6 @@ jobs: runs-on: ubuntu-latest needs: [ - get_version, call_kuksa_databroker_build, call_kuksa_databroker-cli_build, ] @@ -87,8 +59,7 @@ jobs: ls -R build-artifacts cd build-artifacts # Rename, add release name (usually tag) - for f in databroker*.tar.gz; do mv "$f" "$(echo "$f" | sed s/.tar.gz/-${{ needs.get_version.outputs.version }}.tar.gz/)"; done - + for f in databroker*.tar.gz; do mv "$f" "$(echo "$f" | sed s/.tar.gz/-${{ github.ref_name }}.tar.gz/)"; done - name: Create release id: create_release @@ -96,7 +67,7 @@ jobs: # if: startsWith(github.ref, 'refs/tags/' with: draft: true - tag_name: KUKSA Databroker ${{ needs.get_version.outputs.version }} + name: KUKSA Databroker ${{ github.ref_name }} fail_on_unmatched_files: true files: | build-artifacts/* diff --git a/.github/workflows/kuksa_databroker_build.yml b/.github/workflows/kuksa_databroker_build.yml index 7765acab..d5c6ff65 100644 --- a/.github/workflows/kuksa_databroker_build.yml +++ b/.github/workflows/kuksa_databroker_build.yml @@ -130,6 +130,12 @@ jobs: with: files: lcov.info token: ${{ secrets.CODECOV_TOKEN }} + - uses: taiki-e/install-action@v2.9.4 + with: + tool: cargo-hack@0.6 + - name: "Check each feature" + working-directory: ${{github.workspace}} + run: cargo hack check --each-feature build: name: Build diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9b181ff6..6ed89c4d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,7 +22,7 @@ https://www.eclipse.org/projects/handbook/#resources-commit Contact the project developers via the project's "dev" list. -* https://dev.eclipse.org/mailman/listinfo/kuksa-dev +* https://accounts.eclipse.org/mailing-list/kuksa-dev ## Pre-commit set up This repository is set up to use [pre-commit](https://pre-commit.com/) hooks. @@ -30,3 +30,12 @@ Use `pip install pre-commit` to install pre-commit. After you clone the project, run `pre-commit install` to install pre-commit into your git hooks. Pre-commit will now run on every commit. Every time you clone a project using pre-commit running pre-commit install should always be the first thing you do. + +## Linting + +Please run the formatter and linter before opening pull requests: + +```sh +cargo fmt -- --check +cargo clippy --all-targets -- -W warnings -D warnings +``` diff --git a/databroker-cli/Cargo.toml b/databroker-cli/Cargo.toml index 59f146c7..d282bf1d 100644 --- a/databroker-cli/Cargo.toml +++ b/databroker-cli/Cargo.toml @@ -48,4 +48,4 @@ http = "0.2.8" [features] default = ["tls"] -tls = ["tonic/tls"] +tls = ["tonic/tls", "kuksa-common/tls", "kuksa/tls"] diff --git a/databroker-cli/src/cli.rs b/databroker-cli/src/cli.rs index 812656f5..71938d73 100644 --- a/databroker-cli/src/cli.rs +++ b/databroker-cli/src/cli.rs @@ -61,6 +61,7 @@ pub struct Cli { } impl Cli { + #[cfg(feature = "tls")] pub fn get_ca_cert(&mut self) -> Option { self.ca_cert.clone() } diff --git a/databroker/Cargo.toml b/databroker/Cargo.toml index 81f28182..e6c7af7d 100644 --- a/databroker/Cargo.toml +++ b/databroker/Cargo.toml @@ -80,7 +80,7 @@ sd-notify = "0.4.1" [features] default = ["tls"] -tls = ["tonic/tls"] +tls = ["tonic/tls", "kuksa-common/tls", "kuksa/tls"] jemalloc = ["dep:jemallocator"] viss = ["dep:axum", "dep:chrono", "dep:uuid"] libtest = [] diff --git a/databroker/src/broker.rs b/databroker/src/broker.rs index efbe7cb2..a791afa3 100644 --- a/databroker/src/broker.rs +++ b/databroker/src/broker.rs @@ -1443,7 +1443,7 @@ pub struct AuthorizedAccess<'a, 'b> { permissions: &'b Permissions, } -impl<'a, 'b> AuthorizedAccess<'a, 'b> { +impl AuthorizedAccess<'_, '_> { #[allow(clippy::too_many_arguments)] pub async fn add_entry( &self, diff --git a/databroker/src/glob.rs b/databroker/src/glob.rs index f457efc5..c3164a17 100644 --- a/databroker/src/glob.rs +++ b/databroker/src/glob.rs @@ -33,9 +33,20 @@ pub struct Matcher { impl Matcher { pub fn new(glob_pattern: &str) -> Result { // Check if the pattern is valid - if is_valid_pattern(glob_pattern) { + // See https://github.com/eclipse-kuksa/kuksa-databroker/blob/main/doc/wildcard_matching.md + // for reference + + // Empty string is ok, and by some reason also quoted empty string + // Must be replaced before checking if valid regexp + let glob_pattern_modified = if glob_pattern.eq("\"\"") || glob_pattern.is_empty() { + "**".to_string() + } else { + glob_pattern.to_string() + }; + + if is_valid_pattern(&glob_pattern_modified) { Ok(Matcher { - glob_pattern: Matcher::to_glob_string(glob_pattern), + glob_pattern: Matcher::to_glob_string(&glob_pattern_modified), }) } else { Err(MatchError::MatchError) @@ -43,7 +54,15 @@ impl Matcher { } pub fn is_match(&self, path: &str) -> bool { - glob_match(&self.glob_pattern, path) + let mut res: bool = glob_match(&self.glob_pattern, path); + // Special case - if we have something like A.B.C as input we want to both match + // the explicit signal A.B.C if existing but also + // sub-signals if A.B.C is a branch + if !res && self.glob_pattern.ends_with("/**") { + let new_pattern = self.glob_pattern.strip_suffix("/**").unwrap(); + res = glob_match(new_pattern, path); + } + res } pub fn as_string(&self) -> String { @@ -53,19 +72,10 @@ impl Matcher { fn to_glob_string(glob: &str) -> String { let mut glob_string = String::new(); - if glob.eq("\"\"") || glob.is_empty() { - glob_string += "**"; - return glob_string; - } - let mut glob_path_string = glob.replace('.', "/"); if !glob.contains('*') { - if glob.ends_with('.') { - glob_path_string += "/*"; - } else if !glob.contains('.') { - glob_path_string += "/**"; - } + glob_path_string += "/**"; } glob_string.push_str(glob_path_string.as_str()); @@ -1269,7 +1279,6 @@ mod tests { .should_match_signal("Vehicle.TraveledDistance")); } - #[ignore] #[test] fn test_regex_single_subpath() { assert!(using_glob("Vehicle").should_equal_regex_pattern("^Vehicle(?:\\..+)?$")); @@ -1299,7 +1308,6 @@ mod tests { .should_match_signals(ALL_SIGNALS)); } - #[ignore] #[test] fn test_regex_matches_multi_subpath() { assert!(using_glob("Vehicle.Cabin.Sunroof") @@ -1314,14 +1322,14 @@ mod tests { } #[test] fn test_matches_multi_subpath() { - using_glob("Vehicle.Cabin.Sunroof") + assert!(using_glob("Vehicle.Cabin.Sunroof") .with_signals(ALL_SIGNALS) .should_match_signals(&[ "Vehicle.Cabin.Sunroof.Position", "Vehicle.Cabin.Sunroof.Shade.Position", "Vehicle.Cabin.Sunroof.Shade.Switch", "Vehicle.Cabin.Sunroof.Switch", - ]); + ])); // Make sure partial "last component" doesn't match assert!(using_glob("Vehicle.Cabin.Sunroof") @@ -1337,7 +1345,6 @@ mod tests { .should_match_signal("Vehicle.Cabin.Sunroof.Shade.Position")); } - #[ignore] #[test] fn test_regex_wildcard_at_end() { assert!(using_glob("Vehicle.Cabin.Sunroof.*") @@ -1354,7 +1361,6 @@ mod tests { ],)); } - #[ignore] #[test] fn test_regex_single_wildcard_in_middle() { assert!(using_glob("Vehicle.Cabin.Sunroof.*.Position") @@ -1428,7 +1434,6 @@ mod tests { ],)); } - #[ignore] #[test] fn test_regex_double_wildcard_at_beginning() { assert!(using_glob("**.Sunroof").should_equal_regex_pattern(r"^.+\.Sunroof$")); @@ -1445,7 +1450,6 @@ mod tests { .should_match_no_signals()); } - #[ignore] #[test] fn test_regex_single_wildcard_at_the_beginning() { assert!(using_glob("*.Sunroof").should_equal_regex_pattern(r"^[^.\s\:]+\.Sunroof$")); @@ -1458,7 +1462,6 @@ mod tests { .should_match_no_signals()); } - #[ignore] #[test] fn test_regex_single_non_matching_literal() { assert!(using_glob("Sunroof").should_equal_regex_pattern(r"^Sunroof(?:\..+)?$")); @@ -2543,16 +2546,33 @@ mod tests_glob_matching { fn should_match_signals(&self, signals: &[&str]) -> bool { let mut should_have_matched = Vec::new(); let mut should_not_have_matched = Vec::new(); + + // We cannot just check self.signals, then we miss the items in signals + // that is not part of self.signals + + let mut matches = Vec::new(); for signal in self.signals { - if signals.contains(signal) { - if !self.glob.is_match(signal) { - should_have_matched.push(signal); - } - } else if self.glob.is_match(signal) { + if self.glob.is_match(signal) { + matches.push(signal); + } + } + + // Now compare in two loops + for signal in &matches { + if !signals.contains(signal) { should_not_have_matched.push(signal); } } + let mut i = 0; + + while i < signals.len() { + if !matches.contains(&&signals[i]) { + should_have_matched.push(signals[i]); + } + i += 1 + } + for signal in &should_have_matched { println!( "glob '{}' should have matched signal '{}' but didn't", @@ -2681,7 +2701,6 @@ mod tests_glob_matching { .should_match_signal("Vehicle/TraveledDistance")); } - #[ignore] #[test] fn test_glob_single_subpath() { assert!(using_glob_matching("Vehicle").should_equal_glob_string_pattern("Vehicle/**")); @@ -2707,11 +2726,12 @@ mod tests_glob_matching { .should_match_signals(ALL_SIGNALS_WITH_SLASH_SEPARATORS)); } - #[ignore] #[test] fn test_glob_matches_multi_subpath() { + // We append "/**"", but later compare also without if needed + // to cover the case that Vehicle.Cabin.Sunroof would be a signal assert!(using_glob_matching("Vehicle.Cabin.Sunroof") - .should_equal_glob_string_pattern(r"Vehicle/Cabin/Sunroof",)); + .should_equal_glob_string_pattern(r"Vehicle/Cabin/Sunroof/**",)); } #[test] @@ -2722,18 +2742,28 @@ mod tests_glob_matching { } #[test] fn test_matches_multi_subpath() { - using_glob_matching("Vehicle.Cabin.Sunroof") + // Note .** should give same result as without + assert!(using_glob_matching("Vehicle.Cabin.Sunroof.**") .with_signals(ALL_SIGNALS_WITH_SLASH_SEPARATORS) .should_match_signals(&[ - "Vehicle.Cabin.Sunroof.Position", - "Vehicle.Cabin.Sunroof.Shade.Position", - "Vehicle.Cabin.Sunroof.Shade.Switch", - "Vehicle.Cabin.Sunroof.Switch", - ]); + "Vehicle/Cabin/Sunroof/Position", + "Vehicle/Cabin/Sunroof/Shade/Position", + "Vehicle/Cabin/Sunroof/Shade/Switch", + "Vehicle/Cabin/Sunroof/Switch", + ])); + + assert!(using_glob_matching("Vehicle.Cabin.Sunroof") + .with_signals(ALL_SIGNALS_WITH_SLASH_SEPARATORS) + .should_match_signals(&[ + "Vehicle/Cabin/Sunroof/Position", + "Vehicle/Cabin/Sunroof/Shade/Position", + "Vehicle/Cabin/Sunroof/Shade/Switch", + "Vehicle/Cabin/Sunroof/Switch", + ])); // Make sure partial "last component" doesn't match assert!(using_glob_matching("Vehicle.Cabin.Sunroof") - .with_signals(&["Vehicle.Cabin.SunroofThing"]) + .with_signals(&["Vehicle/Cabin/SunroofThing"]) .should_match_no_signals()); } @@ -2745,7 +2775,6 @@ mod tests_glob_matching { .should_match_signal("Vehicle/Cabin/Sunroof/Shade/Position")); } - #[ignore] #[test] fn test_glob_wildcard_at_end() { assert!(using_glob_matching("Vehicle.Cabin.Sunroof.*") @@ -2762,7 +2791,6 @@ mod tests_glob_matching { ],)); } - #[ignore] #[test] fn test_glob_single_wildcard_in_middle() { assert!(using_glob_matching("Vehicle.Cabin.Sunroof.*.Position") @@ -2786,11 +2814,17 @@ mod tests_glob_matching { .should_match_signals(&["Vehicle/Cabin/Sunroof/Shade/Position"])); } - #[ignore] + #[ignore] // Ignored due to comment below #[test] fn test_matches_combination_of_multiple_wildcard_and_single_wildcard() { /* This is the only case that can not be supported by the new glob match lib used. + Known problem, see e.g. + https://github.com/devongovett/glob-match/issues/8 + https://github.com/devongovett/glob-match/issues/9 + https://github.com/devongovett/glob-match/pull/18 + + But repo seems to be abandoned! */ assert!(using_glob_matching("**.*.*.*.Position") .with_signals(ALL_SIGNALS_WITH_SLASH_SEPARATORS) @@ -2840,7 +2874,6 @@ mod tests_glob_matching { ],)); } - #[ignore] #[test] fn test_glob_double_wildcard_at_beginning() { assert!(using_glob_matching("**.Sunroof").should_equal_glob_string_pattern(r"**/Sunroof")); @@ -2857,7 +2890,6 @@ mod tests_glob_matching { .should_match_no_signals()); } - #[ignore] #[test] fn test_glob_single_wildcard_at_the_beginning() { assert!(using_glob_matching("*.Sunroof").should_equal_glob_string_pattern(r"*/Sunroof")); @@ -2870,10 +2902,10 @@ mod tests_glob_matching { .should_match_no_signals()); } - #[ignore] #[test] fn test_glob_single_non_matching_literal() { - assert!(using_glob_matching("Sunroof").should_equal_glob_string_pattern(r"Sunroof")); + // Single word without dash should result in everything below, thats why /** is expected + assert!(using_glob_matching("Sunroof").should_equal_glob_string_pattern(r"Sunroof/**")); } #[test] @@ -2896,6 +2928,7 @@ mod tests_glob_matching { #[test] fn test_valid_glob_path() { + assert_eq!(Matcher::to_glob_string("String"), "String/**"); assert_eq!(Matcher::to_glob_string("String.*"), "String/*"); assert_eq!(Matcher::to_glob_string("String.**"), "String/**"); assert_eq!( @@ -2908,7 +2941,7 @@ mod tests_glob_matching { ); assert_eq!( Matcher::to_glob_string("String.String.String.String"), - "String/String/String/String" + "String/String/String/String/**" ); assert_eq!( Matcher::to_glob_string("String.String.String.String.String.**"), @@ -2952,6 +2985,10 @@ mod tests_glob_matching { ); assert_eq!(Matcher::to_glob_string("**.String"), "**/String"); assert_eq!(Matcher::to_glob_string("*.String"), "*/String"); + assert_eq!( + Matcher::to_glob_string("**.*.*.*.String"), + "**/*/*/*/String" + ); assert_eq!( Matcher::to_glob_string("*.String.String.String"), "*/String/String/String" diff --git a/databroker/src/grpc/kuksa_val_v2/conversions.rs b/databroker/src/grpc/kuksa_val_v2/conversions.rs index e632e4f7..49443aa4 100644 --- a/databroker/src/grpc/kuksa_val_v2/conversions.rs +++ b/databroker/src/grpc/kuksa_val_v2/conversions.rs @@ -219,6 +219,7 @@ impl From<&broker::Metadata> for proto::Metadata { fn from(metadata: &broker::Metadata) -> Self { proto::Metadata { id: metadata.id, + path: metadata.path.clone(), data_type: proto::DataType::from(metadata.data_type.clone()) as i32, entry_type: proto::EntryType::from(metadata.entry_type.clone()) as i32, description: metadata.description.clone(), diff --git a/databroker/src/grpc/kuksa_val_v2/val.rs b/databroker/src/grpc/kuksa_val_v2/val.rs index 80694ffd..286d1958 100644 --- a/databroker/src/grpc/kuksa_val_v2/val.rs +++ b/databroker/src/grpc/kuksa_val_v2/val.rs @@ -853,6 +853,10 @@ async fn get_signal( signal_id: Option, broker: &AuthorizedAccess<'_, '_>, ) -> Result { + if signal_id.is_none() { + return Err(tonic::Status::invalid_argument("No SignalId provided")); + } + if let Some(signal) = signal_id.unwrap().signal { match signal { proto::signal_id::Signal::Path(path) => { @@ -1175,6 +1179,28 @@ mod tests { } } + #[tokio::test] + async fn test_get_value_with_signal_id_none() { + let broker = DataBroker::default(); + + let request = proto::GetValueRequest { signal_id: None }; + + // Manually insert permissions + let mut get_value_request = tonic::Request::new(request); + get_value_request + .extensions_mut() + .insert(permissions::ALLOW_ALL.clone()); + + match broker.get_value(get_value_request).await { + Ok(_response) => { + panic!("Did not expect success"); + } + Err(status) => { + assert_eq!(status.code(), tonic::Code::InvalidArgument) + } + } + } + struct GetValuesConfig { send_auth: bool, request_first: bool, @@ -2253,6 +2279,10 @@ mod tests { assert_eq!(list_response.metadata.first().unwrap().min, min); assert_eq!(list_response.metadata.first().unwrap().max, max); + assert_eq!( + list_response.metadata.first().unwrap().path, + "test.datapoint1".to_string() + ); } Err(_status) => panic!("failed to execute get request"), } @@ -2302,6 +2332,22 @@ mod tests { root: "test.*".to_owned(), filter: "".to_owned(), }); + + let mut no_wildcard_req_root = tonic::Request::new(proto::ListMetadataRequest { + root: "test".to_owned(), + filter: "".to_owned(), + }); + + let mut no_wildcard_req_branch = tonic::Request::new(proto::ListMetadataRequest { + root: "test.branch".to_owned(), + filter: "".to_owned(), + }); + + let mut empty_req = tonic::Request::new(proto::ListMetadataRequest { + root: "".to_owned(), + filter: "".to_owned(), + }); + // Manually insert permissions wildcard_req_two_asteriks .extensions_mut() @@ -2311,6 +2357,18 @@ mod tests { .extensions_mut() .insert(permissions::ALLOW_ALL.clone()); + no_wildcard_req_root + .extensions_mut() + .insert(permissions::ALLOW_ALL.clone()); + + no_wildcard_req_branch + .extensions_mut() + .insert(permissions::ALLOW_ALL.clone()); + + empty_req + .extensions_mut() + .insert(permissions::ALLOW_ALL.clone()); + match proto::val_server::Val::list_metadata(&broker, wildcard_req_two_asteriks) .await .map(|res| res.into_inner()) @@ -2332,6 +2390,39 @@ mod tests { } Err(_status) => panic!("failed to execute get request"), } + + match proto::val_server::Val::list_metadata(&broker, empty_req) + .await + .map(|res| res.into_inner()) + { + Ok(list_response) => { + let entries_size = list_response.metadata.len(); + assert_eq!(entries_size, 2); + } + Err(_status) => panic!("failed to execute get request"), + } + + match proto::val_server::Val::list_metadata(&broker, no_wildcard_req_root) + .await + .map(|res| res.into_inner()) + { + Ok(list_response) => { + let entries_size = list_response.metadata.len(); + assert_eq!(entries_size, 2); + } + Err(_status) => panic!("failed to execute get request"), + } + + match proto::val_server::Val::list_metadata(&broker, no_wildcard_req_branch) + .await + .map(|res| res.into_inner()) + { + Ok(list_response) => { + let entries_size = list_response.metadata.len(); + assert_eq!(entries_size, 1); + } + Err(_status) => panic!("failed to execute get request"), + } } #[tokio::test] diff --git a/databroker/src/grpc/server.rs b/databroker/src/grpc/server.rs index c4b95753..b94d1ed2 100644 --- a/databroker/src/grpc/server.rs +++ b/databroker/src/grpc/server.rs @@ -156,6 +156,7 @@ where serve_with_incoming_shutdown( incoming, broker, + #[cfg(feature = "tls")] ServerTLS::Disabled, apis, authorization, diff --git a/databroker/src/main.rs b/databroker/src/main.rs index bc6d5007..0507292a 100644 --- a/databroker/src/main.rs +++ b/databroker/src/main.rs @@ -27,14 +27,11 @@ use databroker::broker::RegistrationError; #[cfg(feature = "tls")] use databroker::grpc::server::ServerTLS; +use clap::{Arg, ArgAction, Command}; use std::thread::available_parallelism; use tokio::select; use tokio::signal::unix::{signal, SignalKind}; -#[cfg(feature = "tls")] -use tracing::warn; -use tracing::{debug, error, info}; - -use clap::{Arg, ArgAction, Command}; +use tracing::{debug, error, info, warn}; #[cfg(feature = "viss")] use databroker::viss; @@ -115,7 +112,7 @@ async fn add_kuksa_attribute( } } -async fn read_metadata_file<'a, 'b>( +async fn read_metadata_file( database: &broker::AuthorizedAccess<'_, '_>, filename: &str, ) -> Result<(), Box> { diff --git a/databroker/src/viss/v2/server.rs b/databroker/src/viss/v2/server.rs index 476670c5..465f4983 100644 --- a/databroker/src/viss/v2/server.rs +++ b/databroker/src/viss/v2/server.rs @@ -386,8 +386,8 @@ fn resolve_permissions( } } -async fn generate_metadata<'a>( - db: &'a AuthorizedAccess<'_, '_>, +async fn generate_metadata( + db: &AuthorizedAccess<'_, '_>, path: &str, ) -> HashMap { let mut metadata: HashMap = HashMap::new(); diff --git a/doc/wildcard_matching.md b/doc/wildcard_matching.md index 15b1fa1c..f2534c99 100644 --- a/doc/wildcard_matching.md +++ b/doc/wildcard_matching.md @@ -17,6 +17,7 @@ |---------------------|--------------------------------------| | `""` | Everything | | `"Vehicle"` | Everything starting with `Vehicle` | +| `"Vehicle.Speed"` | `Vehicle.Speed` | | `"Vehicle.Cabin.Sunroof"` | `Vehicle.Cabin.Sunroof.Position`
`Vehicle.Cabin.Sunroof.Shade.Position`
`Vehicle.Cabin.Sunroof.Shade.Switch`
`Vehicle.Cabin.Sunroof.Switch` | | `"Vehicle.Cabin.Sunroof.**"` | `Vehicle.Cabin.Sunroof.Position`
`Vehicle.Cabin.Sunroof.Shade.Position`
`Vehicle.Cabin.Sunroof.Shade.Switch`
`Vehicle.Cabin.Sunroof.Switch` | | `"Vehicle.Cabin.Sunroof.*"` | `Vehicle.Cabin.Sunroof.Position`
`Vehicle.Cabin.Sunroof.Switch` | diff --git a/lib/common/Cargo.toml b/lib/common/Cargo.toml index cdb532bc..617bc77c 100644 --- a/lib/common/Cargo.toml +++ b/lib/common/Cargo.toml @@ -33,5 +33,4 @@ crate-type = ["lib"] path = "src/lib.rs" [features] -default = ["tls"] tls = ["tonic/tls"] diff --git a/lib/kuksa/Cargo.toml b/lib/kuksa/Cargo.toml index c1796cb8..c4d61fc8 100644 --- a/lib/kuksa/Cargo.toml +++ b/lib/kuksa/Cargo.toml @@ -34,5 +34,4 @@ crate-type = ["lib"] path = "src/lib.rs" [features] -default = ["tls"] tls = ["tonic/tls"] diff --git a/proto/kuksa/val/v2/types.proto b/proto/kuksa/val/v2/types.proto index 8955f6de..4eae41d2 100644 --- a/proto/kuksa/val/v2/types.proto +++ b/proto/kuksa/val/v2/types.proto @@ -75,6 +75,9 @@ enum ErrorCode { } message Metadata { + + // Full dot notated path for the signal + string path = 9; // ID field int32 id = 10; @@ -110,6 +113,7 @@ message Metadata { Value allowed_values = 17; // Must be of array type Value min = 18; Value max = 19; + } // VSS Data type of a signal