Skip to content

Commit

Permalink
add grpc service
Browse files Browse the repository at this point in the history
  • Loading branch information
isaidsari committed Mar 7, 2024
1 parent 84365bf commit 0c79aba
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 4 deletions.
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

## [Unreleased] - 07-03-2024

### Added

- v0.1.1 CHANGELOG.md added
- v0.1.1 versioning started
- v0.1.1 gRPC added for other services to notify their status
- v0.1.1 proto file(s) introduced for gRPC. its a simple for now but will be extended
- v0.1.1 build.rs added to compile proto files

### Changed

- v0.1.1 tokio crate updated to latest version
- v0.1.1 Duration::seconds() is now deprecated, changed to try_seconds()

## [0.1.0]

### Added

- v0.1.0 initial

### Fixed

### Changed

### Removed
10 changes: 8 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "remon-server"
version = "0.1.0"
version = "0.1.1"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand All @@ -21,7 +21,6 @@ serde_json = "1.0.107"
thiserror = "1.0.50"
sqlx = { version = "0.7.2", features = ["sqlite", "runtime-tokio"] }
sysinfo = "0.30.3"
tokio = { version = "1.33.0", features = ["full"] }
totp-rs = "5.4.0"
env_logger = "0.10.0"
log = "0.4.14"
Expand All @@ -31,6 +30,13 @@ maplit = "1.0.2"
lazy_static = "1.4.0"
async_once = "0.2.6"
fcm = { git = "https://github.com/rj76/fcm-rust.git", branch = "main" }
tokio = { version = "1.36.0", features = ["full"] }
tonic = "0.11.0"
tonic-reflection = "0.11.0"
prost = "0.12.3"

[build-dependencies]
tonic-build = "0.11.0"

[dev-dependencies]
ctor = "0.2.6"
13 changes: 13 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use std::{env, error::Error, path::PathBuf};

fn main() -> Result<(), Box<dyn Error>> {
let out_dir = PathBuf::from(env::var("OUT_DIR")?);

tonic_build::configure()
.file_descriptor_set_path(out_dir.join("remonproto_descriptor.bin"))
.compile(&[r".\proto\notification.proto"], &["proto"])?;

tonic_build::compile_protos(r".\proto\notification.proto")?;

Ok(())
}
17 changes: 17 additions & 0 deletions proto/notification.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
syntax = "proto3";

package remonproto;

service NotificationService {
rpc SendNotification(NotificationRequest) returns (NotificationResponse) {}
}

message NotificationRequest {
string title = 1;
string body = 2;
string token = 3;
}

message NotificationResponse {
string message = 1;
}
1 change: 1 addition & 0 deletions src/grpc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod grpc_service;
62 changes: 62 additions & 0 deletions src/grpc/grpc_service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use log::{info};
use tonic::{transport::Server, Request, Response, Status};

pub mod remonproto {
tonic::include_proto!("remonproto");

pub(super) const FILE_DESCRIPTOR_SET: &[u8] =
tonic::include_file_descriptor_set!("remonproto_descriptor");
}

use remonproto::{
notification_service_server::{NotificationService as NotificationServiceImpl, NotificationServiceServer},
NotificationRequest, NotificationResponse,
};

#[derive(Default)]
pub struct NotificationService;

#[tonic::async_trait]
impl NotificationServiceImpl for NotificationService {
async fn send_notification(
&self,
request: Request<NotificationRequest>,
) -> Result<Response<NotificationResponse>, Status> {
let request = request.into_inner();

info!(
"Received notification: {} - {}",
request.title, request.body
);

// TODO(isaidsari): send notification here

let response = remonproto::NotificationResponse {
message: "Notification received".into(),
};

// return the response
Ok(Response::new(response))
}
}

pub async fn init() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse()?;
let notification_service = NotificationService::default();

// use reflection to expose the service
let reflection_service = tonic_reflection::server::Builder::configure()
.register_encoded_file_descriptor_set(remonproto::FILE_DESCRIPTOR_SET)
.build()
.unwrap();

info!("gRPC service listening on {}", addr);

Server::builder()
.add_service(NotificationServiceServer::new(notification_service))
.add_service(reflection_service)
.serve(addr)
.await?;

Ok(())
}
9 changes: 9 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use log::{error, info};

mod auth;
mod monitor;
mod grpc;

use local_ip_address::local_ip;

Expand Down Expand Up @@ -133,6 +134,14 @@ async fn main() {
}
}

match grpc::grpc_service::init().await {
Ok(_) => {}
Err(_) => {
error!("Failed to initialize gRPC.");
return;
}
}

let server = Server::bind(&socket_addr)
.serve(make_service_fn(|_conn| async {
Ok::<_, Infallible>(service_fn(req_handler))
Expand Down
2 changes: 1 addition & 1 deletion src/monitor/config_exceeds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub(super) async fn check_thresholds(

// TODO(adnanjpg): make it configurable
fn get_send_notification_interval() -> Duration {
Duration::seconds(5 * 60)
Duration::try_seconds(60 * 5).expect("failed to create duration")
}

async fn should_send_notification_to_exceeding_device(config: &MonitorConfig) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion src/monitor/persistence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use self::status_mem::{create_mem_status_frame_singles_table, create_mem_status_
pub use self::status_mem::{get_mem_status_between_dates, insert_mem_status_frame};

use crate::persistence::SQLConnection;
pub use crate::persistence::{get_default_sql_connection, get_sql_connection, FetchId};
pub use crate::persistence::{get_default_sql_connection, FetchId};

pub async fn init_db(conn: &SQLConnection) -> Result<(), sqlx::Error> {
create_monitor_configs_table(conn).await?;
Expand Down

0 comments on commit 0c79aba

Please sign in to comment.