bbox_feature_server/
service.rs

1use crate::config::FeatureServiceCfg;
2use crate::datasource::Datasources;
3use crate::inventory::Inventory;
4use async_trait::async_trait;
5use bbox_core::cli::{NoArgs, NoCommands};
6use bbox_core::config::{error_exit, CoreServiceCfg};
7use bbox_core::metrics::{no_metrics, NoMetrics};
8use bbox_core::ogcapi::{ApiLink, CoreCollection};
9use bbox_core::service::OgcApiService;
10
11#[derive(Clone)]
12pub struct FeatureService {
13    pub inventory: Inventory,
14}
15#[async_trait]
16impl OgcApiService for FeatureService {
17    type Config = FeatureServiceCfg;
18    type CliCommands = NoCommands;
19    type CliArgs = NoArgs;
20    type Metrics = NoMetrics;
21
22    async fn create(config: &Self::Config, _core_cfg: &CoreServiceCfg) -> Self {
23        let mut sources = Datasources::create(&config.datasources)
24            .await
25            .unwrap_or_else(error_exit);
26
27        let mut inventory = Inventory::scan(&config.auto_collections).await;
28        for cfg in &config.collections {
29            let collection = sources
30                .setup_collection(cfg)
31                .await
32                .unwrap_or_else(error_exit);
33            inventory.add_collection(collection);
34        }
35        FeatureService { inventory }
36    }
37    fn conformance_classes(&self) -> Vec<String> {
38        let mut classes = vec![
39            "http://www.opengis.net/spec/ogcapi-common-2/1.0/conf/collections".to_string(),
40            "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core".to_string(),
41            "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson".to_string(),
42            "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30".to_string(),
43            // "http://www.opengis.net/spec/ogcapi-features-2/1.0/conf/crs".to_string(),
44        ];
45        if cfg!(feature = "html") {
46            classes.extend(vec![
47                "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/html".to_string(),
48            ]);
49        }
50        classes
51    }
52    fn landing_page_links(&self, _api_base: &str) -> Vec<ApiLink> {
53        vec![ApiLink {
54            href: "/collections".to_string(),
55            rel: Some("data".to_string()),
56            type_: Some("application/json".to_string()),
57            title: Some("Information about the feature collections".to_string()),
58            hreflang: None,
59            length: None,
60        }]
61    }
62    fn collections(&self) -> Vec<CoreCollection> {
63        self.inventory.collections()
64    }
65    fn openapi_yaml(&self) -> Option<&str> {
66        Some(include_str!("openapi.yaml"))
67    }
68    fn metrics(&self) -> &'static Self::Metrics {
69        no_metrics()
70    }
71}