The ClojureWerkz Blog

News and updates about ClojureWerkz projects

Elastisch 2.0.0-rc2 Is Released

TL;DR

Elastisch is a battle tested, small but feature rich and well documented Clojure client for ElasticSearch. It supports virtually every Elastic Search feature and has solid documentation.

2.0.0-rc2 is a release candidate of Elastisch 2.0, which focuses on the new features in ElasticSearch 1.1 and introduces major API improvements, including a breaking change.

Changes between Elastisch 2.0.0-rc1 and 2.0.0-rc2

ElasticSearch Client Update

ElasticSearch client has been upgraded to 1.2.x.

Snapshotting Support in Native Client

Native client now supports snapshotting (updated for ElasticSearch 1.2) with the same Clojure API as the REST client (all the usual API conventions apply).

Full Change Log

Elastisch change log is available on GitHub.

Elastisch is a ClojureWerkz Project

Elastisch is part of the group of libraries known as ClojureWerkz, together with

  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Monger, a Clojure MongoDB client for a more civilized age
  • Cassaforte, a Clojure Cassandra client
  • Titanium, a Clojure graph library
  • Neocons, a client for the Neo4J REST API
  • Welle, a Riak client with batteries included
  • Quartzite, a powerful scheduling library

and several others. If you like Elastisch, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

About the Author

Michael on behalf of the ClojureWerkz Team

Cassaforte 2.0.0-beta1 Is Released

TL;DR

Cassaforte is a Clojure client for Apache Cassandra. It is built around CQL 3 and focuses on ease of use. You will likely find that using Cassandra from Clojure has never been so easy.

2.0.0 is a major API revision release that introduces breaking public API changes.

Changes between 1.3.0 and 2.0.0

Cassaforte 2.0 has breaking API changes in most namespaces.

Client (Session) is Explicit Argument

All Cassaforte public API functions that issue requests to Cassandra now require a client (session) to be passed as an explicit argument:

1
2
3
4
5
6
(ns cassaforte.docs
  (:require [clojurewerkz.cassaforte.client :as cc]
            [clojurewerkz.cassaforte.cql    :as cql]))

(let [conn (cc/connect ["127.0.0.1"])]
  (cql/use-keyspace conn "cassaforte_keyspace"))
1
2
3
4
5
6
7
8
9
10
11
(ns cassaforte.docs
  (:require [clojurewerkz.cassaforte.client :as cc]
            [clojurewerkz.cassaforte.cql    :as cql]
            [clojurewerkz.cassaforte.query :refer :all]))

(let [conn (cc/connect ["127.0.0.1"])]
  (cql/create-table conn "user_posts"
                (column-definitions {:username :varchar
                                     :post_id  :varchar
                                     :body     :text
                                     :primary-key [:username :post_id]})))
1
2
3
4
5
6
(ns cassaforte.docs
  (:require [clojurewerkz.cassaforte.client :as cc]
            [clojurewerkz.cassaforte.cql    :as cql]))

(let [conn (cc/connect ["127.0.0.1"])]
  (cql/insert conn "users" {:name "Alex" :age (int 19)}))

Policy Namespace

Policy-related functions from clojurewerkz.cassaforte.client were extracted into clojurewerkz.cassaforte.policies:

