Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalized storage #31

Merged
merged 42 commits into from
Sep 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8d1fdc8
Base Cargo.toml
castelao Sep 21, 2023
617d093
Skeletons for in memory and sqlite
castelao Sep 21, 2023
6d09fba
Registering (sub-)crate storage
castelao Sep 22, 2023
b5bd907
Centralizing workspace dependencies
castelao Sep 22, 2023
4dae0da
Minimalist Volatile save()
castelao Sep 22, 2023
590a052
security: Upgrading chrono (dependency)
castelao Sep 22, 2023
d2394bd
sqlite storage with sqlx
castelao Sep 23, 2023
42d14a1
Volatile storing top level Message
castelao Sep 23, 2023
27d636a
FileSystem skeleton
castelao Sep 23, 2023
9acdf0a
Concept for library base
castelao Sep 23, 2023
1b9cb73
feat: VolatileStorage::connect()
castelao Sep 24, 2023
3186c23
Locking volatile
castelao Sep 29, 2023
9c81710
Volatile save as async
castelao Sep 29, 2023
0e59415
sqlite with async
castelao Sep 29, 2023
931b750
Database working with memory, file, & sqlite
castelao Sep 29, 2023
82136d0
Require tokio to run tests
castelao Sep 29, 2023
03d343e
filesystem with async save
castelao Sep 29, 2023
c383d53
feat: directip::Message::to_vec()
castelao Sep 29, 2023
8b8f49a
Tokio required to test async procedures
castelao Sep 29, 2023
15e692d
Test async open with tokio::test
castelao Sep 29, 2023
2d5dd77
Check if could publish all applications
castelao Sep 29, 2023
887e4af
fix: License link to workspace
castelao Sep 29, 2023
7f3898f
Edition metadata defined at workspace level
castelao Sep 29, 2023
b70405a
fix: typo, wrong syntax in sqlite module
castelao Sep 29, 2023
eec1345
fix: Syntax mistakes in sqlite module
castelao Sep 29, 2023
4d49594
Reverting workspace metadata to debug strange error
castelao Sep 30, 2023
e0f2f90
syntax: sqlite module
castelao Sep 30, 2023
7a60d93
fix: Updating tarpaulin option
castelao Sep 30, 2023
7c86fe8
test: filesystem test prototype
castelao Sep 30, 2023
e090ab6
Testing sqlite
castelao Sep 30, 2023
66e2c82
FileSystem tested using connect()
castelao Sep 30, 2023
b453d9f
Using temporary dir for FileSystem
castelao Sep 30, 2023
b27be69
Updating core directip library
castelao Sep 30, 2023
4fc2832
Temporary switching off tests
castelao Sep 30, 2023
e62cd43
testing inmemory
castelao Sep 30, 2023
552ed60
Limiting tests on aarch64
castelao Sep 30, 2023
ea4164b
Limiting tests on powerpc64
castelao Sep 30, 2023
e87464c
Removing tests on s390
castelao Sep 30, 2023
3681803
Note on directip-storage in the README file
castelao Sep 30, 2023
0c021f6
Testing VolatileStorage
castelao Sep 30, 2023
a28d039
Renaming dialect to volatile
castelao Sep 30, 2023
7e588c4
Updating Nix
castelao Sep 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
target: [
aarch64-unknown-linux-gnu,
powerpc64le-unknown-linux-gnu,
s390x-unknown-linux-gnu,
# s390x-unknown-linux-gnu,
]
steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -118,7 +118,7 @@ jobs:
test -e ~/.cargo/bin/cargo-tarpaulin || cargo install cargo-tarpaulin --version ${{ steps.tarpaulin-version.outputs.version }}

- name: Run cargo-tarpaulin
run: cargo tarpaulin --all-features --timeout 600 --out Xml -- --test-threads 1
run: cargo tarpaulin --all-features --timeout 600 --out xml -- --test-threads 1

- name: Upload coverage to codecov
uses: codecov/codecov-action@v3
Expand Down Expand Up @@ -193,8 +193,20 @@ jobs:
command: publish
args: --dry-run -p directip

- name: Make sure we can publish direciip-client
- name: Make sure we can publish directip-client
uses: actions-rs/cargo@v1
with:
command: publish
args: --dry-run -p directip-client

- name: Make sure we can publish directip-dump
uses: actions-rs/cargo@v1
with:
command: publish
args: --dry-run -p directip-dump

