Skip to content
Snippets Groups Projects
Commit a6f749ac authored by Éloïs's avatar Éloïs
Browse files

[ref] gva: move query endpoints in network

parent e952d0af
No related branches found
No related tags found
No related merge requests found
// Copyright (C) 2020 Éloïs SANCHEZ.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::*;
use duniter_dbs::databases::dunp_v1::DunpV1DbReadable;
#[cfg(test)]
mod tests {
use super::*;
use duniter_dbs::databases::dunp_v1::DunpV1DbWritable;
use duniter_dbs::PeerCardDbV1;
#[test]
fn test_empty_endpoints() -> KvResult<()> {
// Populate DB
let dunp_db = duniter_dbs::databases::dunp_v1::DunpV1Db::<Mem>::open(MemConf::default())?;
let db_reader = DbsReaderImpl::mem();
let pk = PublicKey::default();
dunp_db
.peers_old_write()
.upsert(PubKeyKeyV2(pk), PeerCardDbV1::default())?;
// Request Data
let api_list = vec!["GVA".to_owned()];
assert_eq!(
db_reader.endpoints_(&dunp_db, api_list)?,
Vec::<String>::new()
);
Ok(())
}
#[test]
fn test_endpoints_with_empty_api_list() -> KvResult<()> {
let dummy_endpoint = "GVA S domain.tld 443 gva";
// Populate DB
let dunp_db = duniter_dbs::databases::dunp_v1::DunpV1Db::<Mem>::open(MemConf::default())?;
let db_reader = DbsReaderImpl::mem();
let pk = PublicKey::default();
let peer = PeerCardDbV1 {
endpoints: vec![dummy_endpoint.to_owned()],
..Default::default()
};
dunp_db.peers_old_write().upsert(PubKeyKeyV2(pk), peer)?;
// Request Data
let api_list = vec![];
assert_eq!(
db_reader.endpoints_(&dunp_db, api_list)?,
Vec::<String>::new()
);
Ok(())
}
#[test]
fn test_single_peer_endpoints() -> KvResult<()> {
let dummy_endpoint = "GVA S domain.tld 443 gva";
// Populate DB
let dunp_db = duniter_dbs::databases::dunp_v1::DunpV1Db::<Mem>::open(MemConf::default())?;
let db_reader = DbsReaderImpl::mem();
let pk = PublicKey::default();
let peer = PeerCardDbV1 {
endpoints: vec![dummy_endpoint.to_owned()],
..Default::default()
};
dunp_db.peers_old_write().upsert(PubKeyKeyV2(pk), peer)?;
// Request Data
let api_list = vec!["GVA".to_owned()];
assert_eq!(
db_reader.endpoints_(&dunp_db, api_list)?,
vec![dummy_endpoint.to_owned()]
);
Ok(())
}
}
impl DbsReaderImpl {
pub(super) fn endpoints_<DB: DunpV1DbReadable>(
&self,
network_db: &DB,
mut api_list: Vec<String>,
) -> KvResult<Vec<String>> {
if api_list.is_empty() {
return Ok(vec![]);
}
for api in &mut api_list {
api.push(' ');
}
network_db.peers_old().iter(.., |it| {
it.values()
.map_ok(|peer| {
peer.endpoints.into_iter().filter(|endpoint| {
api_list
.iter()
.any(|api| endpoint.starts_with(api.as_str()))
})
})
.flatten_ok()
.collect::<Result<Vec<String>, _>>()
})
}
}
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
pub mod block; pub mod block;
pub mod current_frame; pub mod current_frame;
pub mod endpoints;
pub mod find_inputs; pub mod find_inputs;
pub mod idty; pub mod idty;
pub mod network; pub mod network;
......
...@@ -15,11 +15,34 @@ ...@@ -15,11 +15,34 @@
use crate::*; use crate::*;
use dubp::crypto::keys::PublicKey as _; use dubp::crypto::keys::PublicKey as _;
use duniter_dbs::databases::dunp_v1::DunpV1DbReadable; use duniter_dbs::{databases::dunp_v1::DunpV1DbReadable, DunpHeadDbV1, PeerCardDbV1};
use duniter_dbs::{DunpHeadDbV1, PeerCardDbV1};
#[allow(clippy::unnecessary_wraps)] #[allow(clippy::unnecessary_wraps)]
impl DbsReaderImpl { impl DbsReaderImpl {
pub(super) fn endpoints_<DB: DunpV1DbReadable>(
&self,
network_db: &DB,
mut api_list: Vec<String>,
) -> KvResult<Vec<String>> {
if api_list.is_empty() {
return Ok(vec![]);
}
for api in &mut api_list {
api.push(' ');
}
network_db.peers_old().iter(.., |it| {
it.values()
.map_ok(|peer| {
peer.endpoints.into_iter().filter(|endpoint| {
api_list
.iter()
.any(|api| endpoint.starts_with(api.as_str()))
})
})
.flatten_ok()
.collect::<Result<Vec<String>, _>>()
})
}
pub(super) fn peers_and_heads_<DB: DunpV1DbReadable>( pub(super) fn peers_and_heads_<DB: DunpV1DbReadable>(
&self, &self,
dunp_db: &DB, dunp_db: &DB,
...@@ -53,6 +76,76 @@ impl DbsReaderImpl { ...@@ -53,6 +76,76 @@ impl DbsReaderImpl {
mod tests { mod tests {
use super::*; use super::*;
use duniter_dbs::databases::dunp_v1::DunpV1DbWritable; use duniter_dbs::databases::dunp_v1::DunpV1DbWritable;
use duniter_dbs::PeerCardDbV1;
#[test]
fn test_empty_endpoints() -> KvResult<()> {
// Populate DB
let dunp_db = duniter_dbs::databases::dunp_v1::DunpV1Db::<Mem>::open(MemConf::default())?;
let db_reader = DbsReaderImpl::mem();
let pk = PublicKey::default();
dunp_db
.peers_old_write()
.upsert(PubKeyKeyV2(pk), PeerCardDbV1::default())?;
// Request Data
let api_list = vec!["GVA".to_owned()];
assert_eq!(
db_reader.endpoints_(&dunp_db, api_list)?,
Vec::<String>::new()
);
Ok(())
}
#[test]
fn test_endpoints_with_empty_api_list() -> KvResult<()> {
let dummy_endpoint = "GVA S domain.tld 443 gva";
// Populate DB
let dunp_db = duniter_dbs::databases::dunp_v1::DunpV1Db::<Mem>::open(MemConf::default())?;
let db_reader = DbsReaderImpl::mem();
let pk = PublicKey::default();
let peer = PeerCardDbV1 {
endpoints: vec![dummy_endpoint.to_owned()],
..Default::default()
};
dunp_db.peers_old_write().upsert(PubKeyKeyV2(pk), peer)?;
// Request Data
let api_list = vec![];
assert_eq!(
db_reader.endpoints_(&dunp_db, api_list)?,
Vec::<String>::new()
);
Ok(())
}
#[test]
fn test_single_peer_endpoints() -> KvResult<()> {
let dummy_endpoint = "GVA S domain.tld 443 gva";
// Populate DB
let dunp_db = duniter_dbs::databases::dunp_v1::DunpV1Db::<Mem>::open(MemConf::default())?;
let db_reader = DbsReaderImpl::mem();
let pk = PublicKey::default();
let peer = PeerCardDbV1 {
endpoints: vec![dummy_endpoint.to_owned()],
..Default::default()
};
dunp_db.peers_old_write().upsert(PubKeyKeyV2(pk), peer)?;
// Request Data
let api_list = vec!["GVA".to_owned()];
assert_eq!(
db_reader.endpoints_(&dunp_db, api_list)?,
vec![dummy_endpoint.to_owned()]
);
Ok(())
}
#[test] #[test]
fn test_peers_and_heads() -> KvResult<()> { fn test_peers_and_heads() -> KvResult<()> {
......
...@@ -17,7 +17,6 @@ pub mod account_balance; ...@@ -17,7 +17,6 @@ pub mod account_balance;
pub mod block; pub mod block;
pub mod current_block; pub mod current_block;
pub mod current_frame; pub mod current_frame;
pub mod endpoints;
pub mod first_utxos_of_scripts; pub mod first_utxos_of_scripts;
pub mod gen_tx; pub mod gen_tx;
pub mod idty; pub mod idty;
...@@ -35,7 +34,6 @@ pub struct QueryRoot( ...@@ -35,7 +34,6 @@ pub struct QueryRoot(
queries::block::BlockQuery, queries::block::BlockQuery,
queries::current_block::CurrentBlockQuery, queries::current_block::CurrentBlockQuery,
queries::current_frame::CurrentFrameQuery, queries::current_frame::CurrentFrameQuery,
queries::endpoints::EndpointsQuery,
queries::first_utxos_of_scripts::FirstUtxosQuery, queries::first_utxos_of_scripts::FirstUtxosQuery,
queries::gen_tx::GenTxsQuery, queries::gen_tx::GenTxsQuery,
queries::idty::IdtyQuery, queries::idty::IdtyQuery,
......
// Copyright (C) 2020 Éloïs SANCHEZ.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::*;
// e2e requester pour obtenir la fiche de peer et un tableau de heads pour une pubKey donnée
// e2e requester pour obtenir la list des endpoints connu filtrable par type (gva, bma, ws2p, es?data-pod)
// ? e2e list endpoints type
// ? renomer dunp_v1 en network_v1 & DunpV1Db & co
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::*;
use duniter_dbs::databases::dunp_v1::DunpV1Db;
#[tokio::test]
async fn endpoints_gva_resolver() -> anyhow::Result<()> {
let mock_cm = MockAsyncAccessor::new();
let mut mock_dbs_reader = MockDbsReader::new();
mock_dbs_reader
.expect_endpoints::<DunpV1Db<FileBackend>>()
.times(1)
.returning(|_, _| {
Ok(vec![
"GVA S g1.librelois.fr 443 gva".to_owned(),
"GVA S domain.tld 443 gva".to_owned(),
])
});
let schema = create_schema(mock_cm, mock_dbs_reader)?;
assert_eq!(
exec_graphql_request(&schema, r#"{ endpoints(apiList:["GVA"]) }"#).await?,
serde_json::json!({
"data": {
"endpoints": [
"GVA S g1.librelois.fr 443 gva",
"GVA S domain.tld 443 gva"
]
}
})
);
Ok(())
}
}
#[derive(Default)]
pub(crate) struct EndpointsQuery;
#[async_graphql::Object]
impl EndpointsQuery {
/// Get endpoints known by the node
async fn endpoints(
&self,
ctx: &async_graphql::Context<'_>,
#[graphql(
desc = "filter endpoints by api (exact match endpoint first word, case sensitive)"
)]
api_list: Vec<String>,
) -> async_graphql::Result<Vec<String>> {
let data = ctx.data::<GvaSchemaData>()?;
let dbs_reader = data.dbs_reader();
Ok(data
.dbs_pool
.execute(move |dbs| dbs_reader.endpoints(&dbs.dunp_db, api_list))
.await??)
}
}
...@@ -25,6 +25,23 @@ pub(crate) struct NetworkQueryInner; ...@@ -25,6 +25,23 @@ pub(crate) struct NetworkQueryInner;
#[async_graphql::Object] #[async_graphql::Object]
impl NetworkQueryInner { impl NetworkQueryInner {
/// Get endpoints known by the node
async fn endpoints(
&self,
ctx: &async_graphql::Context<'_>,
#[graphql(
desc = "filter endpoints by api (exact match endpoint first word, case sensitive)"
)]
api_list: Vec<String>,
) -> async_graphql::Result<Vec<String>> {
let data = ctx.data::<GvaSchemaData>()?;
let dbs_reader = data.dbs_reader();
Ok(data
.dbs_pool
.execute(move |dbs| dbs_reader.endpoints(&dbs.dunp_db, api_list))
.await??)
}
/// Get peers and heads /// Get peers and heads
async fn nodes( async fn nodes(
&self, &self,
...@@ -54,6 +71,36 @@ mod tests { ...@@ -54,6 +71,36 @@ mod tests {
use duniter_dbs::databases::dunp_v1::DunpV1Db; use duniter_dbs::databases::dunp_v1::DunpV1Db;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
#[tokio::test]
async fn test_endpoints() -> anyhow::Result<()> {
let mock_cm = MockAsyncAccessor::new();
let mut mock_dbs_reader = MockDbsReader::new();
mock_dbs_reader
.expect_endpoints::<DunpV1Db<FileBackend>>()
.times(1)
.returning(|_, _| {
Ok(vec![
"GVA S g1.librelois.fr 443 gva".to_owned(),
"GVA S domain.tld 443 gva".to_owned(),
])
});
let schema = create_schema(mock_cm, mock_dbs_reader)?;
assert_eq!(
exec_graphql_request(&schema, r#"{ network { endpoints(apiList:["GVA"]) } }"#).await?,
serde_json::json!({
"data": {
"network": {
"endpoints": [
"GVA S g1.librelois.fr 443 gva",
"GVA S domain.tld 443 gva"
]
}
}
})
);
Ok(())
}
#[tokio::test] #[tokio::test]
async fn test_peers_and_heads() -> anyhow::Result<()> { async fn test_peers_and_heads() -> anyhow::Result<()> {
let mut dbs_reader = MockDbsReader::new(); let mut dbs_reader = MockDbsReader::new();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment