cqrs-server

An opinionated Clojure CQRS/ES implementation using Onyx, Datomic, DynamoDB, Kafka and Zookeeper.

  • 所有者: Yuppiechef/cqrs-server
  • 平台:
  • 许可证: MIT License
  • 分类:
  • 主题:
  • 喜欢:
    0
      比较:

Github星跟踪图

cqrs-server

An opinionated CQRS/ES implementation using Onyx, Datomic, DynamoDB, Kafka and Zookeeper.

Usage

A quick guide to get started :

Install dynamodb local

Get dynamodb local from: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tools.DynamoDBLocal.html

And then run:

java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar

Kafka & Zookeeper

Download and extract Kafka: http://kafka.apache.org/downloads.html

Run both these (probably in separate terminals)

bin/zookeeper-server-start.sh config/zookeeper.properties
bin/kafka-server-start.sh config/server.properties

Currently, this needs the latest SNAPSHOT version of Prismatic Schema, so clone that repo and install the jar:

git clone https://github.com/Prismatic/schema.git
cd schema
lein cljx once
lein install

cqrs-server

Then clone this repo and fire it up!

cd cqrs-server
lein repl

=> (start)
"Setup complete"
=> (send-command :user/register {:name "Bob" :age 31})
nil
=> (d/q '[:find [?e ...] :where [?e :user/name]] (d/db (d/connect datomic-uri)))
[17592186045422]
=> (map #(d/touch (d/entity (d/db (d/connect datomic-uri)) %)) *1)
({:base/uuid #uuid "54d8fc2e-6c1f-4fb6-93f9-bef9536a9f7d", :user/age 31, :user/name "Bob", :db/id 17592186045422})

Now we have a user in the system, let's fill out his profile a bit:

=> (send-command :user/update-email {:uuid #uuid "54d8fc2e-6c1f-4fb6-93f9-bef9536a9f7d" :email "bob@example.com"})
=> (send-command :user/disabled {:uuid #uuid "54d8fc2e-6c1f-4fb6-93f9-bef9536a9f7d"})
=> (map #(d/touch (d/entity (d/db (d/connect datomic-uri)) %)) (d/q '[:find [?e ...] :where [?e :user/name]] (d/db (d/connect datomic-uri))))
({:base/uuid #uuid "54d90a89-0880-4f30-bb34-42f29ceb1095", :user/age 31, :user/email "bob@example.com", :user/name "Bob", :user/status :user.status/disabled, :db/id 17592186045422})

We can also send some pageviews and see how it updates the viewcount on the user (a possibly useful aggregate):

=> (send-command :user/pageview {:uuid #uuid "54d90a89-0880-4f30-bb34-42f29ceb1095" :url "http://www.example.com" :render-time 230})
=> (send-command :user/pageview {:uuid #uuid "54d90a89-0880-4f30-bb34-42f29ceb1095" :url "http://www.example.com" :render-time 212})
=> (send-command :user/pageview {:uuid #uuid "54d90a89-0880-4f30-bb34-42f29ceb1095" :url "http://www.example.com" :render-time 182})
=> (map #(d/touch (d/entity (d/db (d/connect datomic-uri)) %)) (d/q '[:find [?e ...] :where [?e :user/name]] (d/db (d/connect datomic-uri))))
({:base/uuid #uuid "54d90a89-0880-4f30-bb34-42f29ceb1095", :user/age 31, :user/email "bob@example.com", :user/name "Bob", :user/status :user.status/disabled, :user/viewcount 3, :db/id 17592186045422})

Then lets have a look at the events:

=> (far/scan dynamodb-cred :events)
[{:date 1423510307575N, :data #<byte[] ...>, :basis-t 1008N, :id "86439637-8f1e-5170-9b23-824486e3506a", :type "user/pageviewed"} {:date 1423510178427N, :data #<byte[] ...>, :basis-t 1005N, :id "c67ccc74-c71c-5578-80ad-924c470f052f", :type "user/email-updated"} {:date 1423510316827N, :data #<byte[] ...>, :basis-t 1010N, :id "08316c9b-3fcd-5a9f-b095-4bf0c1a61a05", :type "user/pageviewed"} {:date 1423510210618N, :data #<byte[] ...>, :basis-t 1007N, :id "46ac00c9-bd7d-5903-91e0-af56d28ef751", :type "user/disabled"} {:date 1423510153513N, :data #<byte[] ...>, :basis-t 1000N, :id "be856c9c-0bf8-5ccc-bec1-bfa0f5a7e983", :type "user/registered"} {:date 1423510312463N, :data #<byte[] ...>, :basis-t 1009N, :id "5c2eb804-1016-5fa3-a868-c01b515f980d", :type "user/pageviewed"}]

The actual data is fressian encoded so that there's no pain with the transformation of clojure data structures.

NOTE: If you do actually use this for user aggregates and authentication, remember to at least bcrypt your passwords.
Be very aware that sensitive data is written to multiple places in this system: the kafka queues, the dynamo event source and the datomic aggregate. This is a particularly important consideration for things like credit card details and passwords.

Datomic-pro

The default profile uses datomic-free - if you want to use datomic-pro, start the repl with lein with-profile prod

When you use cqrs-server as a library to your application project, you'll probably want to add it as a dependency with an exclusion: [cqrs-server "0.1.0-SNAPSHOT" :exclusions [com.datomic/datomic-free]]

Tests

Because this project depends on correct integration with kafka, dynamodb and zookeeper, the tests require that you have these running locally before you run lein test. See above in order to get them installed and started.

License

Copyright © 2015 Yuppiechef Online (Pty) Ltd.

Distributed under The MIT License (MIT) - See LICENSE.txt

主要指标

概览
名称与所有者Yuppiechef/cqrs-server
主编程语言Clojure
编程语言Clojure (语言数: 1)
平台
许可证MIT License
所有者活动
创建于2015-02-09 19:42:15
推送于2015-05-11 06:42:50
最后一次提交2015-05-11 08:42:47
发布数0
用户参与
星数210
关注者数16
派生数13
提交数29
已启用问题?
问题数8
打开的问题数4
拉请求数0
打开的拉请求数0
关闭的拉请求数0
项目设置
已启用Wiki?
已存档?
是复刻?
已锁定?
是镜像?
是私有?