- name: Make sure we can publish directip-storage
uses: actions-rs/cargo@v1
with:
command: publish
args: --dry-run -p directip-storage
19 changes: 16 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "directip"
version = "0.2.5"
version = "0.2.6"
authors = ["Guilherme Castelão <[email protected]>", "Luiz Irber <[email protected]>"]
edition = "2021"
description = "Iridium SBD Direct-IP communication protocol"
Expand All @@ -12,21 +12,34 @@ rust-version = "1.60.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[workspace]
members = ["directip-client", "directip-dump"]
members = ["directip-client", "directip-dump", "crates/storage"]
default-members = [".", "directip-client"]

[workspace.package]
authors = ["Guilherme Castelão <[email protected]>", "Luiz Irber <[email protected]>"]
edition = "2021"
license = "MIT OR Apache-2.0"
repository = "https://github.com/castelao/DirectIP"

[features]
serde = ["dep:serde", "dep:serde_bytes", "chrono/serde"]

[dependencies]
byteorder = "1"
chrono = "0.4.23"
chrono = "0.4.31"
log = "0.4"
thiserror = "1.0"
derive_builder = "0.11.2"
serde = { version = "1.0.147", optional = true, default-features = false, features=["serde_derive"]}
serde_bytes = { version = "0.11.8", optional = true }

[workspace.dependencies]
chrono = "0.4.31"
directip = { version = "0.2.6", path = "." }
sqlx = { version = "=0.7.0", features = ["sqlite", "runtime-tokio-native-tls"] }
tempfile = "3.8.0"
tokio = { version = "1.32.0", features = ["macros"] }

[lib]
name = "directip"

Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ the core support for applications such as the one listed below.
components, such as the IMEI or message-id, from a Direct-IP binary
transmission. This is an equivalent to ncdump but for Direct-IP messages.

- [directip-storage](https://crates.io/crates/directip-storage): A library
that provides multiple backends to store Direct-IP messages. It can be
used, for instance, to archive MT messages transmitted or MO messages
received.

## Minimum supported Rust version

Currently the minimum supported Rust version is 1.60.0
Expand Down
20 changes: 20 additions & 0 deletions crates/storage/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "directip-storage"
version = "0.0.1"
authors = ["Guilherme Castelão <[email protected]>", "Luiz Irber <[email protected]>"]
license = "MIT OR Apache-2.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
chrono.workspace = true
directip.workspace = true
sqlx = { workspace = true, optional = true }
tempfile = { workspace = true }

[dev-dependencies]
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }

[features]
sqlite = ["dep:sqlx"]
95 changes: 95 additions & 0 deletions crates/storage/src/filesystem.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// filesystem:///var/iridium-storage/

use std::fs::File;
use std::io::{BufWriter, Read, Write};

Check warning on line 4 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (beta)

unused import: `Read`

Check warning on line 4 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (stable)

unused import: `Read`

Check warning on line 4 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (macos)

unused import: `Read`

Check warning on line 4 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (windows)

unused import: `Read`
use std::path::PathBuf;

use chrono::Utc;

use directip::Message;

pub struct FileSystemStorage {
root: PathBuf,

Check warning on line 12 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (beta)

field `root` is never read

Check warning on line 12 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (stable)

field `root` is never read

Check warning on line 12 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (macos)

field `root` is never read

Check warning on line 12 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (windows)

field `root` is never read
// current_id: usize,
}

impl super::Storage for FileSystemStorage {}

