From df0f1a4fb4920d44e95e9d53fc2f462346c2d94a Mon Sep 17 00:00:00 2001 From: Michiel de Mare Date: Wed, 20 Nov 2024 14:17:31 +0100 Subject: [PATCH 1/2] Remove unused root-url; use it in web-url --- resources/public/javascript/status.js | 1 + src/nl/surf/eduhub/validator/service/api.clj | 15 ++------------- .../surf/eduhub/validator/service/jobs/client.clj | 4 ++-- src/nl/surf/eduhub/validator/service/main.clj | 1 - .../eduhub/validator/service/views/status.clj | 10 +++++----- 5 files changed, 10 insertions(+), 21 deletions(-) diff --git a/resources/public/javascript/status.js b/resources/public/javascript/status.js index c1575cb..b291a9c 100644 --- a/resources/public/javascript/status.js +++ b/resources/public/javascript/status.js @@ -1,4 +1,5 @@ // Define the endpoint and polling interval (in milliseconds) +const rootUrl = `${window.location.protocol}//${window.location.host}`; const endpoint = `${rootUrl}/status/${validationUuid}`; // Replace with your actual endpoint const pollInterval = 2000; // Poll every 5 seconds diff --git a/src/nl/surf/eduhub/validator/service/api.clj b/src/nl/surf/eduhub/validator/service/api.clj index acabcac..5739fe8 100644 --- a/src/nl/surf/eduhub/validator/service/api.clj +++ b/src/nl/surf/eduhub/validator/service/api.clj @@ -30,17 +30,6 @@ [ring.middleware.json :refer [wrap-json-response]] [ring.middleware.resource :refer [wrap-resource]])) -;; Many response handlers have the same structure - with this function they can be written inline. -;; `activate-handler?` is a function that takes a request and returns a boolean which determines if -;; the current handler should be activated (or skipped). -;; `response-handler` takes an intermediate response and processes it into the next step. -(defn wrap-response-handler [app action response-handler config] - (fn [req] - (let [resp (app req)] - (if (= action (:action resp)) - (response-handler (dissoc resp :action) config) - resp)))) - ;; Turn the contents of a job status (stored in redis) into an http response. (defn- job-status-handler [uuid {:keys [redis-conn] :as _config}] (let [job-status (status/load-status redis-conn uuid)] @@ -58,10 +47,10 @@ (status/delete-status redis-conn uuid) {:status http-status/see-other :headers {"Location" (str "/view/status/" uuid)}}) -(defn- view-status-handler [uuid {:keys [redis-conn] :as config}] +(defn- view-status-handler [uuid {:keys [redis-conn] :as _config}] (let [validation (status/load-status redis-conn uuid)] (if validation - {:status http-status/ok :body (views.status/render (assoc validation :uuid uuid) config)} + {:status http-status/ok :body (views.status/render (assoc validation :uuid uuid))} {:status http-status/not-found :body (views.status/render-not-found)}))) (defn wrap-html-response [app] diff --git a/src/nl/surf/eduhub/validator/service/jobs/client.clj b/src/nl/surf/eduhub/validator/service/jobs/client.clj index 01452bf..064b464 100644 --- a/src/nl/surf/eduhub/validator/service/jobs/client.clj +++ b/src/nl/surf/eduhub/validator/service/jobs/client.clj @@ -16,7 +16,7 @@ ;; Enqueue the validate-endpoint call in the worker queue. (defn enqueue-validation - [endpoint-id profile {:keys [redis-conn gateway-basic-auth gateway-url ooapi-version max-total-requests] :as _config}] + [endpoint-id profile {:keys [redis-conn gateway-basic-auth gateway-url ooapi-version max-total-requests root-url] :as _config}] (let [uuid (str (UUID/randomUUID)) prof (or profile "rio") opts {:basic-auth gateway-basic-auth @@ -26,4 +26,4 @@ :profile prof}] (status/set-status-fields redis-conn uuid "pending" {:endpoint-id endpoint-id, :profile prof} nil) (c/perform-async client-opts `worker/validate-endpoint endpoint-id uuid opts) - {:status 200 :body {:job-status "pending" :uuid uuid, :web-url (str "http://localhost:3002/view/status/" uuid)}})) + {:status 200 :body {:job-status "pending" :uuid uuid, :web-url (str root-url "/view/status/" uuid)}})) diff --git a/src/nl/surf/eduhub/validator/service/main.clj b/src/nl/surf/eduhub/validator/service/main.clj index d8dfd51..b3f3476 100644 --- a/src/nl/surf/eduhub/validator/service/main.clj +++ b/src/nl/surf/eduhub/validator/service/main.clj @@ -28,7 +28,6 @@ ;; Starts a Jetty server on given port. (defn start-server [routes {:keys [server-port] :as _config}] (let [server (-> routes - (run-jetty {:port server-port :join? false})) handler ^Runnable (fn [] (.stop server))] ;; Add a shutdown hook to stop Jetty on JVM exit (Ctrl+C) diff --git a/src/nl/surf/eduhub/validator/service/views/status.clj b/src/nl/surf/eduhub/validator/service/views/status.clj index 970c4d6..7973cf8 100644 --- a/src/nl/surf/eduhub/validator/service/views/status.clj +++ b/src/nl/surf/eduhub/validator/service/views/status.clj @@ -16,7 +16,7 @@ h2/html str)) -(defn render [{:keys [endpoint-id job-status profile uuid]} {:keys [root-url] :as _config}] +(defn render [{:keys [endpoint-id job-status profile uuid]}] {:pre [job-status profile uuid endpoint-id]} (let [display (if (= "finished" job-status) "block" "none")] (-> @@ -27,7 +27,7 @@ [:meta {:name "viewport" :content "width=device-width, initial-scale=1.0"}] [:title "Status Report"] [:link {:href "/stylesheets/all.css" :rel "stylesheet"}] - [:script (h2/raw (str "var rootUrl = '" root-url "'; var validationUuid = '" uuid "';"))] + [:script (h2/raw (str "var validationUuid = '" uuid "';"))] [:script {:src "/javascript/status.js"}] ;; Start polling for the status to change to "finished" or "failed" [:script (when (= job-status "pending") (h2/raw (str "const polling = setInterval(pollJobStatus, pollInterval);")))]] @@ -37,9 +37,9 @@ [:p.status {:id "job-status" :class job-status} (str "Status: " job-status)] [:p (str "Profile Name: " profile)] [:div {:style (str "margin-left: 100px; display: " display)} - [:a.button.report-button {:href (str root-url "/view/report/" uuid)} "View Report"] - [:a.button.report-button {:href (str root-url "/download/report/" uuid)} "Download Report"] - [:form {:action (str root-url "/delete/report/" uuid) :method "POST"} + [:a.button.report-button {:href (str "/view/report/" uuid)} "View Report"] + [:a.button.report-button {:href (str "/download/report/" uuid)} "Download Report"] + [:form {:action (str "/delete/report/" uuid) :method "POST"} [:button.delete-button.button {:type "submit"} "Delete Report"]]]]]] h2/html str))) From bb44b8aceec48f7b1ebc4b7d7736acda1c7101b2 Mon Sep 17 00:00:00 2001 From: Michiel de Mare Date: Wed, 20 Nov 2024 14:17:40 +0100 Subject: [PATCH 2/2] Updated README --- readme.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 9df51d4..c4049ee 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,9 @@ A web service for validating Eduhub OOAPI endpoints ## API -`GET /endpoints/{endpointId}/config` +### Check endpoint. + +Perform basic checks on whether the endpoint is up. Calls the endpoint with `endpointId` through the Eduhub gateway and reports if a successful response is received. @@ -13,6 +15,47 @@ On success, responds with a `200 OK` status On error, responds with a `502 Bad Gateway` status. +`GET /endpoints/{endpointId}/config` + +### Validate endpoint + +Use the validator to validate the endpoint and generate a report. + +`GET /endpoints/{endpointId}/paths` + +### Fetch Status + +Load the current status as json. Fields include job-status (pending, finished or failed), endpoint-id, profile, +pending-at and finished-at, with ISO-8601 timestamp format. + +`GET /status/{uuid}` + +# HTML Endpoints + +## View status + +View the status in the browser. If the status is finished, the report can be viewed, downloaded or deleted from this page. + +`GET /view/status/{uuid}` + +## View report + +View the validation report in the browser. + +`GET /view/report/{uuid}` + +## Download Report + +Download report as a HTML file. + +`GET /download/report/{uuid}` + +# Delete report + +Delete the report and the associated status data from the Redis database. + +`POST /delete/report/{uuid}` + ## Configuring The service is configured using environment variables: @@ -31,6 +74,7 @@ SERVER_PORT Starts the app server on this port REDIS_URI URI to redis JOB_STATUS_EXPIRY_SECONDS Number of seconds before job status in Redis expires SPIDER_TIMEOUT_MILLIS Maximum number of milliseconds before spider timeout. +VALIDATOR_SERVICE_ROOT_URL The root url of the web endpoint, used to generate a url to a status view. This url is included in the json output after starting a validation job as "web-url". ``` ## Build @@ -50,6 +94,17 @@ make docker-build docker compose up # To test: curl -v 'http://localhost:3002/endpoints/demo04.test.surfeduhub.nl/config' +curl -v 'http://localhost:3002/endpoints/demo04.test.surfeduhub.nl/paths' +``` + +## Run locally + +```bash +make +java -jar target/eduhub-validator-service.jar +# Extract ACCESS_TOKEN +curl -s -X POST https://connect.test.surfconext.nl/oidc/token -u client01.registry.validator.dev.surfeduhub.nl:$SURF_CONEXT_PASSWORD -d "grant_type=client_credentials" +curl -v -X POST 'http://localhost:3002/endpoints/demo04.test.surfeduhub.nl/paths?profile=rio' -H "Authorization: Bearer $ACCESS_TOKEN" ``` ## Notes