changed database connection to use r2d2 and implemented subscription insert
This commit is contained in:
parent
6b3f200778
commit
f65ae11463
|
@ -6,17 +6,12 @@ jobs:
|
|||
working_directory: ~/repo
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-dependencies-{{ checksum "Cargo.lock" }}
|
||||
- run:
|
||||
name: install dependencies
|
||||
command: |
|
||||
cargo build
|
||||
- save_cache:
|
||||
paths:
|
||||
- ~/.cargo
|
||||
key: v1-dependencies-{{ checksum "Cargo.lock" }}
|
||||
cargo install diesel_cli
|
||||
diesel migration run
|
||||
- run:
|
||||
name: run test suite
|
||||
command: |
|
||||
|
|
|
@ -568,6 +568,7 @@ dependencies = [
|
|||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libsqlite3-sys 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"r2d2 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1136,6 +1137,16 @@ dependencies = [
|
|||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r2d2"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"scheduled-thread-pool 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
|
@ -1315,6 +1326,7 @@ dependencies = [
|
|||
"askama 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"diesel 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"r2d2 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slog-term 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1327,6 +1339,14 @@ name = "ryu"
|
|||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "scheduled-thread-pool"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped_threadpool"
|
||||
version = "0.1.9"
|
||||
|
@ -1992,6 +2012,7 @@ dependencies = [
|
|||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
|
||||
"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
|
||||
"checksum r2d2 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bc42ce75d9f4447fb2a04bbe1ed5d18dd949104572850ec19b164e274919f81b"
|
||||
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
|
@ -2012,6 +2033,7 @@ dependencies = [
|
|||
"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
|
||||
"checksum scheduled-thread-pool 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bbecfcb36d47e0d6a4aefb198d475b13aa06e326770c1271171d44893766ae1c"
|
||||
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
|
||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
|
||||
|
|
|
@ -6,7 +6,8 @@ authors = ["Gonçalo Valério <gon@ovalerio.net>"]
|
|||
[dependencies]
|
||||
actix = "0.8.3"
|
||||
actix-web = "1.0.2"
|
||||
diesel = { version = "1.4.2", features = ["sqlite"] }
|
||||
r2d2 = "0.8.5"
|
||||
diesel = { version = "1.4.2", features = ["sqlite", "r2d2"] }
|
||||
toml = "0.5.0"
|
||||
clap = "2.32.0"
|
||||
askama = "0.8"
|
||||
|
|
|
@ -1,3 +1,65 @@
|
|||
use url::form_urlencoded::Parse;
|
||||
use super::schema::subscriptions;
|
||||
use diesel::prelude::*;
|
||||
use models::NewSubscription;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use utils::{setup_logging, Pool};
|
||||
|
||||
pub fn handle_subscription(data: Parse) {}
|
||||
pub fn handle_subscription(db: &Pool, data: &HashMap<String, String>) -> bool {
|
||||
let log = setup_logging();
|
||||
let mode;
|
||||
let callback;
|
||||
let topic;
|
||||
let timestamp = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("Invalid Time")
|
||||
.as_secs();
|
||||
let now = i32::try_from(timestamp).ok().unwrap();
|
||||
let conn = db.get().unwrap();
|
||||
|
||||
match data.get("hub.mode") {
|
||||
Some(value) => mode = value,
|
||||
None => return false,
|
||||
}
|
||||
|
||||
match data.get("hub.callback") {
|
||||
Some(value) => callback = value,
|
||||
None => return false,
|
||||
}
|
||||
|
||||
match data.get("hub.topic") {
|
||||
Some(value) => topic = value,
|
||||
None => return false,
|
||||
}
|
||||
|
||||
debug!(
|
||||
log,
|
||||
"Mode: {}, Callback: {}, topic: {}", mode, callback, topic
|
||||
);
|
||||
|
||||
if mode == &"subscribe" {
|
||||
let subscription = NewSubscription {
|
||||
callback: callback,
|
||||
topic: topic,
|
||||
sec: "",
|
||||
created_at: &now,
|
||||
expires_at: &now,
|
||||
};
|
||||
|
||||
diesel::insert_into(subscriptions::table)
|
||||
.values(&subscription)
|
||||
.execute(&conn)
|
||||
.expect("Error saving new subscription");
|
||||
debug!(log, "Subscription created.");
|
||||
return true;
|
||||
} else if mode == &"unsubscribe" {
|
||||
return true;
|
||||
} else {
|
||||
debug!(log, "Wrong method.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use actions::handle_subscription;
|
||||
use actix_web::{http, web, HttpRequest, HttpResponse};
|
||||
use askama::Template;
|
||||
use std::collections::HashMap;
|
||||
use url::form_urlencoded;
|
||||
use utils::{validate_parsed_data, AppState};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "index.html")]
|
||||
|
@ -17,6 +17,7 @@ pub fn index(_state: web::Data<AppState>, _req: HttpRequest) -> HttpResponse {
|
|||
|
||||
pub fn hub(state: web::Data<AppState>, _req: HttpRequest, params: String) -> HttpResponse {
|
||||
let log = &state.log;
|
||||
let db = &state.db;
|
||||
info!(log, "Received Request");
|
||||
debug!(log, "Content: {}", params);
|
||||
|
||||
|
@ -26,13 +27,14 @@ pub fn hub(state: web::Data<AppState>, _req: HttpRequest, params: String) -> Htt
|
|||
parameters.insert(key.to_string(), value.to_string());
|
||||
}
|
||||
|
||||
if !validate_parsed_data(parameters) {
|
||||
if !validate_parsed_data(¶meters) {
|
||||
return HttpResponse::Ok()
|
||||
.status(http::StatusCode::BAD_REQUEST)
|
||||
.finish();
|
||||
}
|
||||
|
||||
handle_subscription(parsed_data);
|
||||
let result = handle_subscription(db, ¶meters);
|
||||
debug!(log, "{}", result);
|
||||
return HttpResponse::Ok()
|
||||
.status(http::StatusCode::ACCEPTED)
|
||||
.finish();
|
||||
|
@ -41,21 +43,23 @@ pub fn hub(state: web::Data<AppState>, _req: HttpRequest, params: String) -> Htt
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use actix::{SyncArbiter, System};
|
||||
use actix::System;
|
||||
use actix_web::{http, test, web};
|
||||
use diesel::prelude::*;
|
||||
use utils::{setup_logging, DbExecutor};
|
||||
use diesel::r2d2::{self, ConnectionManager};
|
||||
use utils::setup_logging;
|
||||
|
||||
#[test]
|
||||
fn test_index() {
|
||||
let _sys = System::new("rusty-hub-test");
|
||||
let addr = SyncArbiter::start(1, || {
|
||||
DbExecutor(SqliteConnection::establish("test.db").unwrap())
|
||||
});
|
||||
let manager = ConnectionManager::<SqliteConnection>::new("test.db");
|
||||
let pool = r2d2::Pool::builder()
|
||||
.build(manager)
|
||||
.expect("Failed to create pool.");
|
||||
|
||||
let data = web::Data::new(AppState {
|
||||
log: setup_logging(),
|
||||
db: addr.clone(),
|
||||
db: pool.clone(),
|
||||
});
|
||||
|
||||
let resp = index(data, test::TestRequest::get().to_http_request());
|
||||
|
@ -65,13 +69,14 @@ mod tests {
|
|||
#[test]
|
||||
fn test_hub_no_parameters() {
|
||||
let _sys = System::new("rusty-hub-test");
|
||||
let addr = SyncArbiter::start(1, || {
|
||||
DbExecutor(SqliteConnection::establish("test.db").unwrap())
|
||||
});
|
||||
let manager = ConnectionManager::<SqliteConnection>::new("test.db");
|
||||
let pool = r2d2::Pool::builder()
|
||||
.build(manager)
|
||||
.expect("Failed to create pool.");
|
||||
|
||||
let data = web::Data::new(AppState {
|
||||
log: setup_logging(),
|
||||
db: addr.clone(),
|
||||
db: pool.clone(),
|
||||
});
|
||||
|
||||
let resp = hub(
|
||||
|
@ -85,13 +90,14 @@ mod tests {
|
|||
#[test]
|
||||
fn test_hub_invalid_callback() {
|
||||
let _sys = System::new("rusty-hub-test");
|
||||
let addr = SyncArbiter::start(1, || {
|
||||
DbExecutor(SqliteConnection::establish("test.db").unwrap())
|
||||
});
|
||||
let manager = ConnectionManager::<SqliteConnection>::new("test.db");
|
||||
let pool = r2d2::Pool::builder()
|
||||
.build(manager)
|
||||
.expect("Failed to create pool.");
|
||||
|
||||
let data = web::Data::new(AppState {
|
||||
log: setup_logging(),
|
||||
db: addr.clone(),
|
||||
db: pool.clone(),
|
||||
});
|
||||
|
||||
let resp = hub(
|
||||
|
@ -105,13 +111,14 @@ mod tests {
|
|||
#[test]
|
||||
fn test_hub_invalid_topic() {
|
||||
let _sys = System::new("rusty-hub-test");
|
||||
let addr = SyncArbiter::start(1, || {
|
||||
DbExecutor(SqliteConnection::establish("test.db").unwrap())
|
||||
});
|
||||
let manager = ConnectionManager::<SqliteConnection>::new("test.db");
|
||||
let pool = r2d2::Pool::builder()
|
||||
.build(manager)
|
||||
.expect("Failed to create pool.");
|
||||
|
||||
let data = web::Data::new(AppState {
|
||||
log: setup_logging(),
|
||||
db: addr.clone(),
|
||||
db: pool.clone(),
|
||||
});
|
||||
|
||||
let resp = hub(
|
||||
|
@ -125,13 +132,14 @@ mod tests {
|
|||
#[test]
|
||||
fn test_hub_invalid_mode() {
|
||||
let _sys = System::new("rusty-hub-test");
|
||||
let addr = SyncArbiter::start(1, || {
|
||||
DbExecutor(SqliteConnection::establish("test.db").unwrap())
|
||||
});
|
||||
let manager = ConnectionManager::<SqliteConnection>::new("test.db");
|
||||
let pool = r2d2::Pool::builder()
|
||||
.build(manager)
|
||||
.expect("Failed to create pool.");
|
||||
|
||||
let data = web::Data::new(AppState {
|
||||
log: setup_logging(),
|
||||
db: addr.clone(),
|
||||
db: pool.clone(),
|
||||
});
|
||||
|
||||
let resp = hub(
|
||||
|
@ -145,13 +153,14 @@ mod tests {
|
|||
#[test]
|
||||
fn test_hub_subscribe_success() {
|
||||
let _sys = System::new("rusty-hub-test");
|
||||
let addr = SyncArbiter::start(1, || {
|
||||
DbExecutor(SqliteConnection::establish("test.db").unwrap())
|
||||
});
|
||||
let manager = ConnectionManager::<SqliteConnection>::new("test.db");
|
||||
let pool = r2d2::Pool::builder()
|
||||
.build(manager)
|
||||
.expect("Failed to create pool.");
|
||||
|
||||
let data = web::Data::new(AppState {
|
||||
log: setup_logging(),
|
||||
db: addr.clone(),
|
||||
db: pool.clone(),
|
||||
});
|
||||
|
||||
let resp = hub(
|
||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -9,12 +9,13 @@ extern crate slog;
|
|||
extern crate slog_async;
|
||||
extern crate slog_term;
|
||||
extern crate url;
|
||||
use actix::{SyncArbiter, System};
|
||||
use actix::{System};
|
||||
use actix_web::{web, App, HttpServer};
|
||||
use clap::Arg;
|
||||
use controllers::{hub, index};
|
||||
use diesel::prelude::*;
|
||||
use utils::{setup_logging, AppState, DbExecutor};
|
||||
use diesel::r2d2::{self, ConnectionManager};
|
||||
use utils::{setup_logging, AppState};
|
||||
|
||||
mod actions;
|
||||
mod controllers;
|
||||
|
@ -50,13 +51,14 @@ fn main() {
|
|||
}
|
||||
|
||||
let sys = System::new("rusty-hub");
|
||||
let addr = SyncArbiter::start(3, || {
|
||||
DbExecutor(SqliteConnection::establish("local.db").unwrap())
|
||||
});
|
||||
let manager = ConnectionManager::<SqliteConnection>::new("local.db");
|
||||
let pool = r2d2::Pool::builder()
|
||||
.build(manager)
|
||||
.expect("Failed to create pool.");
|
||||
|
||||
let app_data = web::Data::new(AppState {
|
||||
log: setup_logging(),
|
||||
db: addr.clone(),
|
||||
db: pool.clone(),
|
||||
});
|
||||
|
||||
info!(log, "Starting server");
|
||||
|
|
12
src/utils.rs
12
src/utils.rs
|
@ -1,19 +1,15 @@
|
|||
use actix::{Actor, Addr, SyncContext};
|
||||
use diesel::prelude::*;
|
||||
use diesel::r2d2::{self, ConnectionManager};
|
||||
use slog::Drain;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use url::Url;
|
||||
|
||||
pub struct DbExecutor(pub SqliteConnection);
|
||||
|
||||
impl Actor for DbExecutor {
|
||||
type Context = SyncContext<Self>;
|
||||
}
|
||||
pub type Pool = r2d2::Pool<ConnectionManager<SqliteConnection>>;
|
||||
|
||||
pub struct AppState {
|
||||
pub log: slog::Logger,
|
||||
pub db: Addr<DbExecutor>,
|
||||
pub db: Pool,
|
||||
}
|
||||
|
||||
pub fn setup_logging() -> slog::Logger {
|
||||
|
@ -23,7 +19,7 @@ pub fn setup_logging() -> slog::Logger {
|
|||
slog::Logger::root(drain, o!())
|
||||
}
|
||||
|
||||
pub fn validate_parsed_data(parameters: HashMap<String,String>) -> bool {
|
||||
pub fn validate_parsed_data(parameters: &HashMap<String,String>) -> bool {
|
||||
let callback;
|
||||
let mode;
|
||||
let topic;
|
||||
|
|
Loading…
Reference in New Issue