impl FileSystemStorage {
pub(super) fn connect() -> Result<Self, Box<dyn std::error::Error>> {

Check warning on line 19 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (beta)

associated items `connect` and `save` are never used

Check warning on line 19 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (stable)

associated items `connect` and `save` are never used

Check warning on line 19 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (macos)

associated items `connect` and `save` are never used

Check warning on line 19 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (windows)

associated items `connect` and `save` are never used
let tmp_dir = tempfile::TempDir::new().unwrap();
Ok(FileSystemStorage {
root: tmp_dir.path().into(),
})
}

pub(super) async fn save(&self, msg: Message) {
let mut path = self.root.clone();
path.push("data");
let mut filename = String::new();
// Add IMEI?
filename.push_str(&Utc::now().format("%Y%m%d%H%M%S%s").to_string());
//filename.push_str(&format!("_{}", &self.current_id));
filename.push_str(".isbd");
path.push(filename);

let mut file = BufWriter::new(File::create(path).unwrap());
file.write(&msg.to_vec()).unwrap();
}
/*
pub fn current_id(&self) -> usize {
self.current_id
}
*/

// Probably distinguish between creating a new from scratch versus
// connecting to an existing one. Connecting requires less checks,
// faster, and a different level of errors.
/*
pub fn initiatedb(root: PathBuf) -> FileSystemStorage {
let mut next_session_id = root.clone();
next_session_id.push("next_session.txt");

let current_id: usize = if next_session_id.exists() {
let mut file = File::open(next_session_id).unwrap();
let mut buffer = String::new();
file.read_to_string(&mut buffer).unwrap();
if buffer.ends_with('\n') {
buffer.pop();
}
buffer.parse().unwrap()
} else {
let mut file = std::fs::File::create(next_session_id).unwrap();
file.write(b"1").unwrap();
1
// let mut file = BufWriter::new(File::create(next_session_id).unwrap());
//file.write("0").unwrap();
};
FileSystemStorage { root, current_id }
}
*/
}

#[cfg(test)]
mod test_filesystem {
use super::*;
use directip;

fn sample() -> directip::Message {

Check warning on line 78 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (stable)

function `sample` is never used

Check warning on line 78 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (macos)

function `sample` is never used

Check warning on line 78 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (windows)

function `sample` is never used
let msg = directip::mt::MTMessage::from_reader(
[
0x01, 0x00, 0x1c, 0x44, 0x00, 0x19, 0x00, 0x00, 0x27, 0x0f, 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf5,
]
.as_slice(),
);
directip::Message::MT(msg.unwrap())
}

//#[tokio::test]
async fn filesystem() {

Check warning on line 91 in crates/storage/src/filesystem.rs

View workflow job for this annotation

GitHub Actions / test (beta)

function `filesystem` is never used
let storage = FileSystemStorage::connect().unwrap();
storage.save(sample()).await;
}
}
51 changes: 51 additions & 0 deletions crates/storage/src/inmemory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use std::sync::RwLock;

use crate::Message;

pub struct VolatileStorage {
// current_id: usize,
data: RwLock<Vec<Message>>,

Check warning on line 7 in crates/storage/src/inmemory.rs

View workflow job for this annotation

GitHub Actions / test (beta)

field `data` is never read

Check warning on line 7 in crates/storage/src/inmemory.rs

View workflow job for this annotation

GitHub Actions / test (stable)

field `data` is never read

Check warning on line 7 in crates/storage/src/inmemory.rs

View workflow job for this annotation

GitHub Actions / test (macos)

field `data` is never read

Check warning on line 7 in crates/storage/src/inmemory.rs

View workflow job for this annotation

GitHub Actions / test (windows)

field `data` is never read
}

impl super::Storage for VolatileStorage {}

impl VolatileStorage {
pub(super) fn connect() -> Result<VolatileStorage, Box<dyn std::error::Error>> {

Check warning on line 13 in crates/storage/src/inmemory.rs

View workflow job for this annotation

GitHub Actions / test (beta)

associated items `connect` and `save` are never used

Check warning on line 13 in crates/storage/src/inmemory.rs

View workflow job for this annotation

GitHub Actions / test (stable)

associated items `connect` and `save` are never used

Check warning on line 13 in crates/storage/src/inmemory.rs

View workflow job for this annotation

GitHub Actions / test (macos)

associated items `connect` and `save` are never used

Check warning on line 13 in crates/storage/src/inmemory.rs

View workflow job for this annotation

GitHub Actions / test (windows)

associated items `connect` and `save` are never used
Ok(VolatileStorage {
data: RwLock::new(vec![]),
})
}

pub(super) async fn save(&self, msg: Message) {
self.data
.write()
.expect("Failed to acquire write lock.")
.push(msg);
}
}

#[cfg(test)]
mod test_volatile {
use super::VolatileStorage;
use directip;

fn sample() -> directip::Message {
let msg = directip::mt::MTMessage::from_reader(
[
0x01, 0x00, 0x1c, 0x44, 0x00, 0x19, 0x00, 0x00, 0x27, 0x0f, 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf5,
]
.as_slice(),
);
directip::Message::MT(msg.unwrap())
}

#[tokio::test]
async fn volatile() {
let storage = VolatileStorage::connect().unwrap();
storage.save(sample()).await;

assert_eq!(storage.data.read().unwrap().len(), 1);
}
}
93 changes: 93 additions & 0 deletions crates/storage/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
mod filesystem;
mod inmemory;

