Skip to content

Commit

Permalink
Merge pull request #10 from sparkhom/carmine
Browse files Browse the repository at this point in the history
use carmine instead of redis-clojure
  • Loading branch information
pelle committed Sep 23, 2013
2 parents 73476a7 + 4637771 commit 855c24f
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 94 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
@@ -1,2 +1,4 @@
---
language: clojure
lein: lein2
services:
- redis-server
29 changes: 11 additions & 18 deletions README.md
Expand Up @@ -106,7 +106,7 @@ There is a generalized protocol called Store and currently a simple memory imple

It should be pretty simple to implement this Store with redis, sql, datomic or what have you.

It includes a simple Redis implementation.
It includes a simple Redis implementation based on Carmine.

The stores used by the various parts are defined in an atom for each type. reset! each of them with your own implementation.

Expand All @@ -120,23 +120,16 @@ The following stores are currently defined:
To use the redis store add the following to your code:

```clojure
(reset! token-store (create-redis-store "tokens"))
(reset! auth-code-store (create-redis-store "auth-codes"))
(reset! client-store (create-redis-store "clients"))
(reset! user-store (create-redis-store "users"))
```

And wrap your handler with a redis connection middleware similar to this:

```clojure
(defn wrap-redis-store [app]
(fn [req]
(redis/with-server
{:host "127.0.0.1"
:port 6379
:db 14
}
(app req))))
(def server-conn
{:pool {}
:spec {:host "127.0.0.1"
:port 6379
:db 14}})

(reset! token-store (create-redis-store "tokens" server-conn))
(reset! auth-code-store (create-redis-store "auth-codes" server-conn))
(reset! client-store (create-redis-store "clients" server-conn))
(reset! user-store (create-redis-store "users" server-conn))
```

## Authorization OAuth Tokens
Expand Down
2 changes: 1 addition & 1 deletion project.clj
Expand Up @@ -13,7 +13,7 @@
:profiles {:dev {
:dependencies [[ring/ring-jetty-adapter "1.1.0"]
[lein-marginalia "0.7.0"]
[org.clojars.tavisrudd/redis-clojure "1.3.1"]
[com.taoensso/carmine "2.2.0"]
[hiccup-bootstrap "0.1.0"]]}}
:clean-non-project-classes true )

8 changes: 3 additions & 5 deletions src/clauth/demo.clj
Expand Up @@ -7,7 +7,7 @@
[user :refer [user-store]]
[auth-code :refer [auth-code-store]]]
[clauth.store.redis
:refer [create-redis-store with-redis wrap-redis]]
:refer [create-redis-store]]
[ring.adapter.jetty :refer [run-jetty]]
[ring.middleware
[cookies :refer [wrap-cookies]]
Expand Down Expand Up @@ -86,10 +86,9 @@
(try
(do
(reset! token-store (create-redis-store "tokens"))
(reset! auth-code-store (create-redis-store "autho-codes"))
(reset! auth-code-store (create-redis-store "auth-codes"))
(reset! client-store (create-redis-store "clients"))
(reset! user-store (create-redis-store "users"))
(with-redis
(let [client (or (first (clients))
(register-client "Clauth Demo"
"http://pelle.github.com/clauth"))
Expand All @@ -113,8 +112,7 @@
(wrap-params)
(wrap-cookies)
(wrap-session)
(wrap-redis)
(wrap-bootstrap-resources)) {:port 3000}))))
(wrap-bootstrap-resources)) {:port 3000})))

(catch java.net.ConnectException e
(println "You don't have a Redis database running in the background:"
Expand Down
82 changes: 40 additions & 42 deletions src/clauth/store/redis.clj
@@ -1,56 +1,54 @@
(ns clauth.store.redis
(:require [clauth.store :refer [Store]]
[redis.core :as redis]))
[taoensso.carmine :as car :refer (wcar)]))

(defn namespaced-keys
"get namespaced list of keys"
[namespace]
(redis/keys (str namespace "/*")))

(defn all-in-namespace
"get all items in namespace"
[namespace]
(let [ks (remove nil? (namespaced-keys namespace))]
(if (not-empty ks) (apply redis/mget ks))))

(defrecord RedisStore [namespace]
Store
(fetch [this t] (if-let [j (redis/get (str namespace "/" t))]
(cheshire.core/parse-string j true)))
(revoke! [this t] (redis/del (str namespace "/" t)))
(store! [this key_param item]
(do
(redis/set (str namespace "/" (key_param item))
(cheshire.core/generate-string item))
item))
(entries [this] (map #(cheshire.core/parse-string % true)
(all-in-namespace namespace)))
(reset-store! [this] (redis/flushdb)))

(defn create-redis-store
"Create a redis store"
[namespace]
(RedisStore. namespace))

