Archive for August, 2016

Adding CORS to Ring Middleware

Tuesday, August 16th, 2016

Clojure.jpgBret and I finally got the CORS support for ring middleware working in our applications. It required that we get the starting point for the CORS support from another project, and then augment it to make sure it was working for all the cases we needed.

Basically, you need to start with:

  [rwilson/ring-cors "0.1.9"]

in your project.clj, and then in the server.clj for the library, we reference it:

  [ring.middleware.cors :as cors]

and then create the middleware function:

  (def wrap-cors
    "This is a simple convenience definition for enabling the CORS support in
    middleware for a service. The use of this will be far simpler than including
    all this in every service."
    #(cors/wrap-cors % :access-control-allow-origin #".+"
                       :access-control-allow-headers ["Origin" "Content-Type"
                                                      "Accept" "Authorization"
                                                      "Last-Modified" "Credentials"
                                                      "X-Request-Id" "X-Session-Id"]
                       :access-control-allow-methods [:get :put :post :delete]))

And with this, you can then simply put this into your middleware stack and it takes care of all the work:

  (def app
    "The actual ring handler that is run -- this is the routes above
     wrapped in various middlewares."
    (-> app-routes
        wrap-json-with-padding
        (wrap-ssl-redirect { :ssl-port (cfg/jetty :https-redirect) })
        handler/site
        wrap-cors
        wrap-params
        wrap-cookies
        wrap-logging
        wrap-proxy-loggly
        wrap-gzip))

Interesting Rounding Issue in Clojure

Friday, August 12th, 2016

Clojure.jpgWe have a shared library that has a lot of really useful functions in it for all the apps we build, and one of the really useful things is to round to a fixed number of decimal places. Now, this isn't Rocket Science, but it is nice to have written well once, and then not have to mess with ever again.

The trick is that you need it to be fast for all Clojure datatypes as well. And several of the more common implementations aren't very fast due to boxing and the overhead associated with that. So we made some pretty simple little functions:

  (defn to-2dp
    "Function to simply resolve a number to a decimal (double), and then round
    it to 2 DP and return it. Pretty simple, but very useful."
    [x]
    (/ (math/round (* 100.0 (parse-double x))) 100.0))
 
  (defn to-3dp
    "Function to simply resolve a number to a decimal (double), and then round
    it to 3 DP and return it. Pretty simple, but very useful."
    [x]
    (/ (math/round (* 1000.0 (parse-double x))) 1000.0))

but we had a problem. Some of the inputs gave us a lot of grief because of some nasty rounding. And it wasn't all values - it was just those values that had a hard time being expressed in the floating point format.

The solution was to accept some of the inefficiency of rat eJVM BigDecimal and the advanced representation it had, and use that:

  (defn to-2dp
    "Function to simply resolve a number to a decimal (double), and then round
    it to 2 DP and return it. Pretty simple, but very useful."
    [x]
    (/ (math/round (* 100.0 (bigdec (parse-double x)))) 100.0))
 
  (defn to-3dp
    "Function to simply resolve a number to a decimal (double), and then round
    it to 3 DP and return it. Pretty simple, but very useful."
    [x]
    (/ (math/round (* 1000.0 (bigdec (parse-double x)))) 1000.0))

and then things settled down.

Upgraded My Volvo

Monday, August 8th, 2016

Volvo

Today I finally upgraded my 2002 Volvo V70 XC to a 2016 Volvo XC70, and wow! is it a nice car. I've been looking for a few months because my old V70 was over 193,000 mi, and it was making some noises that were going to be several thousand dollars to fix. There was nothing wrong with the car - other than old age, and a lot of miles. It has served me very well these three years, but it was costing about $400 to $500 a month in repairs, and there were plenty of signs that a long trip to Indy was not a really advisable journey.

So I looked at the same car - just newer - and there were some really good deals on year-end clearance at the dealerships around me. So I decided that today was as good a day as any, and went and drive the new model.

What a dream! Now, to be honest, the 2002 V70 was a great car to drive. Even with the age, it was smooth, easy to drive, and very comfortable. The newer model is on a different chassis, and with a different power-plant and lots of interior goodies, it is just an amazing car to drive. But then it's a Volvo - and to me, that's amazing engineering.

Plus, with the new frame, I've got about 15% more storage in the back which means I can really sleep in the back with a few blankets. And it's got all the goodies. Very nice.