From 0b8277f72cdc2ed2abeb566f30958bd8e0dc5167 Mon Sep 17 00:00:00 2001 From: "Gabriel A. Giovanini" Date: Wed, 21 Feb 2018 22:41:20 -0300 Subject: Readme and validation --- README.md | 17 +++++++++-------- src/clj/queue_api/db/core.clj | 9 +++++++-- src/clj/queue_api/routes/services.clj | 12 ++++++++---- test/clj/queue_api/test/db/core_test.clj | 20 +++++++++++++------- 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" -- cgit v1.2.3