(def redis-server
(def server1-conn
(if-let [redis_url (or (get (System/getenv) "REDIS_URL")
(get (System/getenv) "REDISTOGO_URL"))]
(let [uri (new java.net.URI redis_url)
host (.getHost uri)
port (.getPort uri)
password (last (clojure.string/split (.getUserInfo uri) #":"))]
{:host host
:port port
:password password})
{:host "127.0.0.1"
:port 6379
:db 14}))
{:pool {}
:spec {:host host
:port port
:password password}})
{:pool {}
:spec {:host "127.0.0.1"
:port 6379
:db 14}}))

(defmacro with-redis
(defmacro wcar*
"Evaluates body in the context of a new connection to either local Redis
server or server specified in REDIS_URL or REDISTOGO_URL"
[& body]
`(redis/with-server redis-server ~@body))
`(car/wcar ~'server-conn ~@body))

(defn wrap-redis [app]
(fn [req] (with-redis (app req))))
(defn namespaced-keys
"get namespaced list of keys"
[namespace server-conn]
(wcar* (car/keys (str namespace "/*"))))

(defn all-in-namespace
"get all items in namespace"
[namespace server-conn]
(let [ks (remove nil? (namespaced-keys namespace server-conn))]
(if (not-empty ks) (wcar* (apply car/mget ks))
[])))

(defrecord RedisStore [namespace server-conn]
Store
(fetch [this t] (wcar* (car/get (str namespace "/" t))))
(revoke! [this t] (wcar* (car/del (str namespace "/" t))))
(store! [this key_param item]
(wcar* (car/set (str namespace "/" (key_param item)) item))
item)
(entries [this] (all-in-namespace namespace server-conn))
(reset-store! [this] (wcar* (car/flushdb))))

(defn create-redis-store
"Create a redis store"
([namespace]
(RedisStore. namespace server1-conn))
([namespace server-conn]
(RedisStore. namespace server-conn)))
44 changes: 17 additions & 27 deletions test/clauth/test/store/redis.clj
Expand Up @@ -6,19 +6,21 @@
[token :as token]
[client :as client]
[user :as user]]
[redis.core :as redis]))
[taoensso.carmine :as car :refer (wcar)]))

(deftest redis-store-implementaiton
(redis/with-server
{:host "127.0.0.1"
:port 6379
:db 15}
(let [st (base/create-redis-store "testing")]
(def server-conn
{:pool {}
:spec {:host "127.0.0.1"
:port 6379
:db 15}})

(deftest redis-store-implementation
(let [st (base/create-redis-store "testing" server-conn)]
(store/reset-store! st)
(is (= 0 (count (store/entries st))))
(is (= [] (store/entries st)))
(is (nil? (store/fetch st "item")))
(let [item (store/store! st :key {:key "item" :hello "world"})]
(let [item (store/store! st :key {:key "item" :hello "world"})]
(is (= 1 (count (store/entries st))))
(is (= item (store/fetch st "item")))
(is (= [item] (store/entries st)))
Expand All @@ -27,14 +29,10 @@
(do (store/reset-store! st)
(is (= 0 (count (store/entries st))))
(is (= [] (store/entries st)))
(is (nil? (store/fetch st "item"))))))))
(is (nil? (store/fetch st "item")))))))

(deftest token-store-implementation
(redis/with-server
{:host "127.0.0.1"
:port 6379
:db 15}
(reset! token/token-store (base/create-redis-store "tokens"))
(reset! token/token-store (base/create-redis-store "tokens" server-conn))
(token/reset-token-store!)
(is (= 0 (count (token/tokens))) "starts out empty")
(let
Expand All @@ -43,34 +41,26 @@
(do (token/store-token record)
(is (= record (token/fetch-token (:token record))))
(is (= 1 (count (token/tokens))) "added one"))))
(reset! token/token-store (store/create-memory-store)))
(reset! token/token-store (store/create-memory-store))

(deftest client-store-implementation
(redis/with-server
{:host "127.0.0.1"
:port 6379
:db 15}
(reset! client/client-store (base/create-redis-store "clients"))
(reset! client/client-store (base/create-redis-store "clients" server-conn))
(client/reset-client-store!)
(is (= 0 (count (client/clients))) "starts out empty")
(let [record (client/client-app)]
(is (nil? (client/fetch-client (:client-id record))))
(do (client/store-client record)
(is (= record (client/fetch-client (:client-id record))))
(is (= 1 (count (client/clients))) "added one"))))
(reset! client/client-store (store/create-memory-store)))
(reset! client/client-store (store/create-memory-store))

(deftest user-store-implementation
(redis/with-server
{:host "127.0.0.1"
:port 6379
:db 15}
(reset! user/user-store (base/create-redis-store "users"))
(reset! user/user-store (base/create-redis-store "users" server-conn))
(user/reset-user-store!)
(is (= 0 (count (user/users))) "starts out empty")
(let [record (user/new-user "john@example.com" "password")]
(is (nil? (user/fetch-user "john@example.com")))
(do (user/store-user record)
(is (= record (user/fetch-user "john@example.com")))
(is (= 1 (count (user/users))) "added one"))))
(reset! user/user-store (store/create-memory-store)))
(reset! user/user-store (store/create-memory-store))

0 comments on commit 855c24f

Please sign in to comment.