Skip to content
This repository has been archived by the owner on Jul 17, 2023. It is now read-only.

Commit

Permalink
Merge pull request #4 from 21re/next2
Browse files Browse the repository at this point in the history
Preparing to merge with master
  • Loading branch information
Ihor authored Nov 20, 2020
2 parents 5361b69 + 3470272 commit a7e607d
Show file tree
Hide file tree
Showing 23 changed files with 2,767 additions and 1,815 deletions.
3,160 changes: 1,829 additions & 1,331 deletions Cargo.lock

Large diffs are not rendered by default.

29 changes: 15 additions & 14 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
[package]
name = "microtools"
version = "0.1.0"
version = "0.2.0"
authors = ["Bodo Junglas <[email protected]>", "Ihor Mordashev <[email protected]"]
edition = "2018"

[dependencies]
actix = "0.7"
actix-web = "0.7"
actix = "0.9"
actix-web = "3.2"
awc = "1"
serde = { version = "1.0", features = ["rc"] }
serde_derive = "1.0"
serde_json = "1.0"
futures = "0.1"
futures = "0.3"

toml = { version = "0.4", optional = true }
log = "0.4"
bytes = "0.4.10"
bytes = "0.5"
prometheus = { version = "0.5", features = ["process"] }
chrono = { version = "0.4", features = ["serde"], optional = true }
slog = { version = "2.4", optional = true }
slog-envlogger = { version = "2.1", optional = true }
slog-async = { version = "2.3", optional = true }
slog-json = { version = "2.2", optional = true }
slog-stdlog = { version = "3.0", optional = true }
slog-scope = { version = "4.0", optional = true }
slog = { version = "2.5", optional = true }
slog-envlogger = { version = "2.2", optional = true }
slog-async = { version = "2.5", optional = true }
slog-json = { version = "2.3", optional = true }
slog-stdlog = { version = "4.0", optional = true }
slog-scope = { version = "4.3", optional = true }
r2d2 = { version = "0.8", optional = true }
diesel = { version = "1.3", optional = true }
url = { version = "1.7", features = ["query_encoding"] }
reqwest = { version = "0.9", optional = true }
url = { version = "2" }
reqwest = { version = "0.10", features = ["json", "stream"] }
config = { version = "0.9", optional = true }

[dev-dependencies]
Expand All @@ -35,5 +37,4 @@ spectral = "0.6"
with-toml = ["toml"]
with-slog = ["slog", "slog-envlogger", "slog-async", "slog-json", "slog-stdlog", "slog-scope", "chrono"]
with-diesel = ["r2d2", "diesel"]
with-reqwest = ["reqwest"]
with-config = ["config"]
27 changes: 27 additions & 0 deletions legacy/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
pub mod auth_middleware;
pub mod business_result;
pub mod elasticsearch;
#[cfg(test)]
pub mod elasticsearch_test;
pub mod gatekeeper;
#[cfg(feature = "with-slog")]
pub mod logging_slog;
pub mod metrics;
pub mod parse_request;
mod problem;
pub mod retry;
#[cfg(test)]
mod retry_tests;
pub mod serde_field_value;
pub mod service_requester;
#[cfg(test)]
mod service_requester_test;
pub mod status;
pub mod subject;
pub mod types;
pub mod ws_try;

pub use crate::business_result::{AsyncBusinessResult, BusinessResult, BusinessResultExt};
pub use crate::parse_request::*;
pub use crate::problem::*;
pub use crate::service_requester::*;
File renamed without changes.
268 changes: 268 additions & 0 deletions legacy/problem.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
use actix;
use actix_web;
use log::error;
use serde_derive::{Deserialize, Serialize};
use serde_json;
use std;

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Problem {
pub code: u16,
#[serde(rename = "type")]
pub problem_type: String,
pub reason: String,
pub details: Option<String>,
}

impl Problem {
pub fn for_status<S: Into<String>>(code: u16, reason: S) -> Problem {
Problem {
code,
problem_type: format!("https://httpstatus.es/{}", code),
reason: reason.into(),
details: None,
}
}

pub fn bad_request() -> Problem {
Self::for_status(400, "Bad request")
}

pub fn unauthorized() -> Problem {
Self::for_status(401, "Unauthorized")
}

pub fn forbidden() -> Problem {
Self::for_status(403, "Forbidden")
}

pub fn conflict() -> Problem {
Self::for_status(409, "Conflict")
}

pub fn internal_server_error() -> Problem {
Self::for_status(500, "Internal server error")
}

pub fn not_found() -> Problem {
Self::for_status(404, "Not found")
}

pub fn method_not_allowed() -> Problem {
Self::for_status(405, "Method not allowed")
}

pub fn failed_dependency() -> Problem {
Self::for_status(424, "Failed dependency")
}

pub fn with_details<T: std::fmt::Display>(mut self, details: T) -> Problem {
self.details = match self.details {
Some(existing) => Some(format!("{}: {}", existing, details)),
None => Some(format!("{}", details)),
};
self
}
}

impl std::fmt::Display for Problem {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
match self.details {
Some(ref details) => write!(
f,
"Problem(code={}, reason={}, details={})",
self.code, self.reason, details
)?,
None => write!(f, "Problem(code={}, reason={})", self.code, self.reason)?,
};
Ok(())
}
}

impl std::error::Error for Problem {}

impl From<std::env::VarError> for Problem {
fn from(error: std::env::VarError) -> Problem {
use std::env::VarError::*;

match error {
NotPresent => Problem::internal_server_error().with_details("Environment variable missing"),
NotUnicode(_) => Problem::internal_server_error().with_details("Environment variable not unicode"),
}
}
}