1
2
3
(require '[clojurewerkz.cassaforte.policies :as cp])

(cp/exponential-reconnection-policy 100 1000)
1
2
3
4
(require '[clojurewerkz.cassaforte.policies :as cp])

(let [p (cp/round-robin-policy)]
  (cp/token-aware-policy p))

Cassandra Sessions Compatible with with-open

Session#shutdown was renamed to Session#close in cassandra-driver-core. Cassaforte needs to be adapted to that.

Contributed by Jarkko Mönkkönen.

News and Updates

New releases and updates are announced on Twitter. Cassaforte also has a mailing list, feel free to ask questions and report issues there.

Cassaforte is a ClojureWerkz Project

Cassaforte is part of the group of libraries known as ClojureWerkz, together with

  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Monger, a Clojure MongoDB client for a more civilized age
  • Elastisch, a minimalistic Clojure client for ElasticSearch
  • EEP, a Clojure library for stream (event) processing
  • Neocons, a Clojure client for the Neo4J REST API
  • Quartzite, a powerful scheduling library

and several others. If you like Cassaforte, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

About the Author

Michael on behalf of the ClojureWerkz Team.

Welle 3.0.0 Is Released

TL;DR

Welle is an expressive Clojure client for Riak with batteries included.

3.0.0 is a major release that has breaking API changes.

Changes between Welle 2.0.x and 3.0

Welle 3.0 has breaking API changes in most namespaces.

Client (Connection) is Explicit Argument

All Welle public API functions that issue requests to Riak now require a client (HTTP or PBC) to be passed as an explicit argument:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(ns welle.docs.examples
  (:require [clojurewerkz.welle.core    :as wc]
            [clojurewerkz.welle.buckets :as wb]
            [clojurewerkz.welle.kv      :as kv])
  (:import com.basho.riak.client.http.util.Constants))

(let [conn   (wc/connect)
      bucket "accounts"
      key    "novemberain"
      val    {:name "Michael" :age 27 :username key}]
  (wb/create conn bucket)
  ;; stores data serialized as JSON
  (kv/store conn bucket key val {:content-type Constants/CTYPE_JSON_UTF8})
  ;; fetches it back
  (kv/fetch conn bucket key))

Options as Maps

Functions that take optional arguments now require them to be proper maps (and not pseudo-keywords):

1
2
3
4
5
;; in 2.0
(kv/store bucket key val :content-type Constants/CTYPE_JSON_UTF8)

;; in 3.0
(kv/store conn bucket key val {:content-type Constants/CTYPE_JSON_UTF8})

HTTPComponents 4.3

Welle now excludes HTTPComponents dependency for Riak client and instead uses version 4.3 which clj-http depends on.

Change Log

Welle change log is available on GitHub.

Welle is a ClojureWerkz Project

Welle is part of the group of libraries known as ClojureWerkz, together with

  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Elastisch, a minimalistic Clojure client for ElasticSearch
  • Monger, a Clojure MongoDB client for a more civilized age
  • Neocons, a feature rich idiomatic Clojure client for the Neo4J REST API
  • Quartzite, a powerful scheduling library

and several others. If you like Welle, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

Donations

ClojureWerkz accepts donations. If you feel like our projects save you time, consider donating. Thanks.

Michael on behalf of the ClojureWerkz Team

Neocons 3.0.0 Is Released

TL;DR

Neocons is a feature rich idiomatic Clojure client for the Neo4J REST API.

3.0.0 is a major release. It has a major breaking API change compared to 2.0.x: every function now takes a connection as an explicit argument instead of relying on a dynamic var.

Changes between Neocons 2.0.0 and 3.0.0

Breaking Change: Explicit Connection Argument

Neocons no longer uses a dynamic var to hold the state of the connection. This leads to significant changes to the API as the connection has to be passed to functions. The position of the connection argument is always the first argument for the sake of consistency:

1
2
3
4
5
6
7
8
9
10
11
(require '[clojurewerkz.neocons.rest :as nr])
(require '[clojurewerkz.neocons.rest.nodes :as nn])

;; with Neocons 2.0

(nr/connect! "http://localhost:7476/db")
(nn/create {:url "http://clojurewerkz.org/"})

;; with Neocons 3.0
(let [conn (nr/connect "http://localhost:7476/db")]
  (nn/create conn {:url "http://clojurewerkz.org/"}))

Additionally connect! function in clojurewerkz.neocons.rest no longer exists. This has been replaced by function connect in clojurewerkz.neocons.rest. The connect function has the same arguments as the connect! function only it returns a Connection record.

The Connection record has a key called :options which can be used to pass additional parameters to be used by clj-http like debug.

Contributed by Rohit Aggarwal.

Clojure 1.6

Neocons now depends on org.clojure/clojure version 1.6.0. It is still compatible with Clojure 1.4 and if your project.clj depends on a different version, it will be used, but 1.6 is the default now.

Cheshire 5.3

Neocons now uses Cheshire 5.3.

clj-http upgraded to 0.9.1

Neocons now uses clj-http 0.9.1.

Neo4J 2.0 Index Creation Fix

Neocons will now use a key name accepted by Neo4J 2.0.0 GA and later version when creating indexes.

Contributed by Rohit Aggarwal.

Change Log

We encourage all users to give this version a try.

Neocons change log is available on GitHub.

Documentation Updates

Neocons documentation has been updated to cover the new API.

Thank You, Contributors

We’d like to thank Rohit Aggarwal for single-handedly doing all the work in Neocons 3.0. Contributors like Rohit is why open source software works as well as it does.

Neocons is a ClojureWerkz Project

Neocons is part of the group of libraries known as ClojureWerkz, together with

  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Elastisch, a minimalistic Clojure client for ElasticSearch
  • Monger, a Clojure MongoDB client for a more civilized age
  • Cassaforte, a Cassandra client built around CQL 3
  • Quartzite, a powerful scheduling library

and several others. If you like Neocons, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

Michael on behalf of the ClojureWerkz Team

Langohr 2.11.0 Is Released

TL;DR

Langohr is a small Clojure RabbitMQ client.

2.11.0 is a minor feature release.

Changes between Langohr 2.10.x and 2.11.0

Multi-Host Support In langohr.core/connect

langohr.core/connect now supports :hosts as well as :host. The hosts provided will be iterated over, the first reachable host will be used.

Example:

1
2
3
4
5
6
7
(require '[langohr.core :as rmq])

(rmq/connect {:hosts #{"192.168.1.2" "192.168.1.3"}})
;; uses port 5688 for both hosts
(rmq/connect {:hosts #{"192.168.1.2" "192.168.1.3"} :port 5688})
;; uses multiple host/port pairs
(rmq/connect {:hosts #{["192.168.1.2" 5688] ["192.168.1.3" 5689]}})

Change Log

Langohr change log is available on GitHub.

Langohr is a ClojureWerkz Project

Langohr is part of the group of libraries known as ClojureWerkz, together with

  • Elastisch, a minimalistic well documented Clojure client for ElasticSearch
  • Cassaforte, a Clojure Cassandra client built around CQL 3.0
  • Monger, a Clojure MongoDB client for a more civilized age
  • Neocons, a client for the Neo4J REST API
  • Quartzite, a powerful scheduling library

and several others. If you like Langohr, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

About The Author

Michael on behalf of the ClojureWerkz Team

Welle 3.0.0-rc1 Is Released

TL;DR

Welle is an expressive Clojure client for Riak with batteries included.

3.0.0-rc1 is a major release that has breaking API changes.

Changes between Welle 2.0.x and 3.0

Welle 3.0 has breaking API changes in most namespaces.

Client (Connection) is Explicit Argument

All Welle public API functions that issue requests to Riak now require a client (HTTP or PBC) to be passed as an explicit argument:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(ns welle.docs.examples
  (:require [clojurewerkz.welle.core    :as wc]
            [clojurewerkz.welle.buckets :as wb]
            [clojurewerkz.welle.kv      :as kv])
  (:import com.basho.riak.client.http.util.Constants))

(let [conn   (wc/connect)
      bucket "accounts"
      key    "novemberain"
      val    {:name "Michael" :age 27 :username key}]
  (wb/create conn bucket)
  ;; stores data serialized as JSON
  (kv/store conn bucket key val {:content-type Constants/CTYPE_JSON_UTF8})
  ;; fetches it back
  (kv/fetch conn bucket key))

Options as Maps

Functions that take optional arguments now require them to be proper maps (and not pseudo-keywords):

1
2
3
4
5
;; in 2.0
(kv/store bucket key val :content-type Constants/CTYPE_JSON_UTF8)

;; in 3.0
(kv/store conn bucket key val {:content-type Constants/CTYPE_JSON_UTF8})

HTTPComponents 4.3

Welle now excludes HTTPComponents dependency for Riak client and instead uses version 4.3 which clj-http depends on.

Change Log

Welle change log is available on GitHub.

Welle is a ClojureWerkz Project

Welle is part of the group of libraries known as ClojureWerkz, together with

  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Elastisch, a minimalistic Clojure client for ElasticSearch
  • Monger, a Clojure MongoDB client for a more civilized age
  • Neocons, a feature rich idiomatic Clojure client for the Neo4J REST API
  • Quartzite, a powerful scheduling library

and several others. If you like Welle, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

Donations

ClojureWerkz accepts donations. If you feel like our projects save you time, consider donating. Thanks.

Michael on behalf of the ClojureWerkz Team

Cassaforte 1.3.0 Is Released

TL;DR

Cassaforte is a new Clojure client for Apache Cassandra. It is built around CQL 3 and focuses on ease of use. You will likely find that using Cassandra from Clojure has never been so easy.

1.3.0 is a minor release that introduces a few minor features and improves compatibility with Cassandra 2.0.

Changes between Cassaforte 1.2.x and 1.3.0

Clojure 1.6 By Default

The project now depends on org.clojure/clojure version 1.6.0. It is still compatible with Clojure 1.4 and if your project.clj depends on a different version, it will be used, but 1.6 is the default now.

We encourage all users to upgrade to 1.6, it is a drop-in replacement for the majority of projects out there.

Cassandra Java Driver Update

Cassandra Java driver has been updated to 2.0.x.

UUID Generation Helpers

clojurewerkz.cassaforte.uuids is a new namespace that provides UUID generation helpers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(require '[clojurewerkz.cassaforte.uuids :as uuids])

(uuids/random)
;= #uuid "d43fdc16-a9c3-4d0f-8809-512115289537"

(uuids/time-based)
;= #uuid "90cf6f40-4584-11e3-90c2-65c7571b1a52"

(uuids/unix-timestamp (uuids/time-based))
;= 1383592179743

(u/start-of (u/unix-timestamp (u/time-based)))
;= #uuid "ad1fd130-4584-11e3-8080-808080808080"

(u/end-of (u/unix-timestamp (u/time-based)))
;= #uuid "b31abb3f-4584-11e3-7f7f-7f7f7f7f7f7f"

Hayt Update

Hayt dependency has been updated to 1.4.1, which supports if-not-exists in create-keyspace:

1
2
3
4
5
(create-keyspace "main"
           (if-not-exists)
           (with {:replication
                    {:class "SimpleStrategy"
                     :replication_factor 1 }}))

Extra Clauses Support in insert-batch

It is now possible to use extra CQL clauses for every statement in a batch insert (e.g. to specify TTL):

1
2
3
(cql/insert-batch "table"
  {:something "cats"}
  [{:something "dogs"} (using :ttl 60)])

Contributed by Sam Neubardt.

Alternative where syntax

Now it is possible to specify hash in where clause, which makes queries more composable:

1
2
3
4
(select :users
        (where {:city "Munich"
                :age [> (int 5)]})
        (allow-filtering true))

Batch Insert Improvements

Clauses to be specified for each record in insert-batch:

1
2
3
(let [input [[{:name "Alex" :city "Munich"} (using :ttl 350)]
             [{:name "Alex" :city "Munich"} (using :ttl 350)]]]
  (insert-batch th/session :users input))

Contributed by Sam Neubardt.

News and Updates

New releases and updates are announced on Twitter. Cassaforte also has a mailing list, feel free to ask questions and report issues there.

Cassaforte is a ClojureWerkz Project

Cassaforte is part of the group of libraries known as ClojureWerkz, together with

  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Monger, a Clojure MongoDB client for a more civilized age
  • Elastisch, a minimalistic Clojure client for ElasticSearch
  • EEP, a Clojure library for stream (event) processing
  • Neocons, a Clojure client for the Neo4J REST API
  • Quartzite, a powerful scheduling library

and several others. If you like Cassaforte, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

About the Author

Michael on behalf of the ClojureWerkz Team.

Monger 2.0.0-rc1 Is Released

TL;DR

Monger is an idiomatic Clojure MongoDB driver for a more civilized age. It has batteries included, offers powerful expressive query DSL, strives to support every MongoDB 2.0+ feature and has sane defaults. It also has solid documentation.

2.0.0 is a major backwards-incompatible release that implements in Monger the major breaking API changes announced earlier for several ClojureWerkz projects.

Changes between 1.8.0 and 2.0.0

2.0 is a major release that has breaking public API changes.

Explicit Connection/DB/GridFS Argument

In Monger 2.0, all key public API functions require an explicit DB/connection/GridFS object to be provided instead of relying on a shared dynamic var. This makes Monger much easier to use with systems such as Component and Jig, as well as concurrent applications that need to work with multiple connections, database, or GridFS filesystems.

In other words, instead of

1
2
3
(require '[monger.collection :as mc])

(mc/insert "libraries" {:name "Monger"})

it is now necessary to do

1
2
3
(require '[monger.collection :as mc])

(mc/insert db "libraries" {:name "Monger"})

This also means that monger.core/connect! and monger.core/connect-via-uri! were removed, as was monger.multi namespaces.

To connect to MongoDB, use monger.core/connect:

1
2
3
(require '[monger.core :as mg])

(let [conn (mg/connect)])

or monger.core/connect-via-uri:

1
2
3
(require '[monger.core :as mg])

(let [{:keys [conn db]} (mg/connect-via-uri "mongodb://clojurewerkz/monger:monger@127.0.0.1/monger-test4")])

To get a database reference, use monger.core/get-db, which now requires a connection object:

1
2
3
4
(require '[monger.core :as mg])

(let [conn (mg/connect)
      db   (mg/get-db conn "monger-test")])

Options as Maps

Functions that take options now require a proper Clojure map instead of pseudo keyword arguments:

1
2
3
4
5
# in Monger 1.x
(mc/update db coll {} {:score 0} :multi true)

# in Monger 2.x
(mc/update db coll {} {:score 0} {:multi true})

Change Log

Monger change log is available on GitHub.

Monger is a ClojureWerkz Project

Monger is part of the group of libraries known as ClojureWerkz, together with

  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Cassaforte, a Clojure Cassandra client built around CQL
  • Elastisch, a minimalistic Clojure client for ElasticSearch
  • Welle, a Riak client with batteries included
  • Neocons, a client for the Neo4J REST API
  • Quartzite, a powerful scheduling library

and several others. If you like Monger, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

About the Author

@michaelklishin on behalf of the ClojureWerkz Team

Langohr 2.10.1 Is Released

TL;DR

Langohr is a small Clojure RabbitMQ client.

2.10.1 is a bug fix release.

Changes between Langohr 2.9.x and 2.10.1

Retries for all IOExceptions During Recovery

All IOException subclasses thrown during connection recovery attempts will now be retried.

Contributed by Paul Bellamy (Xively).

RabbitMQ Java Client Upgrade

RabbitMQ Java client dependency has been updated to 3.3.1.

Change Log

Langohr change log is available on GitHub.

Langohr is a ClojureWerkz Project

Langohr is part of the group of libraries known as ClojureWerkz, together with

  • Elastisch, a minimalistic well documented Clojure client for ElasticSearch
  • Cassaforte, a Clojure Cassandra client built around CQL 3.0
  • Monger, a Clojure MongoDB client for a more civilized age
  • Neocons, a client for the Neo4J REST API
  • Quartzite, a powerful scheduling library

and several others. If you like Langohr, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

About The Author

Michael on behalf of the ClojureWerkz Team

Monger 1.8.0 Is Released

TL;DR

Monger is an idiomatic Clojure MongoDB driver for a more civilized age. It has batteries included, offers powerful expressive query DSL, strives to support every MongoDB 2.0+ feature and has sane defaults. It also has solid documentation.

1.8.0 is a minor backwards-compatible release that updates MongoDB Java driver and adds a few minor features. The next release will be 2.0 with some major breaking API changes that we’ve announced earlier.

Changes between 1.7.0 and 1.8.0

Clojure 1.6

Monger now depends on org.clojure/clojure version 1.6.0. It is still compatible with Clojure 1.4 and if your project.clj depends on a different version, it will be used, but 1.6 is the default now.

monger.result Use with WriteConcerns is Deprecated

MongoDB Java driver 2.12.x no longer guarantees connection affinity for thread pool threads.

This means that WriteConcern#getLastError is no longer a safe from concurrency hazards. Therefore the use of monger.result functions on WriteConcern instances is now deprecated in MongoDB Java client and Monger.

MongoDB Java Driver Update

MongoDB Java driver dependency has been updated to 2.12.x.

Default WriteConcern Change

Monger now uses WriteConcern/ACKNOWLEDGED by default. Functionality-wise it is the same as WriteConcern/SAFE in earlier versions.

monger.core/connect-via-uri

monger.core/connect-via-uri is a version of monger.core/connect-via-uri! which returns the connection instead of mutating a var.

It should be used by projects that are built from reloadable components, together with monger.multi.*.

Future Plans

The next Monger release will be 2.0 with some major breaking API changes that we’ve announced earlier.

Change Log

Monger change log is available on GitHub.

Monger is a ClojureWerkz Project

Monger is part of the group of libraries known as ClojureWerkz, together with

  • Langohr, a Clojure client for RabbitMQ that embraces the AMQP 0.9.1 model
  • Cassaforte, a Clojure Cassandra client built around CQL
  • Elastisch, a minimalistic Clojure client for ElasticSearch
  • Welle, a Riak client with batteries included
  • Neocons, a client for the Neo4J REST API
  • Quartzite, a powerful scheduling library

and several others. If you like Monger, you may also like our other projects.

Let us know what you think on Twitter or on the Clojure mailing list.

About the Author

@michaelklishin on behalf of the ClojureWerkz Team