Skip to content

Commit

Permalink
EN-142 - enable global configuration settings (hyperledger-archives#15)
Browse files Browse the repository at this point in the history
* enable settings for global configuration (EN-142)

* EN-142 hyperledger-archives#2

* stabilize unit tests, small fix for EN-125

Signed-off-by: glowkey <douglas.wightman@evernym.com>
  • Loading branch information
glowkey authored and hadleym committed Oct 6, 2017
1 parent 6cc49cb commit 7d25ad7
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 29 deletions.
1 change: 1 addition & 0 deletions cxs/libcxs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ rand = "0.3"
serde = "1.0"
serde_json = "1.0"
serde_derive = "1.0"
config = "0.6"
2 changes: 1 addition & 1 deletion cxs/libcxs/include/cxs.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ typedef struct {
* Initialize the SDK
*/

cxs_error_t cxs_init();
cxs_error_t cxs_init(const char *config_path);


/**
Expand Down
100 changes: 76 additions & 24 deletions cxs/libcxs/src/api/cxs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,42 @@ use api::CxsStatus;
use utils::cstring::CStringUtils;
use utils::{pool, wallet};
use utils::error;
use connection::build_connection;
use connection::connect;
use connection::to_string;
use connection::get_state;
use connection::release;
use std::ffi::CString;
use settings;
use connection::{build_connection, connect, to_string, get_state, release};

#[no_mangle]
pub extern fn cxs_init (pool_name:*const c_char,
config_name:*const c_char,
wallet_name:*const c_char,
wallet_type:*const c_char) -> u32 {
check_useful_c_str!(pool_name,1001);
check_useful_c_str!(config_name,1001);
check_useful_c_str!(wallet_name,1001);
check_useful_c_str!(wallet_type,1001);
pub extern fn cxs_init (config_path:*const c_char) -> u32 {

settings::set_defaults();

if !config_path.is_null() {
check_useful_c_str!(config_path,error::UNKNOWN_ERROR.code_num);

if settings::process_config_file(&config_path) != error::SUCCESS.code_num {
return error::UNKNOWN_ERROR.code_num;
}
}

let config_name = match settings::get_config_value(settings::CONFIG_POOL_CONFIG_NAME) {
Err(x) => return x,
Ok(v) => v,
};

let pool_name = match settings::get_config_value(settings::CONFIG_POOL_NAME) {
Err(x) => return x,
Ok(v) => v,
};

let wallet_name = match settings::get_config_value(settings::CONFIG_WALLET_NAME) {
Err(x) => return x,
Ok(v) => v,
};

let wallet_type = match settings::get_config_value(settings::CONFIG_WALLET_TYPE) {
Err(x) => return x,
Ok(v) => v,
};

match pool::create_pool_config(&pool_name, &config_name) {
0 => 0,
x => return x,
Expand All @@ -31,7 +51,7 @@ pub extern fn cxs_init (pool_name:*const c_char,
x => return x,
};

return 0
return error::SUCCESS.code_num
}


Expand Down Expand Up @@ -75,7 +95,7 @@ pub extern fn cxs_connection_create(recipient_info: *const c_char, connection_ha

if connection_handle.is_null() {return error::UNKNOWN_ERROR.code_num}

let handle = build_connection("Whatever.".to_owned());
let handle = build_connection(recipient_info.to_owned());

unsafe { *connection_handle = handle }

Expand Down Expand Up @@ -158,19 +178,51 @@ pub extern fn cxs_proof_list_state(status_array: *mut CxsStatus) -> u32 { error:
#[allow(unused_variables, unused_mut)]
pub extern fn cxs_proof_get_state(proof_handle: u32, status: *mut c_char) -> u32 { error::SUCCESS.code_num }




#[cfg(test)]
mod tests {

use super::*;
use utils::error::UNKNOWN_ERROR;
use std::path::Path;
use std::ffi::CString;
use std::ptr;
use std::error::Error;
use std::io::prelude::*;
use std::fs;

#[test]
fn test_init_with_file() {
let config_path = "/tmp/test_init.json";
let path = Path::new(config_path);

let mut file = match fs::File::create(&path) {
Err(why) => panic!("couldn't create sample config file: {}", why.description()),
Ok(file) => file,
};

let content = "{ \"pool_name\" : \"my_pool\", \"config_name\":\"my_config\", \"wallet_name\":\"my_wallet\", \"wallet_type\":\"default\" }";
match file.write_all(content.as_bytes()) {
Err(why) => panic!("couldn't write to sample config file: {}", why.description()),
Ok(_) => println!("sample config ready"),
}

let result = cxs_init(CString::new(config_path).unwrap().into_raw());
assert_eq!(result,0);
// Leave file around or other concurrent tests will fail
//fs::remove_file(config_path).unwrap();
}

#[test]
fn test_init() {
let pool_name = CString::new("pool1").unwrap().into_raw();
let config_name = CString::new("config1").unwrap().into_raw();
let wallet_name = CString::new("wallet1").unwrap().into_raw();
let wallet_type = CString::new("default").unwrap().into_raw();
fn test_init_bad_path() {
let empty_str = CString::new("").unwrap().into_raw();
let result = cxs_init(pool_name, config_name, wallet_name, wallet_type);
assert_eq!(error::UNKNOWN_ERROR.code_num,cxs_init(empty_str));
}

#[test]
fn test_init_no_config_path() {
let result = cxs_init(ptr::null());
assert_eq!(result,0);
assert_eq!(UNKNOWN_ERROR.code_num,cxs_init(empty_str, config_name, wallet_name, wallet_type));
}
}
3 changes: 3 additions & 0 deletions cxs/libcxs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#![allow(dead_code)]
extern crate indy;
extern crate serde;
extern crate serde_json;
extern crate rand;
extern crate config;

use std::path::Path;

Expand All @@ -13,6 +15,7 @@ extern crate lazy_static;

#[macro_use]
mod utils;
mod settings;

pub mod api;
pub mod connection;
Expand Down
130 changes: 130 additions & 0 deletions cxs/libcxs/src/settings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
extern crate config;

use config::Config;
use std::sync::RwLock;
use utils::error;
use std::path::Path;


pub static CONFIG_POOL_NAME: &'static str = "pool_name";
pub static CONFIG_POOL_CONFIG_NAME: &'static str = "config_name";
pub static CONFIG_WALLET_NAME: &'static str = "wallet_name";
pub static CONFIG_WALLET_TYPE: &'static str = "wallet_type";
pub static CONFIG_AGENT_ENDPOINT: &'static str = "agent_endpoint";

lazy_static! {
static ref SETTINGS: RwLock<Config> = RwLock::new(Config::default());
}

pub fn set_defaults() -> u32 {

let mut settings = match SETTINGS.write() {
Err(_) => return error::UNKNOWN_ERROR.code_num,
Ok(y) => y,
};

settings.set_default(CONFIG_POOL_NAME,"pool1");
settings.set_default(CONFIG_POOL_CONFIG_NAME,"config1");
settings.set_default(CONFIG_WALLET_NAME,"wallet1");
settings.set_default(CONFIG_WALLET_TYPE,"default");
settings.set_default(CONFIG_AGENT_ENDPOINT,"http://127.0.0.1:8080");

error::SUCCESS.code_num
}

pub fn process_config_file(path: &str) -> u32 {

if !Path::new(path).is_file() {return error::UNKNOWN_ERROR.code_num}

match SETTINGS.write() {
Err(_) => return error::UNKNOWN_ERROR.code_num,
Ok(mut y) => y.merge(config::File::with_name(path)).unwrap(),
};

error::SUCCESS.code_num
}

pub fn get_config_value(key: &str) -> Result<String, u32> {

match SETTINGS.read() {
Err(_) => Err(error::UNKNOWN_ERROR.code_num),
Ok(y) => match y.get_str(key) {
Err(_) => Err(error::UNKNOWN_ERROR.code_num),
Ok(value) => Ok(value),
},
}
}


#[cfg(test)]
pub mod tests {
use std::error::Error;
use std::io::prelude::*;
use std::fs;
use super::*;

#[test]
fn test_invalid_config_value() {
match get_config_value("garbage") {
Err(x) => assert_eq!(x, error::UNKNOWN_ERROR.code_num),
Ok(v) => assert_eq!(v,"totalgarbage"), //if test gets here it will fail
};
}

#[test]
fn test_bad_path() {
//test bad path
let tmp_string = "garbage.txt";
let rc = process_config_file(&tmp_string);
assert_eq!(rc, error::UNKNOWN_ERROR.code_num);
}

#[test]
fn test_process_config_file() {
let a = "a";
let b = "b";
let c = "c";
let d = "d";

let config_path = "/tmp/test_settings.json";
let path = Path::new(config_path);

let mut file = match fs::File::create(&path) {
Err(why) => panic!("couldn't create sample config file: {}", why.description()),
Ok(file) => file,
};

let content = "{ \"a\" : \"a\", \"b\":\"b\", \"c\":\"c\", \"d\":\"d\" }";

match file.write_all(content.as_bytes()) {
Err(why) => panic!("couldn't write to sample config file: {}", why.description()),
Ok(_) => println!("sample config ready"),
}

let rc = process_config_file(&config_path);
assert_eq!(rc, error::SUCCESS.code_num);

match get_config_value(&a) {
Err(x) => assert_eq!(x, error::SUCCESS.code_num), //fail if we get here
Ok(v) => assert_eq!(v,a),
};

match get_config_value(&b) {
Err(x) => assert_eq!(x, error::SUCCESS.code_num), //fail if we get here
Ok(v) => assert_eq!(v,b),
};

match get_config_value(&c) {
Err(x) => assert_eq!(x, error::SUCCESS.code_num), //fail if we get here
Ok(v) => assert_eq!(v,c),
};

match get_config_value(&d) {
Err(x) => assert_eq!(x, error::SUCCESS.code_num), //fail if we get here
Ok(v) => assert_eq!(v,d),
};

// Leave file around or other concurrent tests will fail
//fs::remove_file(config_path).unwrap();
}
}
2 changes: 1 addition & 1 deletion cxs/wrappers/node/src/rustlib.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FFIConfiguration = {
'cxs_init': ['int', ['string', 'string', 'string', 'string']]
'cxs_init': ['int', ['string']]
};
6 changes: 3 additions & 3 deletions cxs/wrappers/node/test/index-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ describe('call to cxs_init with provided path', function() {
path += "/lib/libcxs.so";
var run = new CXSRuntime(new CXSRuntimeConfig(path));
it('should return 0', function () {
assert.equal(run.ffi.cxs_init('pool1', 'config1', 'wallet1','default'), 0);
assert.equal(run.ffi.cxs_init(null), 0);
})

it('should return 1002', function() {
assert.equal(run.ffi.cxs_init(' ', 'config1', 'wallet1','default'), 0);
it('should return 1001', function() {
assert.equal(run.ffi.cxs_init('garbage'), 1001);
})
});

0 comments on commit 7d25ad7

Please sign in to comment.