From d85ac6d3fbd2640dd8045480bd870c91ca98664e Mon Sep 17 00:00:00 2001 From: David Leatherman Date: Thu, 13 Aug 2015 00:01:39 +0000 Subject: [PATCH] move middleware to carica.middleware --- src/carica/core.clj | 104 +++++--------------------------- src/carica/middleware.clj | 84 ++++++++++++++++++++++++++ test/carica/test/core.clj | 44 -------------- test/carica/test/middleware.clj | 49 +++++++++++++++ 4 files changed, 148 insertions(+), 133 deletions(-) create mode 100644 src/carica/middleware.clj create mode 100644 test/carica/test/middleware.clj diff --git a/src/carica/core.clj b/src/carica/core.clj index cdbdd00..7959ed9 100644 --- a/src/carica/core.clj +++ b/src/carica/core.clj @@ -1,6 +1,7 @@ (ns carica.core - (:use [clojure.java.io :only [reader input-stream] :as io]) - (:require [clojure.tools.logging :as log] + (:require [carica.middleware :as mw] + [clojure.java.io :as io] + [clojure.tools.logging :as log] [clojure.tools.reader :as clj-reader] [clojure.tools.reader.edn :as edn] [clojure.tools.reader.reader-types :as readers] @@ -41,7 +42,7 @@ (defn load-with [resource loader] (try - (-> resource input-stream readers/input-stream-push-back-reader loader) + (-> resource io/input-stream readers/input-stream-push-back-reader loader) (catch Throwable t (log/warn t "error reading config" resource) (throw @@ -66,7 +67,7 @@ (defmethod load-config :carica/json [resource] (with-open [s (.openStream resource)] - (-> s reader (json-parse-stream true)))) + (-> s io/reader (json-parse-stream true)))) (derive :carica/clj :carica/edn) @@ -104,74 +105,6 @@ n)) resources)) -(defn get-config-fn - "Retrieve the wrapped fn from the middleware, or return f if - it isn't wrapped." - [f] - {:post [f]} - (if (map? f) - (:carica/fn f) - f)) - -(defn get-options - "Retrieve the exposed options from the wrapped middleware, or return - {} if the middleware isn't wrapped." - [f] - {:post [f]} - (if (map? f) - (:carica/options f) - {})) - -(defn unwrap-middleware-fn - "Convenience function for pulling the fn and options out of the - wrapped middleware. It's easier to destructure a seq than a map - with namespaced keys." - [f] - [(get-config-fn f) (get-options f)]) - -(defn wrap-middleware-fn - "Take the passed function and an optional map of options and return - the wrapped middleware map that the rest of the code expects to - use." - [f & [opt-map]] - {:carica/options (or opt-map {}) - :carica/fn f}) - -(defn eval-config - "Config middleware that will evaluate the config map. This allows - arbitrary code to live in the config file. It is often useful for - coercing config values to a particular type." - [f] - (fn [resources] - (let [cfg-map (f resources)] - (try - (eval cfg-map) - (catch Throwable t - (log/warn t "error evaling config" cfg-map) - (throw - (Exception. (str "error evaling config " cfg-map) t))))))) - -(defn cache-config - "Config middleware that will cache the config map so that it is - loaded only once." - [f] - (let [mem (atom {})] - (wrap-middleware-fn - (fn [resources] - (if-let [e (find @mem resources)] - (val e) - (let [ret (f resources)] - (swap! mem assoc resources ret) - ret))) - {:carica/mem mem}))) - -(defn clear-config-cache! - "Clear the cached config. If a custom config function has been - defined, it must be passed in." - [& [config-fn]] - (when ((or config-fn config) :carica/middleware :carica/mem) - (swap! ((or config-fn config) :carica/middleware :carica/mem) empty))) - (defn config* "Looks up the keys in the maps. If not found, log and return nil." [m ks] @@ -182,20 +115,8 @@ (def default-middleware "The default list of middleware carica uses." - [eval-config - cache-config]) - -(defn middleware-compose - "Unwrap and rewrap the function and middleware. Used in a reduce to - create the actual config funtion that is eventually called to fetch - the values from the config map." - [f mw] - (let [[f-fn f-opts] (unwrap-middleware-fn f) - [mw-fn mw-opts] (unwrap-middleware-fn mw) - ;; mw-fn might return wrapped mw, so pull *it* apart as well - [new-f-fn new-f-opts] (unwrap-middleware-fn (mw-fn f-fn))] - (wrap-middleware-fn new-f-fn - (merge f-opts mw-opts new-f-opts)))) + [mw/eval-config + mw/cache-config]) (defn configurer "Given a the list of resources in the format expected by get-configs, @@ -212,9 +133,9 @@ (configurer resources default-middleware)) ([resources middleware] (let [[config-fn options] - (unwrap-middleware-fn - (reduce middleware-compose - (wrap-middleware-fn get-configs) + (mw/unwrap-middleware-fn + (reduce mw/middleware-compose + (mw/wrap-middleware-fn get-configs) middleware))] (fn [& ks] (if (= (first ks) :carica/middleware) @@ -272,3 +193,8 @@ E.g., (with-redefs [config (override-config nil)])" (overrider config)) + +;; for backwards compatibility +(def eval-config mw/eval-config) +(def cache-config mw/cache-config) +(def clear-config-cache! mw/clear-config-cache!) diff --git a/src/carica/middleware.clj b/src/carica/middleware.clj new file mode 100644 index 0000000..adbf7e6 --- /dev/null +++ b/src/carica/middleware.clj @@ -0,0 +1,84 @@ +(ns carica.middleware + (:require [clojure.tools.logging :as log])) + +(defn get-config-fn + "Retrieve the wrapped fn from the middleware, or return f if + it isn't wrapped." + [f] + {:post [f]} + (if (map? f) + (:carica/fn f) + f)) + +(defn get-options + "Retrieve the exposed options from the wrapped middleware, or return + {} if the middleware isn't wrapped." + [f] + {:post [f]} + (if (map? f) + (:carica/options f) + {})) + +(defn unwrap-middleware-fn + "Convenience function for pulling the fn and options out of the + wrapped middleware. It's easier to destructure a seq than a map + with namespaced keys." + [f] + [(get-config-fn f) (get-options f)]) + +(defn wrap-middleware-fn + "Take the passed function and an optional map of options and return + the wrapped middleware map that the rest of the code expects to + use." + [f & [opt-map]] + {:carica/options (or opt-map {}) + :carica/fn f}) + +(defn middleware-compose + "Unwrap and rewrap the function and middleware. Used in a reduce to + create the actual config funtion that is eventually called to fetch + the values from the config map." + [f mw] + (let [[f-fn f-opts] (unwrap-middleware-fn f) + [mw-fn mw-opts] (unwrap-middleware-fn mw) + ;; mw-fn might return wrapped mw, so pull *it* apart as well + [new-f-fn new-f-opts] (unwrap-middleware-fn (mw-fn f-fn))] + (wrap-middleware-fn new-f-fn + (merge f-opts mw-opts new-f-opts)))) + +(defn eval-config + "Config middleware that will evaluate the config map. This allows + arbitrary code to live in the config file. It is often useful for + coercing config values to a particular type." + [f] + (fn [resources] + (let [cfg-map (f resources)] + (try + (eval cfg-map) + (catch Throwable t + (log/warn t "error evaling config" cfg-map) + (throw + (Exception. (str "error evaling config " cfg-map) t))))))) + +(defn cache-config + "Config middleware that will cache the config map so that it is + loaded only once." + [f] + (let [mem (atom {})] + (wrap-middleware-fn + (fn [resources] + (if-let [e (find @mem resources)] + (val e) + (let [ret (f resources)] + (swap! mem assoc resources ret) + ret))) + {:carica/mem mem}))) + +(defn clear-config-cache! + "Clear the cached config. If a custom config function has been + defined, it must be passed in." + [& [config-fn]] + (let [config-fn (or config-fn (ns-resolve 'carica.core 'config))] + (when (config-fn :carica/middleware :carica/mem) + (swap! (config-fn :carica/middleware :carica/mem) empty)))) + diff --git a/test/carica/test/core.clj b/test/carica/test/core.clj index 277bf5d..172f46c 100644 --- a/test/carica/test/core.clj +++ b/test/carica/test/core.clj @@ -71,50 +71,6 @@ (is (= (get-configs [(resources "config.clj")]) (get-configs [nil (resources "config.clj") nil [nil nil]])))) -(deftest test-middleware - (let [call-count (atom 0) - call-mdlware (fn [f] - (fn [resources] - (swap! call-count inc) - (f resources))) - empty-cfg (configurer (resources "config.clj") []) - mdlware-cfg (configurer (resources "config.clj") - [call-mdlware]) - cached-cfg (configurer (resources "config.clj") - [call-mdlware cache-config]) - eval-cfg (configurer (resources "config.clj") - [eval-config])] - (testing "General middleware" - (is (= true (empty-cfg :from-test))) - (is (= 0 @call-count)) - (is (= true (mdlware-cfg :from-test))) - (is (= 1 @call-count))) - (testing "Caching works" - (is (= true (cached-cfg :from-test))) - (is (= true (cached-cfg :from-test))) - (is (= 2 @call-count))) - (testing "Eval works" - (is (= '(+ 1 1) (empty-cfg :eval-cfg))) - (is (= 2 (eval-cfg :eval-cfg)))))) - -(deftest test-wrap-middleware - (let [call-count (atom 0) - call-mdlware (fn [f] - (fn [resources] - (swap! call-count inc) - (f resources))) - cached-cfg (configurer (resources "config.clj") - [call-mdlware cache-config]) - eval-cfg (configurer (resources "config.clj") - [eval-config])] - (testing "Resetting cache works" - (is (= true (cached-cfg :from-test))) - (is (= true (cached-cfg :from-test))) - (is (= 1 @call-count)) - (clear-config-cache! cached-cfg) - (is (= true (cached-cfg :from-test))) - (is (= 2 @call-count))))) - (deftest test-edn-config (is (= "test-edn" (config :test-edn)))) diff --git a/test/carica/test/middleware.clj b/test/carica/test/middleware.clj new file mode 100644 index 0000000..9bbefd1 --- /dev/null +++ b/test/carica/test/middleware.clj @@ -0,0 +1,49 @@ +(ns carica.test.middleware + (:require [carica.core :refer [configurer resources config]] + [carica.middleware :refer :all] + [clojure.test :refer :all] + [clojure.tools.logging.impl :refer [write!]])) + +(deftest test-middleware + (let [call-count (atom 0) + call-mdlware (fn [f] + (fn [resources] + (swap! call-count inc) + (f resources))) + empty-cfg (configurer (resources "config.clj") []) + mdlware-cfg (configurer (resources "config.clj") + [call-mdlware]) + cached-cfg (configurer (resources "config.clj") + [call-mdlware cache-config]) + eval-cfg (configurer (resources "config.clj") + [eval-config])] + (testing "General middleware" + (is (= true (empty-cfg :from-test))) + (is (= 0 @call-count)) + (is (= true (mdlware-cfg :from-test))) + (is (= 1 @call-count))) + (testing "Caching works" + (is (= true (cached-cfg :from-test))) + (is (= true (cached-cfg :from-test))) + (is (= 2 @call-count))) + (testing "Eval works" + (is (= '(+ 1 1) (empty-cfg :eval-cfg))) + (is (= 2 (eval-cfg :eval-cfg)))))) + +(deftest test-wrap-middleware + (let [call-count (atom 0) + call-mdlware (fn [f] + (fn [resources] + (swap! call-count inc) + (f resources))) + cached-cfg (configurer (resources "config.clj") + [call-mdlware cache-config]) + eval-cfg (configurer (resources "config.clj") + [eval-config])] + (testing "Resetting cache works" + (is (= true (cached-cfg :from-test))) + (is (= true (cached-cfg :from-test))) + (is (= 1 @call-count)) + (clear-config-cache! cached-cfg) + (is (= true (cached-cfg :from-test))) + (is (= 2 @call-count)))))