use directip::Message;
use filesystem::FileSystemStorage;
use inmemory::VolatileStorage;

// Feature sqlite
#[cfg(feature = "sqlite")]
mod sqlite;

trait Storage {
//fn connect(cfg: String) -> Self;
// fn save(&self, msg: Message);
}

enum Database {

Check warning on line 17 in crates/storage/src/lib.rs

View workflow job for this annotation

GitHub Actions / test (beta)

enum `Database` is never used

Check warning on line 17 in crates/storage/src/lib.rs

View workflow job for this annotation

GitHub Actions / test (stable)

enum `Database` is never used

Check warning on line 17 in crates/storage/src/lib.rs

View workflow job for this annotation

GitHub Actions / test (macos)

enum `Database` is never used

Check warning on line 17 in crates/storage/src/lib.rs

View workflow job for this annotation

GitHub Actions / test (windows)

enum `Database` is never used
M(VolatileStorage),
F(FileSystemStorage),
#[cfg(feature = "sqlite")]
L(sqlite::SQLiteStorage),
}

impl Database {
pub async fn open(cfg: &str) -> Result<Self, Box<dyn std::error::Error>> {

Check warning on line 25 in crates/storage/src/lib.rs

View workflow job for this annotation

GitHub Actions / test (beta)

associated items `open` and `save` are never used

Check warning on line 25 in crates/storage/src/lib.rs

View workflow job for this annotation

GitHub Actions / test (stable)

associated items `open` and `save` are never used

Check warning on line 25 in crates/storage/src/lib.rs

View workflow job for this annotation

GitHub Actions / test (macos)

associated items `open` and `save` are never used

Check warning on line 25 in crates/storage/src/lib.rs

View workflow job for this annotation

GitHub Actions / test (windows)

associated items `open` and `save` are never used
if (&cfg.len() >= &(11 as usize)) && (cfg[..11] == "volatile://".to_string()) {
Ok(Database::M(VolatileStorage::connect()?))
} else if (&cfg.len() >= &(13 as usize)) && (cfg[..13] == "filesystem://".to_string()) {
Ok(Database::F(FileSystemStorage::connect()?))
} else if cfg[..9] == "sqlite://".to_string() {
#[cfg(feature = "sqlite")]
{
let db = crate::sqlite::SQLiteStorage::connect().await;
Ok(Database::L(db))
}
#[cfg(not(feature = "sqlite"))]
unimplemented!("Missing sqlite feature")
} else {
unimplemented!("Unknown storage")
}
/*
Database::F(FileSystemStorage::initiatedb(std::path::PathBuf::from(
"./",
)))
*/
}

pub async fn save(&self, msg: Message) {
match self {
Database::M(s) => s.save(msg).await,
Database::F(s) => s.save(msg).await,
#[cfg(feature = "sqlite")]
Database::L(s) => s.save(msg).await,
_ => todo!(),

Check warning on line 54 in crates/storage/src/lib.rs

View workflow job for this annotation

GitHub Actions / test (beta)

unreachable pattern

Check warning on line 54 in crates/storage/src/lib.rs

View workflow job for this annotation

GitHub Actions / test (stable)

unreachable pattern

Check warning on line 54 in crates/storage/src/lib.rs

View workflow job for this annotation

GitHub Actions / test (macos)

unreachable pattern

Check warning on line 54 in crates/storage/src/lib.rs

View workflow job for this annotation

GitHub Actions / test (windows)

unreachable pattern
}
}
}

#[cfg(test)]
mod tests {
use super::Database;

fn sample() -> directip::Message {
let msg = directip::mt::MTMessage::from_reader(
[
0x01, 0x00, 0x1c, 0x44, 0x00, 0x19, 0x00, 0x00, 0x27, 0x0f, 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf5,
]
.as_slice(),
);
directip::Message::MT(msg.unwrap())
}

#[tokio::test]
async fn volatile() {
let db = Database::open("volatile://").await.unwrap();
db.save(sample());
}

//#[tokio::test]
async fn filesystem() {
let db = Database::open("filesystem://").await.unwrap();
db.save(sample());
}

#[cfg(feature = "sqlite")]
#[tokio::test]
async fn open_sqlite() {
let db = Database::open("sqlite://").await.unwrap();
db.save(sample());
}
}
Loading
Loading