actix / actix-web

Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.
https://actix.rs
Apache License 2.0
21.6k stars 1.67k forks source link

Cassandra DB 'AlexPikalov/cdrs' connection pool is not configure #1207

Closed ayonsaha2011 closed 4 years ago

ayonsaha2011 commented 4 years ago

Cassandra DB 'AlexPikalov/cdrs' connection pool is not configure. Throw Error -

in console - DEBUG actix_web::data] Failed to construct App-level Data extractor. Request path: response App data is not configured, to configure use App::data()

There is any solution ?

My Code somthing like - `

 let node = NodeTcpConfigBuilder::new("127.0.0.1:9042", NoneAuthenticator {}).build();
    let cluster_config = ClusterTcpConfig(vec![node]);
    let lb = RoundRobinSync::new();
    let no_compression: Arc<CurrentSession> =
        Arc::new(new_session(&cluster_config, lb).expect("session should be created"));
    create_keyspace(&no_compression.clone());
    create_table(&no_compression.clone());
HttpServer::new(move || {
    App::new()
        .data(no_compression.clone())
         …..
})
.bind(&app_url)?
.start();

`

fafhrd91 commented 4 years ago
  1. casandra db is something outside of scope of actix
  2. App data is not configured means you use wrong type in your handler, differ from Arc<CurrentSession>
artem-v-shamsutdinov commented 4 years ago

The following runs for me (it did panic initially saying couldn't find prepared statement but is working now):

[macro_use]

extern crate cdrs;

use cdrs::authenticators::StaticPasswordAuthenticator; use cdrs::cluster::session::{new as new_session, Session}; use cdrs::cluster::{ClusterTcpConfig, NodeTcpConfigBuilder, TcpConnectionPool}; use cdrs::load_balancing::RoundRobinSync; use cdrs::query::; use cdrs::types::prelude::;

use actix_web::{middleware, web, App, Error, HttpRequest, HttpResponse, HttpServer, Result};

use std::sync::Arc; use cdrs::types::ByName;

type CurrentSession = Session<RoundRobinSync<TcpConnectionPool>>;

type GetWidgetPreparedQuery = PreparedQuery;

async fn getwidget( : HttpRequest, path: web::Path<(u64,String,u64,)>, session: web::Data\<Arc\<CurrentSession>>, group_widget_by_ids: web::Data\<Arc\<GetWidgetPreparedQuery>> ) -> Result<HttpResponse, Error> { let values_with_names = query_values!{ "group_id" => path.0, "date" => path.1.clone(), "widget_id" => path.2};

let rows = session.exec_with_values(
    &group_widget_by_ids,
    values_with_names)
    .expect("query_with_values")
    .get_body()
    .expect("get body")
    .into_rows()
    .expect("into rows");

if rows.len() == 1 {
    let widget_row: &Row = &rows[0];
    let bytes: Blob = widget_row.by_name("data").expect("data value").unwrap();
    Ok(HttpResponse::Ok()
        .body(bytes.into_vec()))
} else {
    Ok(HttpResponse::Ok().finish())
}

}

[actix_rt::main]

async fn main() -> std::io::Result<()> { let user = "cassandra"; let password = "cassandra"; let auth = StaticPasswordAuthenticator::new(&user, &password);

let node = NodeTcpConfigBuilder::new("127.0.0.1:9042", auth).build();
let cluster_config = ClusterTcpConfig(vec![node]);
let session = Arc::new(
    new_session(&cluster_config, RoundRobinSync::new()).expect("session should be created")
);

session.query("USE widgets;").expect("USE Keyspace error");

let group_widget_by_ids: Arc<GetWidgetPreparedQuery> = Arc::new(
    session.prepare_tw("SELECT data from widgets WHERE group_id = ? AND date = ? AND widget_id = ?", false, false).unwrap()
);

std::env::set_var("RUST_LOG", "actix_web=info");
env_logger::init();

HttpServer::new(move || {
    App::new()
        .data(session.clone())
        .data(group_widget_by_ids.clone())
        // enable logger
        .wrap(middleware::Logger::default())
        .service(web::resource("/index.html").to(|| async { "read-server" }))
        .service(web::resource("/get/getWidget/{groupId}/{date}/{widgetId}").route(web::get().to(get_widget)))
})
    .bind("127.0.0.1:8080")?
    .run()
    .await

}

Hope this helps, :)

Artem