use std::io::{Error, ErrorKind};
use launchdarkly_server_sdk::{PersistentDataStore, PersistentDataStoreFactory};
use crate::data_store::RedisPersistentDataStore;
const DEFAULT_URL: &str = "redis://localhost:6379";
const DEFAULT_PREFIX: &str = "launchdarkly";
pub struct RedisPersistentDataStoreFactory {
url: String,
prefix: String,
}
impl RedisPersistentDataStoreFactory {
pub fn new() -> Self {
Self {
url: String::from(DEFAULT_URL),
prefix: String::from(DEFAULT_PREFIX),
}
}
pub fn prefix(&mut self, prefix: &str) -> &mut Self {
self.prefix = prefix.into();
self
}
pub fn url(&mut self, url: &str) -> &mut Self {
self.url = url.into();
self
}
}
impl Default for RedisPersistentDataStoreFactory {
fn default() -> Self {
Self::new()
}
}
impl PersistentDataStoreFactory for RedisPersistentDataStoreFactory {
fn create_persistent_data_store(&self) -> Result<Box<dyn PersistentDataStore>, Error> {
let prefix = self.prefix.clone();
let url = self.url.clone();
let client =
redis::Client::open(url).map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
Ok(Box::new(RedisPersistentDataStore::new(client, prefix)))
}
}
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use std::panic;
use super::RedisPersistentDataStoreFactory;
use super::{DEFAULT_PREFIX, DEFAULT_URL};
use launchdarkly_server_sdk::{AllData, PersistentDataStoreFactory};
#[test]
fn factory_is_initialized_with_defaults() {
let factory = RedisPersistentDataStoreFactory::new();
assert_eq!(factory.prefix, DEFAULT_PREFIX);
assert_eq!(factory.url, DEFAULT_URL);
}
#[test]
fn factory_can_have_defaults_changed() {
let mut factory = RedisPersistentDataStoreFactory::new();
factory
.prefix("new-prefix")
.url("redis://remote-host.com:9999");
assert_eq!(factory.prefix, "new-prefix");
assert_eq!(factory.url, "redis://remote-host.com:9999");
}
#[test]
fn factory_returns_error_on_invalid_url() {
let mut factory = RedisPersistentDataStoreFactory::new();
factory.url("localhost:10000");
let result = factory.create_persistent_data_store();
assert!(result.is_err());
}
#[test]
fn factory_can_create_store_that_cannot_connect() {
let mut factory = RedisPersistentDataStoreFactory::new();
factory.url("redis://localhost:9999");
let result = factory.create_persistent_data_store();
assert!(result.is_ok());
let mut store = result.unwrap();
let result = store.init(AllData {
flags: HashMap::new(),
segments: HashMap::new(),
});
if let Err(_) = result {
} else {
panic!("store.init failed to return a connection error");
}
}
}