Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 10 additions & 21 deletions angular-client/src/api/rules.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,21 @@ export interface RulesResponse {
client_rules: ClientRule[];
}

const basicAuthHeader = (clientId: string): string => 'Basic ' + btoa(`${clientId}:`);

export const getRulesByClientId = (clientId: string): Promise<Response> => {
return fetch(urls.getRulesByClientId(clientId));
};

export const addRule = (clientId: string, rule: RulePayload): Promise<Response> => {
return fetch(urls.addRule(), {
return fetch(urls.addRule(clientId), {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Authorization: basicAuthHeader(clientId)
},
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(rule)
});
};

export const deleteRule = (clientId: string, ruleId: string): Promise<Response> => {
return fetch(urls.deleteRule(ruleId), {
method: 'POST',
headers: { Authorization: basicAuthHeader(clientId) }
return fetch(urls.deleteRule(clientId, ruleId), {
method: 'POST'
});
};

Expand All @@ -53,23 +47,18 @@ export const editRule = (ruleId: string, rule: object): Promise<Response> => {
});
};

export interface RuleSubscriptionRequest {
rule_ids: string[];
client_id: string;
}

export const subscribeToRules = (request: RuleSubscriptionRequest): Promise<Response> => {
return fetch(urls.subscribeToRule(), {
export const subscribeToRules = (clientId: string, ruleIds: string[]): Promise<Response> => {
return fetch(urls.subscribeToRule(clientId), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request)
body: JSON.stringify(ruleIds)
});
};

export const unsubscribeFromRules = (request: RuleSubscriptionRequest): Promise<Response> => {
return fetch(urls.unsubscribeFromRule(), {
export const unsubscribeFromRules = (clientId: string, ruleIds: string[]): Promise<Response> => {
return fetch(urls.unsubscribeFromRule(clientId), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request)
body: JSON.stringify(ruleIds)
});
};
8 changes: 4 additions & 4 deletions angular-client/src/api/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ const carCommandConfig = (key: string, values: number[]) =>

/* Rules */
const getRulesByClientId = (clientId: string) => `${baseURL}/rules/${clientId}`;
const addRule = () => `${baseURL}/rules/add`;
const deleteRule = (ruleId: string) => `${baseURL}/rules/delete/${ruleId}`;
const addRule = (clientId: string) => `${baseURL}/rules/${clientId}/add`;
const deleteRule = (clientId: string, ruleId: string) => `${baseURL}/rules/${clientId}/delete/${ruleId}`;
const editRule = (ruleId: string) => `${baseURL}/rules/edit/${ruleId}`;
const subscribeToRule = () => `${baseURL}/rules/subscribe`;
const unsubscribeFromRule = () => `${baseURL}/rules/unsubscribe`;
const subscribeToRule = (clientId: string) => `${baseURL}/rules/${clientId}/subscribe`;
const unsubscribeFromRule = (clientId: string) => `${baseURL}/rules/${clientId}/unsubscribe`;

/* Authentication */
const authenticate = () => `${baseURL}/authenticate`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@ export default class NotificationRulesPageComponent implements OnInit {
try {
const promises: Promise<Response>[] = [];
if (toSubscribe.length > 0) {
promises.push(subscribeToRules({ rule_ids: toSubscribe, client_id: this.clientId }));
promises.push(subscribeToRules(this.clientId, toSubscribe));
}
if (toUnsubscribe.length > 0) {
promises.push(unsubscribeFromRules({ rule_ids: toUnsubscribe, client_id: this.clientId }));
promises.push(unsubscribeFromRules(this.clientId, toUnsubscribe));
}

const results = await Promise.all(promises);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ export class RulesTableComponent implements OnInit {
}

async onToggleSubscription(rule: ClientRule, subscribed: boolean): Promise<void> {
const request = { rule_ids: [rule.id], client_id: this.clientId() };
const ruleIds = [rule.id];
try {
const response = subscribed ? await subscribeToRules(request) : await unsubscribeFromRules(request);
const response = subscribed
? await subscribeToRules(this.clientId(), ruleIds)
: await unsubscribeFromRules(this.clientId(), ruleIds);
if (response.ok) {
this.rules.update((rules) => rules.map((r) => (r.id === rule.id ? { ...r, is_subscribed: subscribed } : r)));
} else {
Expand Down
25 changes: 0 additions & 25 deletions scylla-server/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion scylla-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ tracing = "0.1.43"
tracing-subscriber = { version = "0.3.23", features = ["ansi", "env-filter"] }
console-subscriber = { version = "0.5.0", optional = true }
ringbuffer = "0.16.0"
axum-extra = { version = "0.12.5", features = ["query", "typed-header"] }
axum-extra = { version = "0.12.5", features = ["query"] }
clap = { version = "4.6.0", features = ["derive", "env"] }
chrono = { version = "0.4.43", features = ["serde"] }
serde_json = "1.0.149"
Expand Down
56 changes: 18 additions & 38 deletions scylla-server/src/controllers/rule_controller.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
use std::sync::Arc;

use axum::{Extension, Json, debug_handler, extract::Path};
use axum_extra::{
TypedHeader,
headers::{Authorization, authorization::Basic},
};
use serde::Deserialize;
use serde_with::DurationSeconds;
use serde_with::serde_as;
Expand All @@ -16,45 +12,27 @@ use crate::{
rule_structs::{ClientId, Rule, RuleId, RuleManager, RulesResponse},
};

#[derive(Deserialize)]
pub struct RuleSubscriptionRequest {
rule_ids: Vec<String>,
client_id: String,
}

#[debug_handler]
pub async fn add_rule(
TypedHeader(auth): TypedHeader<Authorization<Basic>>,
Path(client_id): Path<String>,
Extension(rules_manager): Extension<Arc<RuleManager>>,
Json(rule): Json<Rule>,
) -> Result<Json<String>, ScyllaError> {
info!(
"Incoming rules reg: {}, from {}",
rule.topic,
auth.username().to_string()
);
match rules_manager
.add_rule(ClientId(auth.username().to_string()), rule)
.await
{
info!("Incoming rules reg: {}, from {}", rule.topic, client_id);
match rules_manager.add_rule(ClientId(client_id), rule).await {
Ok(_) => Ok(Json::from("Rule added!".to_owned())),
Err(err) => Err(ScyllaError::RuleError(err)),
}
}

#[debug_handler]
pub async fn delete_rule(
TypedHeader(auth): TypedHeader<Authorization<Basic>>,
Path((client_id, rule_id)): Path<(String, String)>,
Extension(rules_manager): Extension<Arc<RuleManager>>,
Path(rule_id): Path<String>,
) -> Result<(), ScyllaError> {
info!(
"Incoming rules del: {}, from {}",
rule_id,
auth.username().to_string()
);
info!("Incoming rules del: {}, from {}", rule_id, client_id);
match rules_manager
.delete_rule(ClientId(auth.username().to_string()), RuleId(rule_id))
.delete_rule(ClientId(client_id), RuleId(rule_id))
.await
{
Ok(_) => Ok(()),
Expand Down Expand Up @@ -126,19 +104,20 @@ pub async fn edit_rule(

#[debug_handler]
pub async fn unsubscribe_rules(
Path(client_id): Path<String>,
Extension(rules_manager): Extension<Arc<RuleManager>>,
Json(request): Json<RuleSubscriptionRequest>,
Json(rule_ids): Json<Vec<String>>,
) -> Result<Json<String>, ScyllaError> {
info!(
"Unsubscribing client {} from {} rules",
request.client_id,
request.rule_ids.len()
client_id,
rule_ids.len()
);

let rule_ids: Vec<RuleId> = request.rule_ids.into_iter().map(RuleId).collect();
let rule_ids: Vec<RuleId> = rule_ids.into_iter().map(RuleId).collect();

match rules_manager
.unsubscribe_rules(ClientId(request.client_id), rule_ids)
.unsubscribe_rules(ClientId(client_id), rule_ids)
.await
{
Ok(_) => Ok(Json::from(
Expand All @@ -150,19 +129,20 @@ pub async fn unsubscribe_rules(

#[debug_handler]
pub async fn subscribe_rules(
Path(client_id): Path<String>,
Extension(rules_manager): Extension<Arc<RuleManager>>,
Json(request): Json<RuleSubscriptionRequest>,
Json(rule_ids): Json<Vec<String>>,
) -> Result<Json<String>, ScyllaError> {
info!(
"Subscribing client {} to {} rules",
request.client_id,
request.rule_ids.len()
client_id,
rule_ids.len()
);

let rule_ids: Vec<RuleId> = request.rule_ids.into_iter().map(RuleId).collect();
let rule_ids: Vec<RuleId> = rule_ids.into_iter().map(RuleId).collect();

match rules_manager
.subscribe_rules(ClientId(request.client_id), rule_ids)
.subscribe_rules(ClientId(client_id), rule_ids)
.await
{
Ok(_) => Ok(Json::from("Successfully subscribed to rules".to_owned())),
Expand Down
11 changes: 5 additions & 6 deletions scylla-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,18 +440,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
)
.merge(
Router::new()
.route("/rules/add", put(add_rule))
.route("/rules/delete/{rule_id}", post(delete_rule))
.route("/rules", get(get_all_rules))
.route("/rules/{client_id}", get(get_all_rules_with_client_info))
.route("/rules/{client_id}/add", put(add_rule))
.route("/rules/{client_id}/delete/{rule_id}", post(delete_rule))
.route(
"/rules/subscribed/{client_id}",
"/rules/{client_id}/subscribed",
get(get_client_subscribed_rules),
)
.route("/rules/unsubscribe", post(unsubscribe_rules))
.route("/rules/{client_id}/subscribe", post(subscribe_rules))
.route("/rules/{client_id}/unsubscribe", post(unsubscribe_rules))
.route("/rules/edit/{rule_id}", put(edit_rule))
.route("/rules/subscribe", post(subscribe_rules))
//.route("/rules/delete/{rule_id}", post()).route("/rules/poll")
.layer(Extension(rules_manager)),
)
// for CORS handling
Expand Down