Skip to content

Commit

Permalink
Demo 03 07 (#81)
Browse files Browse the repository at this point in the history
* added check if output folder exists then prompts for if it should be repalced

* refactored function out of main

* load data into .env file, write multiple templates, tree structure in template folder, service reads .env file

* splitted model and helper functions into own folders

* moved utils into correct folder

* removed unneeded log

* completed merge

* fixed bug with some producer handlers not being created

* made publish handlers more usable

* corrected path

* fix

* added simple cli to microservice

* clippy

* fixed streams compiling

---------

Co-authored-by: Aro <rother@mail.tu-berlin.de>
  • Loading branch information
doepnern and Aro authored Jul 3, 2023
1 parent 19b39f2 commit 94247d1
Show file tree
Hide file tree
Showing 23 changed files with 596 additions and 241 deletions.
67 changes: 67 additions & 0 deletions example/demo/automatic_lighting.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
asyncapi: '2.6.0'
info:
title: automatic lighting
version: '1.0.0'
description: |
The Smartylighting Streetlights API allows you to remotely manage the city lights.
### Check out its awesome features:
* Turn a specific streetlight on/off 🌃
* Receive real-time information about environmental lighting conditions 📈
servers:
dev:
url: localhost:4022
protocol: nats
description: Nats message broker
channels:
lightMeasured:
description: The topic on which measured values may be produced and consumed.
publish:
summary: Inform about environmental lighting conditions of a particular streetlight.
operationId: receiveLightMeasurement
message:
$ref: '#/components/messages/lightMeasured'
turnOnStreetlight:
subscribe:
operationId: turnOn
message:
$ref: '#/components/messages/turnOnOff'
turnOffStreetlight:
subscribe:
operationId: turnOff
message:
$ref: '#/components/messages/turnOnOff'
components:
messages:
lightMeasured:
name: lightMeasured
title: Light measured
summary: Inform about environmental lighting conditions of a particular streetlight.
contentType: application/json
payload:
$ref: "#/components/schemas/lightMeasuredPayload"
turnOnOff:
name: turnOnOff
title: Turn on/off
summary: Command a particular streetlight to turn the lights on or off.
payload:
$ref: "#/components/schemas/turnOnOffPayload"
schemas:
lightMeasuredPayload:
type: object
properties:
lumens:
type: integer
minimum: 0
description: Light intensity measured in lumens.
turnOnOffPayload:
type: object
properties:
lightId:
type: string
command:
type: string
enum:
- on
- off
description: Whether to turn on or off the light.

14 changes: 11 additions & 3 deletions example/specs/basic_queues_and_stream.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
asyncapi: 2.1.0
info:
title: My_API
title: queue_and_stream_api
version: 1.0.0
servers:
production:
Expand All @@ -11,7 +11,7 @@ channels:
subscribe:
bindings:
nats:
streamname: testStream
x-streamname: testStream
operationId: onUserSignup
summary: User signup notification
message:
Expand All @@ -27,7 +27,7 @@ channels:
publish:
bindings:
nats:
streamname: testStream
x-streamname: testStream
operationId: userSignedUp
summary: send welcome email to user
message:
Expand All @@ -53,6 +53,10 @@ channels:
properties:
userBought:
type: string
quantity:
type: number
timestamp:
type: string
publish:
bindings:
nats:
Expand All @@ -65,6 +69,10 @@ channels:
properties:
userBought:
type: string
quantity:
type: number
credit:
type: boolean
user/sell:
subscribe:
operationId: userSold
Expand Down
110 changes: 110 additions & 0 deletions example/specs/basic_queues_and_stream_messages.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
asyncapi: 2.1.0
info:
title: queue_and_stream_api
version: 1.0.0
servers:
production:
url: demo.nats.io
protocol: nats
channels:
user/signedup:
subscribe:
bindings:
nats:
x-streamname: testStream
operationId: onUserSignup
summary: User signup notification
message:
payload:
type: object
properties:
userSingnedUp:
type: string
userID:
type: number
timestamp:
type: string
publish:
bindings:
nats:
x-streamname: testStream
operationId: userSignedUp
summary: send welcome email to user
message:
payload:
type: object
properties:
userSingnedUp:
type: string
userID:
type: number
timestamp:
type: string
user/buy:
subscribe:
bindings:
nats:
queue: MyQueue
operationId: userBought
summary: User bought something
message:
payload:
type: object
properties:
userBought:
type: string
quantity:
type: number
timestamp:
type: string
examples:
- name: simpleExample
payload:
userBought: "something"
quantity: 1
timestamp: "2020-01-01T00:00:00Z"
publish:
bindings:
nats:
queue: MyQueue
operationId: onUserBought
summary: send email to user
message:
payload:
type: object
properties:
userBought:
type: string
quantity:
type: number
credit:
type: boolean
examples:
- name: secondExample
payload:
userBought: "something else"
quantity: 3
credit: true
user/sell:
subscribe:
operationId: userSold
summary: User sold something
message:
payload:
type: object
properties:
soldItem:
type: string
timestamp:
type: string
publish:
operationId: onUserSold
summary: send email to user
message:
payload:
type: object
properties:
soldItem:
type: string
timestamp:
type: string
2 changes: 2 additions & 0 deletions src/asyncapi_model/operation_binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ pub struct NATSOperationBinding {
/// The version of this binding. If omitted, "latest" MUST be assumed.
#[serde(skip_serializing_if = "Option::is_none")]
pub binding_version: Option<String>,

#[serde(rename(deserialize = "x-streamname", serialize = "streamname"))]
pub streamname: Option<String>,
}

Expand Down
63 changes: 59 additions & 4 deletions src/generator/common.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
use gtmpl::Context;

use crate::utils;
use crate::{template_context::TemplateContext, utils};
use std::{
ffi::OsStr,
fs,
path::{Path, PathBuf},
process::{Command, Output},
vec,
};

pub fn check_for_overwrite(output_path: &Path, project_title: &str) {
//check if project with name already exists, if yes ask for permission to overwrite
if output_path.exists() {
let warn_message = format!("A project with the name {} already exists in the current directory, do you want to overwrite the existing project? \nWARNING: This will delete all files in the directory and all applied. \nType 'y' to continue or anything else to exit.",project_title);
println!("{}", warn_message);
let mut input = String::new();
match std::io::stdin().read_line(&mut input) {
Ok(_) => {
if input.trim() != "y" {
println!("Aborting generation...");
std::process::exit(0);
}
std::fs::remove_dir_all(output_path).unwrap();
}
Err(err) => {
println!("❌ Error reading input: {}", err);
std::process::exit(1);
}
}
}
}

/// initialize a cargo project in path
pub fn cargo_init_project(path: impl AsRef<OsStr>) -> Output {
Command::new("cargo")
Expand Down Expand Up @@ -39,7 +62,6 @@ pub fn cargo_fix(path: &PathBuf) -> Output {
}

fn key_exists(args: &[gtmpl_value::Value]) -> Result<gtmpl_value::Value, gtmpl_value::FuncError> {
println!("{:?}", args);
if args.is_empty() {
return Err(gtmpl_value::FuncError::AtLeastXArgs(
"Need at least 1 arg for key exists".to_string(),
Expand Down Expand Up @@ -94,7 +116,11 @@ pub fn template_render_write(
let template = match fs::read_to_string(template_path) {
Ok(template) => template,
Err(e) => {
eprintln!("❌ Error reading template: {}", e);
eprintln!(
"❌ Error reading template {:#?}: {}",
template_path.to_str(),
e
);
std::process::exit(1);
}
};
Expand All @@ -103,13 +129,19 @@ pub fn template_render_write(
base_template
.parse(&template)
.expect("failed to parse template");
let render = match base_template.render(&Context::from(context_ref.into())) {
let mut render = match base_template.render(&Context::from(context_ref.into())) {
Ok(render) => render,
Err(e) => {
eprintln!("❌ Error rendering template: {}", e);
std::process::exit(1);
}
};
if output_path.ends_with(".env") {
let mut lines: Vec<&str> = render.split('\n').collect();
lines.retain(|&x| x.trim() != "");
render = lines.join("\n");
}

match utils::write_to_path_create_dir(&render, output_path) {
Ok(_) => (),
Err(e) => {
Expand All @@ -119,6 +151,29 @@ pub fn template_render_write(
}
}

pub fn write_multiple_templates(
template_path: &Path,
context_ref: &TemplateContext,
output_path: &Path,
endings: &[&str],
) {
for ending in endings {
if ending.ends_with(".go") {
template_render_write(
&template_path.join(ending),
context_ref,
&output_path.join(ending).with_extension("rs"),
);
} else {
template_render_write(
&template_path.join(ending),
context_ref,
&output_path.join(ending),
);
}
}
}

pub fn cargo_generate_rustdoc(path: &Path) {
Command::new("cargo")
.current_dir(path)
Expand Down
5 changes: 4 additions & 1 deletion src/generator/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
mod common;
mod model;
pub use common::{
cargo_fix, cargo_fmt, cargo_generate_rustdoc, cargo_init_project, template_render_write,
cargo_fix, cargo_fmt, cargo_generate_rustdoc, cargo_init_project, check_for_overwrite,
template_render_write, write_multiple_templates,
};
pub use model::generate_models_folder;
Loading

0 comments on commit 94247d1

Please sign in to comment.