Add readme instructions, run proxy command.
This commit is contained in:
parent
924712f583
commit
81c1ace175
|
@ -6,6 +6,9 @@ edition = "2018"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
default-run = "tenebrous"
|
default-run = "tenebrous"
|
||||||
|
|
||||||
|
[package.metadata.scripts]
|
||||||
|
grpc-proxy = 'docker run -d --rm -v "$(pwd)"/envoy.yaml:/etc/envoy/envoy.yaml:ro --network=host envoyproxy/envoy:v1.16.1'
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "tenebrous-migrate"
|
name = "tenebrous-migrate"
|
||||||
path = "src/migrate.rs"
|
path = "src/migrate.rs"
|
||||||
|
|
68
README.md
68
README.md
|
@ -4,41 +4,66 @@ An open source character sheet service for tabletop roleplaying games.
|
||||||
|
|
||||||
Currently under heavy development.
|
Currently under heavy development.
|
||||||
|
|
||||||
|
## The Stack
|
||||||
|
|
||||||
|
This project makes use of these technologies:
|
||||||
|
|
||||||
|
- Rust
|
||||||
|
- Rocket Web Framework
|
||||||
|
- Tonic gRPC Framework
|
||||||
|
- Typescript
|
||||||
|
|
||||||
|
Building is backed by: cargo, npm, and webpack.
|
||||||
|
|
||||||
## Build Instructions
|
## Build Instructions
|
||||||
|
|
||||||
These are very basic build instructions. They assume you already have
|
These are very basic build instructions. They assume you already have
|
||||||
cargo set up and installed.
|
cargo set up and installed.
|
||||||
|
|
||||||
### Install Dependencies
|
|
||||||
|
|
||||||
Install dependencies. The exact method depends on your OS.
|
|
||||||
|
|
||||||
* sqlite3 and development headers (Void Linux: `xbps-install
|
|
||||||
sqlite sqlite-devel`, Ubuntu: `apt install sqlite3 libsqlite3-dev`).
|
|
||||||
* protoc: protocol buffers compiler. There is one baked into the
|
|
||||||
build, so you should not need this unless you are not using
|
|
||||||
Linux/Mac/Windows.
|
|
||||||
|
|
||||||
### Initial Setup
|
### Initial Setup
|
||||||
|
|
||||||
Follow these instructions from the root of the repository.
|
Quick initial setup instructions that will set up a development
|
||||||
|
environment.
|
||||||
|
|
||||||
Set up database:
|
First, install dependencies by either using the command below (Void
|
||||||
|
Linux), or reading the "Dependencies Required" section:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
xbps-install sqlite sqlite-devel protobuf nodejs docker
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run the required `cargo` commands to install management tools and
|
||||||
|
create a development database:
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
cargo install --version=0.2.0 sqlx-cli
|
cargo install --version=0.2.0 sqlx-cli
|
||||||
|
cargo install cargo-run-script
|
||||||
cargo run --bin tenebrous-migrate
|
cargo run --bin tenebrous-migrate
|
||||||
```
|
```
|
||||||
|
|
||||||
### Run Application
|
### Dependencies Required
|
||||||
|
|
||||||
If you are using `rustup`, then it should automatically switch to the
|
Dependencies required to build the project. The exact installation
|
||||||
stable version of Rust in this repository. This is because of the
|
method depends on your OS.
|
||||||
`rust-toolchain` file.
|
|
||||||
|
* sqlite3 and development headers (Void Linux: `xbps-install
|
||||||
|
sqlite sqlite-devel`, Ubuntu: `apt install sqlite3 libsqlite3-dev`).
|
||||||
|
* protoc: protocol buffers compiler. Needed to compile protobuf files
|
||||||
|
for both the server and web frontends (Void Linux: `xbps-install
|
||||||
|
protobuf`).
|
||||||
|
* Node and npm: Needed to run webpack for compiling and injecting
|
||||||
|
Typescript into various web pages (Void Linux: `xbps-install
|
||||||
|
nodejs`).
|
||||||
|
* Docker: Needed to run the grpc proxy (Void Linux `xbps-install
|
||||||
|
docker`).
|
||||||
|
|
||||||
|
### Run Application
|
||||||
|
|
||||||
Command line "instructions" to build and run the application:
|
Command line "instructions" to build and run the application:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
cargo run-script grpc-proxy # only required if proxy not already running
|
||||||
cargo run
|
cargo run
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -65,4 +90,15 @@ to update the SQLx data JSON file:
|
||||||
cargo sqlx prepare -- --bin tenebrous
|
cargo sqlx prepare -- --bin tenebrous
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### gRPC-Web Proxy
|
||||||
|
|
||||||
|
The frontend web application makes use of the gRPC-Web protocol to
|
||||||
|
call gPRC endpoints from the browser. This requires a proxy to
|
||||||
|
translate the calls from the browser to HTTP2 calls gRPC understands.
|
||||||
|
For development, executing the `cargo run-script grpc-proxy` command
|
||||||
|
will start the envoy proxy recommended by Google's gRPC-Web project.
|
||||||
|
|
||||||
|
The envoy configuration assumes you are on Linux. If you are using Mac
|
||||||
|
OS or Windows, see the note in the envoy configuration.
|
||||||
|
|
||||||
[rustup]: https://rust-lang.github.io/rustup/index.html
|
[rustup]: https://rust-lang.github.io/rustup/index.html
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
use crate::models::proto::cofd::api::cofd_api_server::{CofdApi, CofdApiServer};
|
||||||
|
use crate::models::proto::cofd::api::UpdateSkillValueRequest;
|
||||||
|
use crate::models::proto::cofd::cofd_sheet::Skill;
|
||||||
|
use tonic::{transport::Server, Request, Response, Status};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CofdApiService {
|
||||||
|
pub db: sqlx::SqlitePool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tonic::async_trait]
|
||||||
|
impl CofdApi for CofdApiService {
|
||||||
|
async fn update_skill_value(
|
||||||
|
&self,
|
||||||
|
request: Request<UpdateSkillValueRequest>, // Accept request of type HelloRequest
|
||||||
|
) -> Result<Response<Skill>, Status> {
|
||||||
|
// Return an instance of type HelloReply
|
||||||
|
println!("Got a request: {:?}", request);
|
||||||
|
|
||||||
|
let reply = Skill::default();
|
||||||
|
|
||||||
|
Ok(Response::new(reply)) // Send back our formatted greeting
|
||||||
|
}
|
||||||
|
}
|
55
src/main.rs
55
src/main.rs
|
@ -9,56 +9,36 @@ extern crate rocket_contrib;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
use log::{error, info};
|
||||||
use rocket_contrib::serve::StaticFiles;
|
use rocket_contrib::serve::StaticFiles;
|
||||||
use rocket_contrib::templates::Template;
|
use rocket_contrib::templates::Template;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use tonic::transport::Server;
|
||||||
|
|
||||||
pub mod catchers;
|
pub mod catchers;
|
||||||
pub mod db;
|
pub mod db;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
|
pub mod grpc;
|
||||||
pub mod migrator;
|
pub mod migrator;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
|
|
||||||
async fn gin_and_tonic() -> Result<(), Box<dyn std::error::Error>> {
|
async fn make_tonic(db: sqlx::SqlitePool) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
use crate::models::proto::cofd::api::cofd_api_server::{CofdApi, CofdApiServer};
|
use crate::models::proto::cofd::api::cofd_api_server::CofdApiServer;
|
||||||
use crate::models::proto::cofd::api::UpdateSkillValueRequest;
|
|
||||||
use crate::models::proto::cofd::cofd_sheet::Skill;
|
|
||||||
use tonic::{transport::Server, Request, Response, Status};
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct MyGreeter {}
|
|
||||||
|
|
||||||
#[tonic::async_trait]
|
|
||||||
impl CofdApi for MyGreeter {
|
|
||||||
async fn update_skill_value(
|
|
||||||
&self,
|
|
||||||
request: Request<UpdateSkillValueRequest>, // Accept request of type HelloRequest
|
|
||||||
) -> Result<Response<Skill>, Status> {
|
|
||||||
// Return an instance of type HelloReply
|
|
||||||
println!("Got a request: {:?}", request);
|
|
||||||
|
|
||||||
let reply = Skill::default();
|
|
||||||
|
|
||||||
Ok(Response::new(reply)) // Send back our formatted greeting
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let addr = "[::1]:9090".parse()?;
|
let addr = "[::1]:9090".parse()?;
|
||||||
let greeter = MyGreeter::default();
|
let service = grpc::CofdApiService { db };
|
||||||
|
|
||||||
println!("Running tonic");
|
info!("Running Tonic");
|
||||||
Server::builder()
|
Server::builder()
|
||||||
.add_service(CofdApiServer::new(greeter))
|
.add_service(CofdApiServer::new(service))
|
||||||
.serve(addr)
|
.serve(addr)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!("ending tonic");
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn make_rocket(database: sqlx::SqlitePool) -> Result<(), Box<dyn std::error::Error>> {
|
async fn make_rocket(database: sqlx::SqlitePool) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
println!("Running rocket");
|
info!("Running Rocket");
|
||||||
let root_routes: Vec<rocket::Route> = {
|
let root_routes: Vec<rocket::Route> = {
|
||||||
routes::root::routes()
|
routes::root::routes()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -72,7 +52,6 @@ async fn make_rocket(database: sqlx::SqlitePool) -> Result<(), Box<dyn std::erro
|
||||||
|
|
||||||
rocket::ignite()
|
rocket::ignite()
|
||||||
.attach(Template::fairing())
|
.attach(Template::fairing())
|
||||||
//.attach(db::TenebrousDbConn::fairing())
|
|
||||||
.manage(database)
|
.manage(database)
|
||||||
.mount("/", root_routes)
|
.mount("/", root_routes)
|
||||||
.mount("/characters", character_routes)
|
.mount("/characters", character_routes)
|
||||||
|
@ -106,15 +85,19 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
migrator::migrate(db_path).await?;
|
migrator::migrate(db_path).await?;
|
||||||
|
|
||||||
let db = crate::db::create_pool(db_path).await?;
|
let db = crate::db::create_pool(db_path).await?;
|
||||||
// let tonic = gin_and_tonic();
|
|
||||||
// let rocket = make_rocket(db);
|
|
||||||
|
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
result = make_rocket(db) => {
|
result = make_rocket(db.clone()) => {
|
||||||
println!("done with rocket: {:?}", result);
|
match result {
|
||||||
|
Ok(_) => info!("Shutting down Rocket."),
|
||||||
|
Err(e) => error!("Rocket error: {}", e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result = gin_and_tonic() => {
|
result = make_tonic(db) => {
|
||||||
println!("done with tonic: {:?}", result);
|
match result {
|
||||||
|
Ok(_) => info!("Shutting down Tonic."),
|
||||||
|
Err(e) => error!("Tonic error: {}", e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue