Add readme instructions, run proxy command.

This commit is contained in:
jeff 2021-01-03 21:24:52 +00:00
parent 06954caaaf
commit f479da9001
5 changed files with 98 additions and 52 deletions

View File

@ -6,6 +6,9 @@ edition = "2018"
build = "build.rs"
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]]
name = "tenebrous-migrate"
path = "src/migrate.rs"

View File

@ -4,41 +4,66 @@ An open source character sheet service for tabletop roleplaying games.
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
These are very basic build instructions. They assume you already have
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
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 cargo-run-script
cargo run --bin tenebrous-migrate
```
### Run Application
### Dependencies Required
If you are using `rustup`, then it should automatically switch to the
stable version of Rust in this repository. This is because of the
`rust-toolchain` file.
Dependencies required to build the project. The exact installation
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. 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:
```
cargo run-script grpc-proxy # only required if proxy not already running
cargo run
```
@ -65,4 +90,15 @@ to update the SQLx data JSON file:
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

24
src/grpc.rs Normal file
View File

@ -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
}
}

View File

@ -9,56 +9,36 @@ extern crate rocket_contrib;
#[macro_use]
extern crate serde_derive;
use log::{error, info};
use rocket_contrib::serve::StaticFiles;
use rocket_contrib::templates::Template;
use std::env;
use tonic::transport::Server;
pub mod catchers;
pub mod db;
pub mod errors;
pub mod grpc;
pub mod migrator;
pub mod models;
pub mod routes;
async fn gin_and_tonic() -> Result<(), Box<dyn std::error::Error>> {
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, 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
}
}
async fn make_tonic(db: sqlx::SqlitePool) -> Result<(), Box<dyn std::error::Error>> {
use crate::models::proto::cofd::api::cofd_api_server::CofdApiServer;
let addr = "[::1]:9090".parse()?;
let greeter = MyGreeter::default();
let service = grpc::CofdApiService { db };
println!("Running tonic");
info!("Running Tonic");
Server::builder()
.add_service(CofdApiServer::new(greeter))
.add_service(CofdApiServer::new(service))
.serve(addr)
.await?;
println!("ending tonic");
Ok(())
}
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> = {
routes::root::routes()
.into_iter()
@ -72,7 +52,6 @@ async fn make_rocket(database: sqlx::SqlitePool) -> Result<(), Box<dyn std::erro
rocket::ignite()
.attach(Template::fairing())
//.attach(db::TenebrousDbConn::fairing())
.manage(database)
.mount("/", root_routes)
.mount("/characters", character_routes)
@ -106,15 +85,19 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
migrator::migrate(db_path).await?;
let db = crate::db::create_pool(db_path).await?;
// let tonic = gin_and_tonic();
// let rocket = make_rocket(db);
tokio::select! {
result = make_rocket(db) => {
println!("done with rocket: {:?}", result);
result = make_rocket(db.clone()) => {
match result {
Ok(_) => info!("Shutting down Rocket."),
Err(e) => error!("Rocket error: {}", e)
}
}
result = make_tonic(db) => {
match result {
Ok(_) => info!("Shutting down Tonic."),
Err(e) => error!("Tonic error: {}", e)
}
result = gin_and_tonic() => {
println!("done with tonic: {:?}", result);
}
}