From b97b545add872cbb8bb2ae65794db822c8ca7af1 Mon Sep 17 00:00:00 2001 From: Sam Van Campenhout Date: Wed, 12 Mar 2025 10:51:52 +0100 Subject: [PATCH 1/2] Set up the jobs dashboard Based on the same setup in the worship decisions app: https://github.com/lblod/app-worship-decisions-database/pull/29 --- CHANGELOG.md | 21 +++ README.md | 23 +++ config/authorization/config.ex | 53 +++++++ config/dispatcher/dispatcher.ex | 39 +++++ config/resources/domain.lisp | 2 + config/resources/files-domain.lisp | 5 +- config/resources/job.json | 147 ++++++++++++++++++ config/resources/report.json | 36 +++++ docker-compose.yml | 14 ++ scripts/project/config.json | 17 +- .../project/generate-dashboard-login/run.sh | 80 ++++++++++ 11 files changed, 435 insertions(+), 2 deletions(-) create mode 100644 config/resources/job.json create mode 100644 config/resources/report.json create mode 100755 scripts/project/generate-dashboard-login/run.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f5043f..126bdb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Bump `triplestore` and `publication-triplestore` to `v1.3.0-rc.1`. [OP-2492] [OP-3547] - Add missing docker compose keys. [DL-6490] - Reorganize delta consumers config to harmonize with the ecosystem +- Set up the dashboard app [OP-3103] ### Deploy notes ``` drc restart migrations; drc logs -ft --tail=200 migrations @@ -20,6 +21,26 @@ drc up -d mandatarissen-consumer leidinggevenden-consumer worship-services-main- drc up -d search elasticsearch ``` +#### Dashboard + +The dashboard requires some server specific configuration before it can be used. + +##### 1. Dashboard domains +To configure the domain name that's used by the dashboard frontend, you can add it to the `VIRTUAL_HOST` and `LETSENCRYPT_HOST` environment variables of the identifier service. +- DEV domain: dev.dashboard.app-organisation-portal.contacthub-dev.s.redhost.be +- QA domain: qa.dashboard.app-organisation-portal.contacthub-dev.s.redhost.be +- PROD domain: dashboard.app-organisation-portal.organisaties.s.redpencil.io + +##### 2. Dashboard users +Before we can generate a user we need to add an application salt to the server. Add a `MU_APPLICATION_SALT` environment variable to the `dashboard-login` service in the docker-compose.override.yml file. + +Once this is done you can generate a user by running `mu script project-scripts generate-dashboard-login` and following the prompts. A new local migration will be generated which can be run by restarting the migrations service and which will insert the new user into the database. + +Store the login credentials as a comment in the docker-compose.override.yml file. + +##### 3. (Re)start the needed services +`drc up -d frontend-dashboard dashboard-login identifier; drc restart dispatcher resource db` + ## v1.30.5 (2025-03-10) ### Backend - Added `http://www.w3.org/ns/prov#Location` to delta stream 'public' [DL-6496] diff --git a/README.md b/README.md index 4fa218d..1884f32 100644 --- a/README.md +++ b/README.md @@ -185,3 +185,26 @@ To make sure the app can share data, producers need to be set up. There is an in ) } ``` + +## Configuring the dashboard +### Accessing the dashboard from your local machine + +Since we use dispatcher v2, which dispatches on hostname, we'll have to update `/etc/hosts`. +Add an entry similar to the following. Ensure the first part of the domain starts with `dashboard`.: + +``` +127.0.0.1 dashboard.localhost +``` + +### Creating new users +For now, we use specific logins for the dashboard users. Each environment has its own passwords. + +To add a user, make sure to have [mu-cli](https://github.com/mu-semtech/mu-cli) installed first. +Then in `docker-compose.override.yml` +``` + dashboard-login: + environment: + MU_APPLICATION_SALT: 'a_random_string_with_sufficient_entropy_hence_not_this_one' +``` +You can now generate a user by running `mu script project-scripts generate-dashboard-login` and following the steps. +Restart `migrations` and it should insert the new user into the database. \ No newline at end of file diff --git a/config/authorization/config.ex b/config/authorization/config.ex index 1983140..fcb6d7e 100644 --- a/config/authorization/config.ex +++ b/config/authorization/config.ex @@ -107,6 +107,19 @@ defmodule Acl.UserGroups.Config do }" end + defp can_access_dashboard() do + %AccessByQuery{ + vars: [], + query: "PREFIX ext: + PREFIX mu: + SELECT DISTINCT ?account WHERE { + ?account. + ?account ?session_role. + FILTER( ?session_role = \"dashboard-user\" ) + }" + } + end + def user_groups do [ %GroupSpec{ @@ -206,6 +219,46 @@ defmodule Acl.UserGroups.Config do } ] }, + # // dashboard users + %GroupSpec{ + name: "dashboard-users", + useage: [:read], + access: can_access_dashboard(), + graphs: [ + %GraphSpec{ + graph: "http://mu.semte.ch/graphs/reports", + constraint: %ResourceConstraint{ + resource_types: [ + "http://lblod.data.gift/vocabularies/reporting/Report", + "http://open-services.net/ns/core#Error", + "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#DataContainer", + "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject" + ] + } + }, + %GraphSpec{ + graph: "http://mu.semte.ch/graphs/system/jobs", + constraint: %ResourceConstraint{ + resource_types: [ + "http://vocab.deri.ie/cogs#Job", + "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#DataContainer", + "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject" + ] + } + }, + # OP stores jobs in multiple graphs, so we configure both until they are merged into one graph + %GraphSpec{ + graph: "http://mu.semte.ch/graphs/jobs", + constraint: %ResourceConstraint{ + resource_types: [ + "http://vocab.deri.ie/cogs#Job", + "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#DataContainer", + "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject" + ] + } + }, + ] + }, # // CLEANUP # diff --git a/config/dispatcher/dispatcher.ex b/config/dispatcher/dispatcher.ex index a58f69a..f647abf 100644 --- a/config/dispatcher/dispatcher.ex +++ b/config/dispatcher/dispatcher.ex @@ -240,6 +240,27 @@ defmodule Dispatcher do Proxy.forward(conn, path, "http://resource/kbo-organizations/") end + # Dashboard + match "/jobs/*path", %{accept: [:json], layer: :api} do + Proxy.forward(conn, path, "http://cache/jobs/") + end + + match "/tasks/*path", %{accept: [:json], layer: :api} do + Proxy.forward(conn, path, "http://cache/tasks/") + end + + match "/data-containers/*path", %{accept: [:json], layer: :api} do + Proxy.forward(conn, path, "http://cache/data-containers/") + end + + match "/job-errors/*path", %{accept: [:json], layer: :api} do + Proxy.forward(conn, path, "http://cache/job-errors/") + end + + match "/reports/*path", %{accept: [:json], layer: :api} do + Proxy.forward(conn, path, "http://resource/reports/") + end + ############### # LOGIN ############### @@ -264,6 +285,10 @@ defmodule Dispatcher do Proxy.forward(conn, path, "http://mocklogin/sessions/") end + match "/sessions/*path", %{ reverse_host: ["dashboard" | _rest] } do + Proxy.forward conn, path, "http://dashboard-login/sessions/" + end + match "/sessions/*path", %{accept: [:any], layer: :api} do Proxy.forward(conn, path, "http://login/sessions/") end @@ -428,6 +453,20 @@ defmodule Dispatcher do # frontend layer ############################################################### + get "/assets/*path", %{ reverse_host: ["dashboard" | _rest], layer: :api } do + forward conn, path, "http://frontend-dashboard/assets/" + end + + get "/@appuniversum/*path", %{ reverse_host: ["dashboard" | _rest], layer: :api} do + forward conn, path, "http://frontend-dashboard/@appuniversum/" + end + + match "/*_path", %{ reverse_host: ["dashboard" | _rest], layer: :api } do + # *_path allows a path to be supplied, but will not yield + # an error that we don't use the path variable. + forward conn, [], "http://frontend-dashboard/index.html" + end + match "/assets/*path", %{layer: :api} do Proxy.forward(conn, path, "http://frontend/assets/") end diff --git a/config/resources/domain.lisp b/config/resources/domain.lisp index a9fa35f..18fb9c0 100644 --- a/config/resources/domain.lisp +++ b/config/resources/domain.lisp @@ -20,3 +20,5 @@ (read-domain-file "files-domain.lisp") (read-domain-file "dcat.json") (read-domain-file "privacy-centric-service.json") +(read-domain-file "job.json") +(read-domain-file "report.json") diff --git a/config/resources/files-domain.lisp b/config/resources/files-domain.lisp index b9dfdcf..36589ef 100644 --- a/config/resources/files-domain.lisp +++ b/config/resources/files-domain.lisp @@ -7,7 +7,10 @@ (:created :datetime ,(s-prefix "nfo:fileCreated"))) :has-one `((file :via ,(s-prefix "nie:dataSource") :inverse t - :as "download")) + :as "download") + (data-container :via ,(s-prefix "task:hasFile") + :inverse t + :as "data-container")) :resource-base (s-url "http://data.lblod.info/files/") :features `(no-pagination-defaults include-uri) :on-path "files") diff --git a/config/resources/job.json b/config/resources/job.json new file mode 100644 index 0000000..dba13a1 --- /dev/null +++ b/config/resources/job.json @@ -0,0 +1,147 @@ +{ + "version": "0.1", + "prefixes": { + "adms": "http://www.w3.org/ns/adms#", + "cogs": "http://vocab.deri.ie/cogs#", + "dct": "http://purl.org/dc/terms/", + "oslc": "http://open-services.net/ns/core#", + "nfo": "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#", + "task": "http://redpencil.data.gift/vocabularies/tasks/" + }, + "resources": { + "jobs": { + "name": "job", + "class": "cogs:Job", + "attributes": { + "created": { + "type": "datetime", + "predicate": "dct:created" + }, + "modified": { + "type": "datetime", + "predicate": "dct:modified" + }, + "creator": { + "type": "url", + "predicate": "dct:creator" + }, + "status": { + "type": "url", + "predicate": "adms:status" + }, + "operation": { + "type": "url", + "predicate": "task:operation" + } + }, + "relationships": { + "error": { + "predicate": "task:error", + "target": "job-error", + "cardinality": "one" + }, + "tasks": { + "predicate": "dct:isPartOf", + "target": "group", + "cardinality": "many", + "inverse": true + } + }, + "features": ["include-uri"], + "new-resource-base": "http://redpencil.data.gift/id/job/" + }, + "tasks": { + "name": "task", + "class": "task:Task", + "attributes": { + "created": { + "type": "datetime", + "predicate": "dct:created" + }, + "modified": { + "type": "datetime", + "predicate": "dct:modified" + }, + "status": { + "type": "url", + "predicate": "adms:status" + }, + "operation": { + "type": "url", + "predicate": "task:operation" + }, + "index": { + "type": "string", + "predicate": "task:index" + } + }, + "relationships": { + "error": { + "predicate": "task:error", + "target": "job-error", + "cardinality": "one" + }, + "job": { + "predicate": "dct:isPartOf", + "target": "job", + "cardinality": "one" + }, + "parent-tasks": { + "predicate": "cogs:dependsOn", + "target": "task", + "cardinality": "many" + }, + "results-containers": { + "predicate": "task:resultsContainer", + "target": "data-container", + "cardinality": "many" + }, + "input-containers": { + "predicate": "task:inputContainer", + "target": "data-container", + "cardinality": "many" + } + }, + "features": ["include-uri"], + "new-resource-base": "http://redpencil.data.gift/id/task/" + }, + "job-errors": { + "name": "job-error", + "class": "oslc:Error", + "attributes": { + "message": { + "type": "string", + "predicate": "oslc:message" + } + }, + "features": ["include-uri"], + "new-resource-base": "http://redpencil.data.gift/id/jobs/error/" + }, + "data-containers": { + "name": "data-container", + "class": "nfo:DataContainer", + "attributes": { + "has-graph": { + "type": "url", + "predicate": "task:hasGraph" + } + }, + "relationships": { + "result-from-tasks": { + "predicate": "task:resultsContainer", + "target": "task", + "cardinality": "many", + "inverse": true + }, + "input-from-tasks": { + "predicate": "task:inputContainer", + "target": "task", + "cardinality": "many", + "inverse":true + } + }, + "features": ["include-uri"], + "new-resource-base": "http://redpencil.data.gift/id/dataContainers/" + } + } +} \ No newline at end of file diff --git a/config/resources/report.json b/config/resources/report.json new file mode 100644 index 0000000..2463efe --- /dev/null +++ b/config/resources/report.json @@ -0,0 +1,36 @@ +{ + "version": "0.1", + "prefixes": { + "dct": "http://purl.org/dc/terms/", + "prov": "http://www.w3.org/ns/prov#" + }, + "resources": { + "reports": { + "name": "report", + "class": "http://lblod.data.gift/vocabularies/reporting/Report", + "attributes": { + "created": { + "type": "datetime", + "predicate": "dct:created" + }, + "title": { + "type": "string", + "predicate": "dct:title" + }, + "description": { + "type": "string", + "predicate": "dct:description" + } + }, + "relationships": { + "file": { + "predicate": "prov:generated", + "target": "file", + "cardinality": "one" + } + }, + "features": ["include-uri"], + "new-resource-base": "http://data.lblod.info/id/reports/" + } + } +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 6a8aa37..162eaf3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -147,6 +147,14 @@ services: logging: *default-logging links: - db:database + dashboard-login: + image: semtech/mu-login-service:3.0.0 + links: + - db:database + labels: + - "logging=true" + restart: always + logging: *default-logging accountdetail: image: lblod/account-detail-service:0.1.0 labels: @@ -202,6 +210,12 @@ services: - "logging=true" restart: always logging: *default-logging + frontend-dashboard: + image: lblod/frontend-dashboard:1.7.0 + labels: + - "logging=true" + restart: always + logging: *default-logging uri-info: image: redpencil/mu-uri-info-service:0.2.1 links: diff --git a/scripts/project/config.json b/scripts/project/config.json index 2a8ae6f..471f975 100644 --- a/scripts/project/config.json +++ b/scripts/project/config.json @@ -16,6 +16,21 @@ "mounts": { "app": "/data/app/" } + }, + { + "documentation": { + "command": "generate-dashboard-login", + "description": "generate a login account for the jobs dashboard", + "arguments": [] + }, + "environment": { + "image": "ruby", + "interactive": true, + "script": "generate-dashboard-login/run.sh" + }, + "mounts": { + "app": "/project/" + } } ] -} +} \ No newline at end of file diff --git a/scripts/project/generate-dashboard-login/run.sh b/scripts/project/generate-dashboard-login/run.sh new file mode 100755 index 0000000..03f4aba --- /dev/null +++ b/scripts/project/generate-dashboard-login/run.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env ruby +require 'bundler/inline' +require 'yaml' +require 'securerandom' +require 'date' + +$stdout.sync = true +print "installing dependencies..." +gemfile do + source 'https://rubygems.org' + gem 'bcrypt' +end +puts "done" + +salt = "" +begin + File.open("/project/docker-compose.override.yml") do |file| + config = YAML.load(file) + salt = config.dig("services", "dashboard-login", "environment", "MU_APPLICATION_SALT") + throw "invalid salt" unless salt + end +rescue + puts "Tried to locate login salt in docker-compose.override.yml, but couldn't find it." + puts "Please make sure a salt is configured:" + puts < +PREFIX people: +PREFIX accounts: +PREFIX dcterms: +PREFIX mu: +PREFIX ext: +PREFIX account: +PREFIX xsd: +INSERT DATA { + GRAPH { + people:#{person_uuid} a foaf:Person ; + foaf:name "#{account_name}"; + foaf:account accounts:#{account_uuid}; + mu:uuid "#{person_uuid}"; + dcterms:created "#{now}"^^xsd:datetime; + dcterms:modified "#{now}"^^xsd:datetime. + accounts:#{account_uuid} a foaf:OnlineAccount; + foaf:accountName "#{account_name}"; + mu:uuid "#{account_uuid}"; + account:password """#{hashed_password}"""; + account:salt "#{account_salt}"; + account:status ; + dcterms:created "#{now}"^^xsd:datetime; + ext:sessionRole "dashboard-user"; + dcterms:modified "#{now}"^^xsd:datetime. +}} +) + +timestamp = DateTime.now.strftime("%Y%m%d%H%M%L") +filename = "#{timestamp}-create-user-#{account_name.gsub(" ", "-")}.sparql" +File.write("/project/config/migrations/local/#{filename}", query) +puts "generated migration ./config/migrations/local/#{filename} for #{account_name.inspect} : #{password.inspect}" \ No newline at end of file From 6cae455d468f85bdaa65e7c3189f25cb810a3aa0 Mon Sep 17 00:00:00 2001 From: Sam Van Campenhout Date: Wed, 12 Mar 2025 16:52:01 +0100 Subject: [PATCH 2/2] Disable the secure cookie flag in development This makes it easier to test the dashboard locally. --- config/dispatcher/dispatcher.ex | 20 ++++ .../20250313103300-create-log-levels.sparql | 33 ++++++ .../20250313103900-create-log-source.sparql | 7 ++ config/resources/domain.lisp | 4 +- config/resources/file.json | 107 ++++++++++++++++++ config/resources/files-domain.lisp | 16 --- config/resources/harvest.json | 40 +++++++ config/resources/job.json | 5 + config/resources/log.json | 92 +++++++++++++++ docker-compose.dev.yml | 2 + 10 files changed, 309 insertions(+), 17 deletions(-) create mode 100644 config/migrations/2025/20250313103300-create-log-levels.sparql create mode 100644 config/migrations/2025/20250313103900-create-log-source.sparql create mode 100644 config/resources/file.json delete mode 100644 config/resources/files-domain.lisp create mode 100644 config/resources/harvest.json create mode 100644 config/resources/log.json diff --git a/config/dispatcher/dispatcher.ex b/config/dispatcher/dispatcher.ex index f647abf..55093c1 100644 --- a/config/dispatcher/dispatcher.ex +++ b/config/dispatcher/dispatcher.ex @@ -261,6 +261,26 @@ defmodule Dispatcher do Proxy.forward(conn, path, "http://resource/reports/") end + match "/log-entries/*path", %{accept: [:json], layer: :api} do + Proxy.forward(conn, path, "http://resource/log-entries/") + end + + match "/log-levels/*path", %{accept: [:json], layer: :api} do + Proxy.forward(conn, path, "http://resource/log-levels/") + end + + match "/status-codes/*path", %{accept: [:json], layer: :api} do + Proxy.forward(conn, path, "http://resource/status-codes/") + end + + match "/log-sources/*path", %{accept: [:json], layer: :api} do + Proxy.forward(conn, path, "http://resource/log-sources/") + end + + match "/remote-data-objects/*path", %{accept: [:json], layer: :api} do + Proxy.forward(conn, path, "http://resource/remote-data-objects/") + end + ############### # LOGIN ############### diff --git a/config/migrations/2025/20250313103300-create-log-levels.sparql b/config/migrations/2025/20250313103300-create-log-levels.sparql new file mode 100644 index 0000000..3f16043 --- /dev/null +++ b/config/migrations/2025/20250313103300-create-log-levels.sparql @@ -0,0 +1,33 @@ +INSERT DATA { + GRAPH { + a ; + "0986a9b6-b543-4629-8ef8-08928ae42430" ; + 1 ; + "TRACE" . + + a ; + "fe6473d5-ac83-450c-83f8-3546357c7117" ; + 2 ; + "DEBUG" . + + a ; + "6f92baad-b4a1-42ce-8bdf-e28218b27ff9" ; + 3 ; + "INFO" . + + a ; + "62d2516b-e6b8-4866-aad1-e8347f2cdc70" ; + 4 ; + "WARN" . + + a ; + "3af9ebe1-e6a8-495c-a392-16ced1f38ef1" ; + 5 ; + "ERROR" . + + a ; + "c679f915-1fdd-4b50-938d-6b565aa31278" ; + 6 ; + "FATAL" . + } +} \ No newline at end of file diff --git a/config/migrations/2025/20250313103900-create-log-source.sparql b/config/migrations/2025/20250313103900-create-log-source.sparql new file mode 100644 index 0000000..703f6ec --- /dev/null +++ b/config/migrations/2025/20250313103900-create-log-source.sparql @@ -0,0 +1,7 @@ +INSERT DATA { + GRAPH { + a ; + "c7806563-25a4-46c8-9be2-a0cdf0db1f98" ; + "Acmidm login service" . + } +} \ No newline at end of file diff --git a/config/resources/domain.lisp b/config/resources/domain.lisp index 18fb9c0..f2d2fd4 100644 --- a/config/resources/domain.lisp +++ b/config/resources/domain.lisp @@ -17,8 +17,10 @@ (read-domain-file "domain.json") (read-domain-file "auth.json") (read-domain-file "change-events.json") -(read-domain-file "files-domain.lisp") +(read-domain-file "file.json") (read-domain-file "dcat.json") (read-domain-file "privacy-centric-service.json") (read-domain-file "job.json") (read-domain-file "report.json") +(read-domain-file "log.json") +(read-domain-file "harvest.json") diff --git a/config/resources/file.json b/config/resources/file.json new file mode 100644 index 0000000..6c75fab --- /dev/null +++ b/config/resources/file.json @@ -0,0 +1,107 @@ +{ + "version": "0.1", + "prefixes": { + "adms": "http://www.w3.org/ns/adms#", + "dct": "http://purl.org/dc/terms/", + "dbpedia": "http://dbpedia.org/ontology/", + "nfo": "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#", + "nie": "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#", + "rpioHttp": "http://redpencil.data.gift/vocabularies/http/", + "skos": "http://www.w3.org/2004/02/skos/core#", + "task": "http://redpencil.data.gift/vocabularies/tasks/" + }, + "resources": { + "files": { + "name": "file", + "class": "nfo:FileDataObject", + "attributes": { + "filename": { + "type": "string", + "predicate": "nfo:fileName" + }, + "format": { + "type": "string", + "predicate": "dct:format" + }, + "size": { + "type": "number", + "predicate": "nfo:fileSize" + }, + "extension": { + "type": "string", + "predicate": "dbpedia:fileExtension" + }, + "created": { + "type": "datetime", + "predicate": "nfo:fileCreated" + } + }, + "relationships": { + "download": { + "predicate": "nie:dataSource", + "target": "file", + "cardinality": "one", + "inverse": true + }, + "data-container": { + "predicate": "task:hasFile", + "target": "data-container", + "cardinality": "one", + "inverse": true + } + }, + "features": ["include-uri"], + "new-resource-base": "http://data.lblod.info/files/" + }, + "remote-data-objects": { + "name": "remote-data-object", + "class": "nfo:RemoteDataObject", + "attributes": { + "source": { + "type": "url", + "predicate": "nie:url" + }, + "created": { + "type": "datetime", + "predicate": "dct:created" + }, + "modified": { + "type": "datetime", + "predicate": "dct:modified" + }, + "request-header": { + "type": "url", + "predicate": "rpioHttp:requestHeader" + }, + "status": { + "type": "url", + "predicate": "adms:status" + }, + "comment": { + "type": "string", + "predicate": "skos:comment" + }, + "creator": { + "type": "url", + "predicate": "dct:creator" + } + }, + "relationships": { + "file": { + "predicate": "nie:dataSource", + "target": "file", + "cardinality": "one", + "inverse": true + }, + "harvesting-collection": { + "predicate": "dct:hasPart", + "target": "harvesting-collection", + "cardinality": "one", + "inverse": true + } + }, + "features": ["include-uri"], + "new-resource-base": "http://data.lblod.info/id/remote-data-objects/" + } + } +} \ No newline at end of file diff --git a/config/resources/files-domain.lisp b/config/resources/files-domain.lisp deleted file mode 100644 index 36589ef..0000000 --- a/config/resources/files-domain.lisp +++ /dev/null @@ -1,16 +0,0 @@ -(define-resource file () - :class (s-prefix "nfo:FileDataObject") - :properties `((:filename :string ,(s-prefix "nfo:fileName")) - (:format :string ,(s-prefix "dct:format")) - (:size :number ,(s-prefix "nfo:fileSize")) - (:extension :string ,(s-prefix "dbpedia:fileExtension")) - (:created :datetime ,(s-prefix "nfo:fileCreated"))) - :has-one `((file :via ,(s-prefix "nie:dataSource") - :inverse t - :as "download") - (data-container :via ,(s-prefix "task:hasFile") - :inverse t - :as "data-container")) - :resource-base (s-url "http://data.lblod.info/files/") - :features `(no-pagination-defaults include-uri) - :on-path "files") diff --git a/config/resources/harvest.json b/config/resources/harvest.json new file mode 100644 index 0000000..4115426 --- /dev/null +++ b/config/resources/harvest.json @@ -0,0 +1,40 @@ +{ + "version": "0.1", + "prefixes": { + "adms": "http://www.w3.org/ns/adms#", + "dct": "http://purl.org/dc/terms/", + "hrvst": "http://lblod.data.gift/vocabularies/harvesting/", + "task": "http://redpencil.data.gift/vocabularies/tasks/" + }, + "resources": { + "harvesting-collections": { + "name": "harvesting-collection", + "class": "hrvst:HarvestingCollection", + "attributes": { + "status": { + "type": "url", + "predicate": "adms:status" + }, + "creator": { + "type": "url", + "predicate": "dct:creator" + } + }, + "relationships": { + "remote-data-objects": { + "predicate": "dct:hasPart", + "target": "remote-data-object", + "cardinality": "many" + }, + "data-container": { + "predicate": "task:hasHarvestingCollection", + "target": "data-container", + "cardinality": "many", + "inverse": true + } + }, + "features": ["include-uri"], + "new-resource-base": "http://data.lblod.info/id/harvesting-collection/" + } + } +} \ No newline at end of file diff --git a/config/resources/job.json b/config/resources/job.json index dba13a1..5f8bbff 100644 --- a/config/resources/job.json +++ b/config/resources/job.json @@ -127,6 +127,11 @@ } }, "relationships": { + "harvesting-collections": { + "predicate": "task:hasHarvestingCollection", + "target": "harvesting-collection", + "cardinality": "many" + }, "result-from-tasks": { "predicate": "task:resultsContainer", "target": "task", diff --git a/config/resources/log.json b/config/resources/log.json new file mode 100644 index 0000000..963bcd4 --- /dev/null +++ b/config/resources/log.json @@ -0,0 +1,92 @@ +{ + "version": "0.1", + "prefixes": { + "dct": "http://purl.org/dc/terms/", + "ext": "http://mu.semte.ch/vocabularies/ext/", + "rlog": "http://persistence.uni-leipzig.org/nlp2rdf/ontologies/rlog#", + "skos": "http://www.w3.org/2004/02/skos/core#" + }, + "resources": { + "log-entries": { + "name": "log-entry", + "class": "rlog:Entry", + "attributes": { + "class-name": { + "type": "url", + "predicate": "rlog:className" + }, + "message": { + "type": "string", + "predicate": "rlog:message" + }, + "specific-information": { + "type": "string", + "predicate": "ext:specificInformation" + }, + "datetime": { + "type": "datetime", + "predicate": "rlog:date" + } + }, + "relationships": { + "log-level": { + "predicate": "rlog:level", + "target": "log-level", + "cardinality": "one" + }, + "status-code": { + "predicate": "rlog:hasCode", + "target": "status-code", + "cardinality": "one" + }, + "log-source": { + "predicate": "dct:source", + "target": "log-source", + "cardinality": "one" + } + }, + "features": ["include-uri"], + "new-resource-base": "http://data.lblod.info/id/log-entries/" + }, + "log-levels": { + "name": "log-level", + "class": "rlog:Level", + "attributes": { + "priority": { + "type": "number", + "predicate": "rlog:priority" + }, + "label": { + "type": "string", + "predicate": "skos:prefLabel" + } + }, + "features": ["include-uri"], + "new-resource-base": "http://data.lblod.info/id/log-levels/" + }, + "status-codes": { + "name": "status-code", + "class": "rlog:StatusCode", + "attributes": { + "code": { + "type": "number", + "predicate": "rlog:codeId" + } + }, + "features": ["include-uri"], + "new-resource-base": "http://data.lblod.info/id/status-codes/" + }, + "log-sources": { + "name": "log-source", + "class": "ext:LogSource", + "attributes": { + "label": { + "type": "string", + "predicate": "skos:prefLabel" + } + }, + "features": ["include-uri"], + "new-resource-base": "http://data.lblod.info/id/log-sources/" + } + } +} \ No newline at end of file diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index f9d2111..1b9a2a0 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -5,6 +5,8 @@ services: restart: "no" ports: - "80:80" + environment: + SESSION_COOKIE_SECURE: "off" dispatcher: restart: "no" triplestore: