aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel A. Giovanini <mail@gabrielgio.me>2018-02-21 22:41:20 -0300
committerGabriel A. Giovanini <mail@gabrielgio.me>2018-02-21 22:41:20 -0300
commit0b8277f72cdc2ed2abeb566f30958bd8e0dc5167 (patch)
treeb4d26fa45fde855ccbc81ffd0af893c88aaba869
parente05e7911084e3f23897d6d5b299d7f84494d618e (diff)
downloadqueue-api-0b8277f72cdc2ed2abeb566f30958bd8e0dc5167.tar.gz
queue-api-0b8277f72cdc2ed2abeb566f30958bd8e0dc5167.tar.bz2
queue-api-0b8277f72cdc2ed2abeb566f30958bd8e0dc5167.zip
Readme and validation
-rw-r--r--README.md17
-rw-r--r--src/clj/queue_api/db/core.clj9
-rw-r--r--src/clj/queue_api/routes/services.clj12
-rw-r--r--test/clj/queue_api/test/db/core_test.clj20
4 files changed, 37 insertions, 21 deletions
diff --git a/README.md b/README.md
index 95c842c..16658a9 100644
--- a/README.md
+++ b/README.md
@@ -12,8 +12,8 @@ then access [localhost:3000/swagger-ui](http://localhost:3000/swagger-ui/index.h
## Stack
-I chose [luminus](http://www.luminusweb.net/) for my stack as it makes the initial setup way easier since it provide a wide range option of configuration for a bunch of technologies.
-To bootstrap the project I used `lein new luminus queue-api +swagger +service +kibit` plus datascrypt which doesn't come with Luminus.
+I chose [luminus](http://www.luminusweb.net/) for my stack as it makes the initial setup way easier, it provides a wide range profiles for a bunch of technologies.
+I bootstrapped the project with `lein new luminus queue-api +swagger +service +kibit` plus datascrypt which doesn't come with Luminus.
### +Swagger
@@ -21,15 +21,15 @@ When possible I always add it to a project for it make easier to visualize and t
### +Service
-To remove all front end stuff since I didn't need it.
+To remove all front end stuff since I don't need it.
### +Kibit
-I added because it gives some insight how to make you code more idiomatic.
+It gives some insight how to make you code more idiomatic.
### Datascript
-I chose [datascript](https://github.com/tonsky/datascript) for its easy setup, after little to no effort I had it working.
+[datascript](https://github.com/tonsky/datascript) was chosen for its easy setup, after little to no effort I had it working.
Even though it was meant to run on browser it fit nicely in the project, and because it works pretty much like Datomic it has [powerful query system](https://docs.datomic.com/on-prem/query.html) and works seamlessly with clojure.
Additionally it had an okay [non-documentation](https://github.com/tonsky/datascript/wiki/Getting-started) with some [samples](https://github.com/kristianmandrup/datascript-tutorial) and if I couldn't find for Datascript I'd search for a Datomic seeing that query system of both are compatible.
@@ -70,7 +70,8 @@ Those models wrap up in schema:
### services.clj
After all luminus file there is actually two files that have the core logic of the app `services.clj` and `db/core.cljs`.
-For `services.clj` it holds all code for endpoint definition and model validation. considering the exercise requirements we gonna need 5 endpoints:
+For `services.clj` it holds all code for endpoint definition and input validation.
+Considering the exercise requirements there is a need for 5 endpoints:
* Endpoint to add agent is a`:put` at `/agent`
* Endpoint to get how many jobs of each type this agent has performed is a `:post` at `/agent`. Note: usually since it is a method that doesn't modify anything I'd have used `:get` and pass the agent id via path (`/agent/:id`) but one of the requirement is "*All endpoints should accept and return JSON content type payloads*" I worked with POST PUT.
@@ -84,7 +85,7 @@ For model and validation details access swagger-ui.
Core.clj holds all logic to interact with Datascrip therefore all the code to manage the queue.
The idea behind it is actually simpler than part 1 since Datascrip handle the hard word.
-For example, to store jobs and agents I'd simply `transact!` the entire object and we good to go.
+For example, to store jobs and agents I'd simply `transact!` the entire object and it is good to go.
```clojure
(d/transact! queue-api.db.core/conn
@@ -95,7 +96,7 @@ For example, to store jobs and agents I'd simply `transact!` the entire object a
:job/status :unassigned}])
```
-While with a simple query I can fetch the exact piece of information that I need for the moment.
+While with a simple query I could fetch the exact piece of information that I need for the moment.
```clojure
(d/q '[:find ?d ?id
diff --git a/src/clj/queue_api/db/core.clj b/src/clj/queue_api/db/core.clj
index c76f0fb..0482feb 100644
--- a/src/clj/queue_api/db/core.clj
+++ b/src/clj/queue_api/db/core.clj
@@ -102,7 +102,12 @@
(if (seq jn)
(first jn))))))
-(defn request-job
+(defn agent
+ "Get a agent by id"
+ [id]
+ (d/entity @conn [:agent/id id]))
+
+(defn fittest-job
"Get the fittest job for a agent `id`."
[^String id]
(let [a (d/entity @conn [:agent/id id])]
@@ -146,7 +151,7 @@
[^String id]
(let [a (d/entity @conn [:agent/id id])]
(if-not (nil? a)
- (let [jid (:job/id (request-job id))]
+ (let [jid (:job/id (fittest-job id))]
(end-job a)
(start-job id jid)
jid)))) \ No newline at end of file
diff --git a/src/clj/queue_api/routes/services.clj b/src/clj/queue_api/routes/services.clj
index 0b26281..766f831 100644
--- a/src/clj/queue_api/routes/services.clj
+++ b/src/clj/queue_api/routes/services.clj
@@ -44,10 +44,14 @@
:return {:job_request {:job_id s/Any :agent_id String}}
:body-params [agent_id :- String]
:summary "Request a job to a given agent"
- (let [j (db/dequeue-job agent_id)]
- (if (nil? j)
- (bad-request {:message "Agent does not exist"})
- (ok {:job_request {:job_id j :agent_id agent_id}}))))
+
+ (let [a (agent agent_id)]
+ (if (nil? a)
+ (not-found {:message "Agent does not exist"}))
+ (let [j (db/dequeue-job agent_id)]
+ (if (nil? j)
+ (not-found {:message "There is no job available for given agent"})
+ (ok {:job_request {:job_id j :agent_id agent_id}})))))
(GET "/" []
:return {:completed [String]
diff --git a/test/clj/queue_api/test/db/core_test.clj b/test/clj/queue_api/test/db/core_test.clj
index 371b903..117cc26 100644
--- a/test/clj/queue_api/test/db/core_test.clj
+++ b/test/clj/queue_api/test/db/core_test.clj
@@ -105,8 +105,7 @@
(d/transact! conn base-schema)
(f)))
-(defn agent [id]
- (d/entity @conn [:agent/id id]))
+
(defn job [id]
(d/entity @conn [:job/id id]))
@@ -225,21 +224,28 @@
:processing (-> a :agent/job :job/status)
"96cf6f11-591d-4cde-9ab0-56e371acb6d2" (-> a :agent/job :job/id)))))
-(deftest request-job-test
+(deftest fittest-job-test
(testing "test query for skillset"
;;primary-skillset urgent
(is (= (job "51ab0771-f1e4-4268-868f-9029a58f6612")
- (request-job "644be0ce-035d-48cb-867e-8e6de2714a8d")))
+ (fittest-job "644be0ce-035d-48cb-867e-8e6de2714a8d")))
;;secondary-skillset urgent
(is (= (job "6e90db58-7a6d-46e2-a02a-e33dc82e6e33")
- (request-job "ff02347a-1b2d-440c-a2a1-7a593dba564e")))
+ (fittest-job "ff02347a-1b2d-440c-a2a1-7a593dba564e")))
(d/transact! conn complete-schema)
;;primary-skillset not urgent
(is (= (job "96cf6f11-591d-4cde-9ab0-56e371acb6d2")
- (request-job "644be0ce-035d-48cb-867e-8e6de2714a8d")))
+ (fittest-job "644be0ce-035d-48cb-867e-8e6de2714a8d")))
;;secondary-skillset not urgent
(is (= (job "f90e149e-fa51-4212-a6bf-8cf81c78d28c")
- (request-job "ff02347a-1b2d-440c-a2a1-7a593dba564e")))))
+ (fittest-job "ff02347a-1b2d-440c-a2a1-7a593dba564e")))))
+
+(deftest agent-test
+ (testing "Test agent"
+ (are [left right]
+ (= left right)
+ (d/entity @conn [:agent/id "644be0ce-035d-48cb-867e-8e6de2714a8d"]) (agent "644be0ce-035d-48cb-867e-8e6de2714a8d")
+ nil (agent "7b8e17fc-7953-44cf-9249-294c4eb73087"))))
(deftest dequeue-job-test
(testing "Test Dummy Derp dequeuing process"