(ns queue-api.routes.services (:require [ring.util.http-response :refer :all] [compojure.api.sweet :refer :all] [schema.core :as s] [queue-api.db.core :as db] [ring.util.http-status :as http-status])) (s/defschema new-agent {:id s/Str :name s/Str :primary_skillset [s/Str] :secondary_skillset [s/Str]}) (s/defschema new-job {:id s/Str :type s/Str :urgent s/Bool}) (s/defschema agent-id {:agent_id s/Str}) (s/defschema agent-sum [{:type s/Str :jobs s/Int}]) (s/defschema error-message {:message s/Str}) (s/defschema job-sum {:completed [s/Str] :processing [s/Str] :unassigned [s/Str]}) (s/defschema job-request {:job_request {:job_id s/Str :agent_id s/Str}}) (defapi service-routes {:swagger {:ui "/swagger-ui" :spec "/swagger.json" :data {:info {:version "1.0.0" :title "Job Queue API" :description "Manages agent resources"}}}} (context "/agent" [] (resource {:tags ["agent"] :put {:summary "Add a new agent" :responses {http-status/created {:description "Agent Created"} http-status/bad-request {:description "Agent id already exists" :schema error-message}} :parameters {:body-params new-agent} :handler (fn [{body :body-params}] (if (nil? (db/agent (:id body))) (do (db/add-agent body) {:status 201}) (bad-request {:message "Agent id already exists"})))} :post {:summary "Get summary of an agent" :parameters {:body-params agent-id} :responses {http-status/ok {:schema agent-sum :description "Fetched correctly"} http-status/not-found {:schema error-message :description "Agent not found"}} :handler (fn [{body :body-params}] (let [a (:agent_id body)] (if-not (nil? (db/agent a)) (let [jobs (db/sum-agent a)] (ok (map (fn [x] {:type (first x) :jobs (last x)}) jobs))) (not-found {:message "Agent does not exist"}))))}})) (context "/job" [] (resource {:tags ["job"] :put {:summary "Add a new job" :responses {http-status/created {:description "Job Created"} http-status/bad-request {:description "Job id already exists" :schema error-message}} :parameters {:body-params new-job} :handler (fn [{body :body-params}] (if (nil? (db/job (:id body))) (do (db/add-job body) {:status 201}) (bad-request {:message "job id already exist"})))} :post {:summary "Request a job to a given agent" :responses {http-status/ok {:description "Job assigned successfully" :schema job-request} http-status/not-found {:description "Agent not found or there is no job avaliable" :schema error-message}} :parameters {:body-params agent-id} :handler (fn [{body :body-params}] (let [id (:agent_id body) a (db/agent id)] (if (nil? a) (not-found {:message "Agent does not exist"})) (let [j (db/dequeue-job id)] (if (nil? j) (not-found {:message "There is no job available for given agent"}) (ok {:job_request {:job_id j :agent_id id}})))))} :get {:summary "Get queue summary" :responses {http-status/ok {:description "Jobs summary fetched correctly" :schema job-sum}} :handler (fn [_] (ok (db/sum-queue)))}})))