impl From<std::io::Error> for Problem {
fn from(error: std::io::Error) -> Problem {
error!("IO: {}", error);

Problem::internal_server_error().with_details(format!("IO: {}", error))
}
}

impl<T> From<std::sync::PoisonError<T>> for Problem {
fn from(error: std::sync::PoisonError<T>) -> Problem {
error!("Sync poison: {}", error);

Problem::internal_server_error().with_details(format!("Sync poison: {}", error))
}
}

impl From<std::time::SystemTimeError> for Problem {
fn from(error: std::time::SystemTimeError) -> Problem {
error!("SystemTime error: {}", error);

Problem::internal_server_error().with_details(format!("SystemTime error: {}", error))
}
}

impl From<std::str::Utf8Error> for Problem {
fn from(error: std::str::Utf8Error) -> Problem {
error!("UTF-8 error: {}", error);

Problem::bad_request().with_details(format!("UTF-8 error: {}", error))
}
}

impl From<actix_web::error::Error> for Problem {
fn from(error: actix_web::Error) -> Problem {
error!("Actix: {}", error);

Problem::internal_server_error().with_details(format!("Actix: {}", error))
}
}

impl actix_web::error::ResponseError for Problem {
fn error_response(&self) -> actix_web::HttpResponse {
actix_web::HttpResponse::build(
actix_web::http::StatusCode::from_u16(self.code).unwrap_or(actix_web::http::StatusCode::INTERNAL_SERVER_ERROR),
)
.json(self)
}
}

impl actix_web::Responder for Problem {
type Item = actix_web::HttpResponse;
type Error = Problem;

fn respond_to<S: 'static>(self, _req: &actix_web::HttpRequest<S>) -> Result<actix_web::HttpResponse, Problem> {
Ok(
actix_web::HttpResponse::build(
actix_web::http::StatusCode::from_u16(self.code).unwrap_or(actix_web::http::StatusCode::INTERNAL_SERVER_ERROR),
)
.json(self),
)
}
}

impl From<actix_web::client::SendRequestError> for Problem {
fn from(error: actix_web::client::SendRequestError) -> Problem {
use actix_web::client::SendRequestError::*;

error!("Http client: {}", error);

match error {
Timeout => Problem::internal_server_error().with_details("Request timeout"),
Connector(err) => Problem::internal_server_error().with_details(format!("HTTP connection error: {}", err)),
ParseError(err) => Problem::internal_server_error().with_details(format!("Invalid HTTP response: {}", err)),
Io(err) => Problem::from(err),
}
}
}

impl From<actix_web::error::PayloadError> for Problem {
fn from(error: actix_web::error::PayloadError) -> Self {
error!("Http payload: {}", error);
Problem::internal_server_error().with_details(format!("Http payload: {}", error))
}
}

impl From<actix_web::error::ReadlinesError> for Problem {
fn from(error: actix_web::error::ReadlinesError) -> Self {
use actix_web::error::ReadlinesError::*;

match error {
EncodingError => Problem::internal_server_error().with_details("Readline: Invalid encoding"),
PayloadError(error) => Problem::from(error),
LimitOverflow => Problem::internal_server_error().with_details("Readline: Limit exeeded"),
ContentTypeError(error) => Problem::from(error),
}
}
}

impl From<actix_web::error::ContentTypeError> for Problem {
fn from(error: actix_web::error::ContentTypeError) -> Self {
error!("Http content type: {}", error);

Problem::internal_server_error().with_details(format!("Http content type: {}", error))
}
}

impl From<actix_web::error::JsonPayloadError> for Problem {
fn from(error: actix_web::error::JsonPayloadError) -> Self {
error!("Http json type: {}", error);

Problem::internal_server_error().with_details(format!("Http json payload: {}", error))
}
}

impl From<actix::MailboxError> for Problem {
fn from(error: actix::MailboxError) -> Self {
error!("Actix mailbox error: {}", error);

Problem::internal_server_error().with_details(format!("Actix mailbox error: {}", error))
}
}

#[cfg(feature = "with-toml")]
impl From<::toml::de::Error> for Problem {
fn from(error: ::toml::de::Error) -> Self {
error!("Toml: {}", error);

Problem::internal_server_error().with_details(format!("Toml: {}", error))
}
}

impl From<serde_json::Error> for Problem {
fn from(error: serde_json::Error) -> Self {
error!("Json: {}", error);

Problem::internal_server_error().with_details(format!("Json: {}", error))
}
}

#[cfg(feature = "with-diesel")]
impl From<::r2d2::Error> for Problem {
fn from(error: ::r2d2::Error) -> Self {
error!("R2D2: {}", error);

Problem::internal_server_error().with_details(format!("R2D2: {}", error))
}
}

#[cfg(feature = "with-diesel")]
impl From<::diesel::result::Error> for Problem {
fn from(error: ::diesel::result::Error) -> Self {
error!("Diesel result: {}", error);

Problem::internal_server_error().with_details(format!("Diesel result: {}", error))
}
}

#[cfg(feature = "with-reqwest")]
impl From<::reqwest::Error> for Problem {
fn from(error: ::reqwest::Error) -> Self {
error!("Reqwest error: {}", error);

Problem::internal_server_error().with_details(format!("Request result: {}", error))
}
}

#[cfg(feature = "with-config")]
impl From<::config::ConfigError> for Problem {
fn from(error: ::config::ConfigError) -> Self {
error!("Config error: {}", error);

Problem::internal_server_error().with_details(format!("Config: {}", error))
}
}
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit a7e607d

Please sign in to comment.