| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| use crate::http::error::CustomError; |
| use crate::http::jwt::json_web_token::Identity; |
| use crate::http::shared::AppState; |
| use crate::shard::transmission::frame::ShardResponse; |
| use crate::shard::transmission::message::{ShardRequest, ShardRequestPayload}; |
| use axum::extract::{Path, Query, State}; |
| use axum::http::StatusCode; |
| use axum::routing::post; |
| use axum::{Extension, Json, Router, debug_handler}; |
| use iggy_binary_protocol::requests::partitions::{ |
| CreatePartitionsRequest as WireCreatePartitions, |
| DeletePartitionsRequest as WireDeletePartitions, |
| }; |
| use iggy_common::Identifier; |
| use iggy_common::Validatable; |
| use iggy_common::create_partitions::CreatePartitions; |
| use iggy_common::delete_partitions::DeletePartitions; |
| use iggy_common::wire_conversions::identifier_to_wire; |
| use std::sync::Arc; |
| use tracing::instrument; |
| |
| pub fn router(state: Arc<AppState>) -> Router { |
| Router::new() |
| .route( |
| "/streams/{stream_id}/topics/{topic_id}/partitions", |
| post(create_partitions).delete(delete_partitions), |
| ) |
| .with_state(state) |
| } |
| |
| #[debug_handler] |
| #[instrument(skip_all, name = "trace_create_partitions", fields(iggy_user_id = identity.user_id, iggy_stream_id = stream_id, iggy_topic_id = topic_id))] |
| async fn create_partitions( |
| State(state): State<Arc<AppState>>, |
| Extension(identity): Extension<Identity>, |
| Path((stream_id, topic_id)): Path<(String, String)>, |
| Json(mut command): Json<CreatePartitions>, |
| ) -> Result<StatusCode, CustomError> { |
| command.stream_id = Identifier::from_str_value(&stream_id)?; |
| command.topic_id = Identifier::from_str_value(&topic_id)?; |
| command.validate()?; |
| |
| let wire_command = WireCreatePartitions { |
| stream_id: identifier_to_wire(&command.stream_id)?, |
| topic_id: identifier_to_wire(&command.topic_id)?, |
| partitions_count: command.partitions_count, |
| }; |
| let request = ShardRequest::control_plane(ShardRequestPayload::CreatePartitionsRequest { |
| user_id: identity.user_id, |
| command: wire_command, |
| }); |
| |
| match state.shard.send_to_control_plane(request).await? { |
| ShardResponse::CreatePartitionsResponse => Ok(StatusCode::CREATED), |
| ShardResponse::ErrorResponse(err) => Err(err.into()), |
| _ => unreachable!("Expected CreatePartitionsResponse"), |
| } |
| } |
| |
| #[debug_handler] |
| #[instrument(skip_all, name = "trace_delete_partitions", fields(iggy_user_id = identity.user_id, iggy_stream_id = stream_id, iggy_topic_id = topic_id))] |
| async fn delete_partitions( |
| State(state): State<Arc<AppState>>, |
| Extension(identity): Extension<Identity>, |
| Path((stream_id, topic_id)): Path<(String, String)>, |
| mut query: Query<DeletePartitions>, |
| ) -> Result<StatusCode, CustomError> { |
| query.stream_id = Identifier::from_str_value(&stream_id)?; |
| query.topic_id = Identifier::from_str_value(&topic_id)?; |
| query.validate()?; |
| |
| let wire_command = WireDeletePartitions { |
| stream_id: identifier_to_wire(&query.stream_id)?, |
| topic_id: identifier_to_wire(&query.topic_id)?, |
| partitions_count: query.partitions_count, |
| }; |
| let request = ShardRequest::control_plane(ShardRequestPayload::DeletePartitionsRequest { |
| user_id: identity.user_id, |
| command: wire_command, |
| }); |
| |
| match state.shard.send_to_control_plane(request).await? { |
| ShardResponse::DeletePartitionsResponse => Ok(StatusCode::NO_CONTENT), |
| ShardResponse::ErrorResponse(err) => Err(err.into()), |
| _ => unreachable!("Expected DeletePartitionsResponse"), |
| } |
| } |