diff --git a/.github/workflows/assembly.yml b/.github/workflows/assembly.yml index f510c94c427..5e4d0c0a11b 100644 --- a/.github/workflows/assembly.yml +++ b/.github/workflows/assembly.yml @@ -3,6 +3,10 @@ name: Assembly GitHub CI on: pull_request +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + env: MAVEN_OPTS: -Dmaven.wagon.httpconnectionManager.ttlSeconds=25 -Dmaven.wagon.http.retryHandler.count=3 -Xmx756m -Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dspotless.apply.skip=true diff --git a/.github/workflows/cite.yml b/.github/workflows/cite.yml new file mode 100644 index 00000000000..d933129d39c --- /dev/null +++ b/.github/workflows/cite.yml @@ -0,0 +1,127 @@ +name: Run CITE Tests + +on: + pull_request: + paths-ignore: + - '**/src/main/resources/GeoServerApplication_*.properties' + - '!**/src/main/resources/GeoServerApplication_fr.properties' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + build-war: + runs-on: ubuntu-latest + name: Build GeoServer WAR + steps: + - name: Checkout repository (shallow clone) + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - name: Set up Maven + uses: stCarolas/setup-maven@v5 + with: + maven-version: 3.9.8 + - name: Maven repository caching + uses: actions/cache@v4 + with: + path: ~/.m2/repository + key: gs-${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + gs-${{ runner.os }}-maven- + + - name: Build geoserver.war + working-directory: build/cite + run: make war + + - name: Upload geoserver.war as artifact + uses: actions/upload-artifact@v3 + with: + name: geoserver-war + path: build/cite/geoserver/geoserver.war + + run-cite-tests: + needs: build-war + runs-on: ubuntu-latest + name: CITE + strategy: + fail-fast: false # Prevents other matrix jobs from being canceled if one fails + matrix: + #suite: [ogcapi-features10, wcs10, wcs11, wfs10, wfs11, wms10, wms11, wms13] + suite: [ogcapi-features10, wms11, wfs10, wfs11, wcs11] + + steps: + - name: Checkout repository (shallow clone) + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Download geoserver.war artifact + uses: actions/download-artifact@v3 + with: + name: geoserver-war + path: build/cite/geoserver/ + + - name: Print services and images used for the ${{ matrix.suite }} test run + # in case there's a jq syntax error + continue-on-error: true + working-directory: build/cite + run: make print-services suite=${{ matrix.suite }} + + - name: Pull teamengine and other required images + working-directory: build/cite + continue-on-error: true + run: make pull suite=${{ matrix.suite }} + + - name: Build ogccite/geoserver:${{ matrix.suite }} docker image + working-directory: build/cite + run: make build-geoserver-image suite=${{ matrix.suite }} + + - name: Build the ETS docker image + working-directory: build/cite + run: make build-ets-image suite=${{ matrix.suite }} + + # optional, used to print out a human readable summary of test failures from the testng results xml + - name: Install the optional xmlstarlet utility + run: | + sudo apt-get update && sudo apt-get install -y xmlstarlet + + - name: Run the ${{ matrix.suite }} CITE test suite + working-directory: build/cite + run: | + chmod o+w logs + make test suite=${{ matrix.suite }} + + - name: Print full failures report + if: always() + working-directory: build/cite + run: make print-full-failures + + - name: Print GeoServer logs + if: always() + working-directory: build/cite + run: make print-logs suite=${{ matrix.suite }} service=geoserver + + - name: Print TeamEngine logs + if: always() + working-directory: build/cite + run: make print-logs suite=${{ matrix.suite }} service=teamengine + + - name: Shutdown containers + if: always() + working-directory: build/cite + run: make stop + + - name: Upload logs folder + if: always() + uses: actions/upload-artifact@v3 + with: + name: cite-${{ matrix.suite }}-logs + path: build/cite/logs/ diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 980b53f73e3..a99ec3623a7 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -6,6 +6,10 @@ on: - doc/** - src/pom.xml +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + env: MAVEN_OPTS: -Xmx1024m -Dmaven.wagon.httpconnectionManager.ttlSeconds=25 -Dmaven.wagon.http.retryHandler.count=3 -Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dspotless.apply.skip=true diff --git a/.github/workflows/javadoc.yml b/.github/workflows/javadoc.yml index fbbbdb22c18..ddec657d102 100644 --- a/.github/workflows/javadoc.yml +++ b/.github/workflows/javadoc.yml @@ -6,6 +6,10 @@ on: - '**/src/main/resources/GeoServerApplication_*.properties' - '!**/src/main/resources/GeoServerApplication_fr.properties' +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + env: MAVEN_OPTS: -Xmx1024m -Dmaven.wagon.httpconnectionManager.ttlSeconds=25 -Dmaven.wagon.http.retryHandler.count=3 -Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dspotless.apply.skip=true diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index a836bd104c3..0ca736e7ac6 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -6,6 +6,10 @@ on: - '**/src/main/resources/GeoServerApplication_*.properties' - '!**/src/main/resources/GeoServerApplication_fr.properties' +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + env: MAVEN_OPTS: -Xmx1024m -Dmaven.wagon.httpconnectionManager.ttlSeconds=25 -Dmaven.wagon.http.retryHandler.count=3 -Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dspotless.apply.skip=true diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index f53699cdef3..a8a58d0e1fe 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -6,6 +6,10 @@ on: - '**/src/main/resources/GeoServerApplication_*.properties' - '!**/src/main/resources/GeoServerApplication_fr.properties' +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + env: MAVEN_OPTS: -Xmx1024m -Dmaven.wagon.httpconnectionManager.ttlSeconds=25 -Dmaven.wagon.http.retryHandler.count=3 -Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dspotless.apply.skip=true diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index e4a1c98ba81..4b88d6801e5 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -2,6 +2,10 @@ name: QA GitHub CI on: [pull_request] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + env: MAVEN_OPTS: -Xmx1024m -Dmaven.wagon.httpconnectionManager.ttlSeconds=25 -Dmaven.wagon.http.retryHandler.count=3 -Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn @@ -37,7 +41,7 @@ jobs: run: | find ~/.m2/repository -name "*SNAPSHOT*" -type d | xargs rm -rf {} - - uses: lcollins/pmd-github-action@v3.0.0 - if: always() - with: - path: '**/pmd.xml' +# - uses: lcollins/pmd-github-action@v3.0.0 +# if: always() +# with: +# path: '**/pmd.xml' diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 45e756b60b3..6c445b0a344 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -6,6 +6,10 @@ on: - '**/src/main/resources/GeoServerApplication_*.properties' - '!**/src/main/resources/GeoServerApplication_fr.properties' +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + env: MAVEN_OPTS: -Xmx1024m -Dmaven.wagon.httpconnectionManager.ttlSeconds=25 -Dmaven.wagon.http.retryHandler.count=3 -Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dspotless.apply.skip=true diff --git a/build/cite/Makefile b/build/cite/Makefile index 0c8dddebffb..e1dc6966aba 100644 --- a/build/cite/Makefile +++ b/build/cite/Makefile @@ -7,34 +7,322 @@ .DEFAULT_GOAL := help .PHONY = help suite = -war_url = "https://build.geoserver.org/geoserver/main/geoserver-main-latest-war.zip" +# `make war` will build the war from ../src/web/app and copy it here +war_url = ./geoserver/geoserver.war +# alternatively you can use one in .war or .zip format from an URL, for example: +# war_url = "https://build.geoserver.org/geoserver/main/geoserver-main-latest-war.zip" +# but it may not have all the required extensions so make sure you know what you're doing + +.PHONY: help help: - @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//' + @echo Usage: + @echo + @echo \# Main targets in suggested order: + @echo + @grep -h '\s##\s' $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//' + @echo + @echo \# Additional helper targets: + @echo + @grep -h '\s###\s' $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/###//' -clean: ## Will Clean the Environment of previous runs. - @echo Cleaning up previous runs - docker-compose down --remove-orphans --rmi all -v - docker-compose rm -vfs +.PHONY: war +war: ## Build the geoserver.war file to use for testing and place it in ./geoserver/geoserver.war + @$(MAKE) build-war + @$(MAKE) copy-war + +# calls build-ets-image and build-geoserver-image +# the CI job may call them independently for the sake of using separate job steps +.PHONY: build +build: ## suite= Build the GeoServer Docker Image for the Environment. +ifndef suite + @echo "Error: suite is not specified. Please specify the suite to build the GeoServer Docker image for." + @$(MAKE) help + @exit 1 +endif + @$(MAKE) build-ets-image + @$(MAKE) build-geoserver-image + +# preparing the geoserver image is performed with docker-compose build including $suite/compose-override.yml +.PHONY: build-geoserver-image +build-geoserver-image: +ifndef suite + @echo "Error: suite is not specified. Please specify the suite to build the GeoServer Docker image for." + @exit 1 +endif + @echo Building the GeoServer Docker Image for the $(suite) test suite + @docker compose -f compose.yml -f ./$(suite)/compose.override.yml \ + build --no-cache --build-arg SOURCE_FILE=${war_url} geoserver + +# If there's a $suite/build-ets.sh file calls it, otherwise exists silently +.PHONY: build-ets-image +build-ets-image: +ifndef suite + @echo "Error: suite is not specified. Please specify the suite to build the GeoServer Docker image for." + @exit 1 +endif + @if [ -f "$(suite)/build-ets.sh" ]; then \ + (cd $(suite) && ./build-ets.sh); \ + else \ + echo "$(suite) has no special script to build the ETS docker image."; \ + fi + +.PHONY: test +test: ## suite= Run the Test Suite with teamengine and GeoServer on docker compose. +ifndef suite + @echo "Error: suite is not specified. Please specify a suite to run the tests." + @$(MAKE) help + @exit 1 +endif +ifeq ($(suite), ogcapi-features10) + @$(MAKE) test-rest suite=$(suite) +else + @$(MAKE) test-cli suite=$(suite) +endif + + +.PHONY: clean +clean: ## Clean the Environment of previous runs. + @$(MAKE) stop + @$(MAKE) cleanlogs + + +.PHONY: test-localhost +test-localhost: ### suite= Run the Test Suite against a local host GeoServer instance +ifndef suite + @echo "Error: suite is not specified. Please specify a suite to run the tests." + @$(MAKE) help + @exit 1 +endif +# for the time being the only suite run through teamengine's rest api is ogcapi-features10 +ifneq ($(suite), ogcapi-features10) + @echo "Error: This target only supports the 'ogcapi-features10' suite." + @exit 1 +endif + @if [ "$(shell uname)" = "Darwin" ]; then \ + echo "Detected a MacOS host Operating System. Using host.docker.internal as the host name"; \ + iut="http://host.docker.internal:8080/geoserver/ogc/features/v1"; \ + else \ + echo "Detected a Linux host Operating System. Using 172.17.0.1 as the host IP address"; \ + iut="http://172.17.0.1:8080/geoserver/ogc/features/v1"; \ + fi; \ + $(MAKE) test-external suite=$(suite) iut=$$iut + +# This target runs the specified test suite against a GeoServer instance provided by the iut parameter. +# It performs the following actions: +# 1. Checks if the required 'suite' and 'iut' parameters are provided, displaying an error and help message if not. +# 2. Validates the 'iut' parameter based on the operating system: +# - On MacOS, it prints an error and exits if 'iut' contains '172.17.0.1'. +# - On Linux, it prints an error and exits if 'iut' contains 'host.docker.internal'. +# 3. Runs either 'test-rest' or 'test-cli' based on the specified suite. +.PHONY: test-external +test-external: ### suite= iut= Run the Test Suite against a GeoServer instance at a provided URL +ifndef suite + @echo "Error: suite is not specified. Please specify a suite to run the tests." + @$(MAKE) help + @exit 1 +endif +ifndef iut + @echo "** Error: iut is not specified. Specify the iut URL. e.g., make test-external suite=ogcapi-features10 iut=http://test.example.com/geoserver/ogc/features/v1" + @$(MAKE) help + @exit 1 +endif + @if [ "$(shell uname)" = "Darwin" ] && echo "$(iut)" | grep -q "172.17.0.1"; then \ + echo "Error: Using '172.17.0.1' as the iut value is not supported on MacOS. Please use 'host.docker.internal'."; \ + exit 1; \ + fi + @if [ "$(shell uname)" = "Linux" ] && echo "$(iut)" | grep -q "host.docker.internal"; then \ + echo "Error: Using 'host.docker.internal' as the iut value is not supported on Linux. Please use '172.17.0.1'."; \ + exit 1; \ + fi +ifeq ($(suite), ogcapi-features10) + @echo "Running REST-based tests for suite: $(suite) with iut: $(iut)" + @$(MAKE) test-rest suite=$(suite) iut=$(iut) +else + @echo "Running CLI-based tests for suite: $(suite)" + @$(MAKE) test-cli suite=$(suite) +endif + + +.PHONY: version +version: ### suite= Print the version of the GeoServer on the current docker. +ifndef suite + @echo "Error: suite is not specified. Please specify the suite print the version for." + @$(MAKE) help + @exit 1 +endif + @echo Getting the GeoServer version. + @docker run -i --rm ogccite/geoserver:$(suite) bash -c \ + 'cd /usr/local/tomcat/webapps/ && \ + if [ -d geoserver ]; then cat geoserver/META-INF/MANIFEST.MF; \ + elif [ -f geoserver.war ]; then jar -xf geoserver.war; cat META-INF/MANIFEST.MF; \ + fi' + + +.PHONY: ogcapi-features10-localhost +ogcapi-features10-localhost: ### Shortcut for make test-localhost suite=ogcapi-features10 + @$(MAKE) test-localhost suite=ogcapi-features10 + + +.PHONY: cleanlogs +cleanlogs: @echo Cleanning the previous logs. - rm -Rf logs/* + @rm -Rf logs/* -build: $(suite) ## Will Build the GeoServer Docker Image for the Environment. - @echo Build the GeoServer Docker Image - docker-compose -f docker-compose.yml -f ./$(suite)/docker-compose.override.yml \ - build --build-arg GEOSERVER_WEBAPP_SRC=${war_url} geoserver -version: $(suite) ## Will give the version of the GeoServer on the current docker. - @echo Getting the GeoServer version. - docker run -i ogccite/geoserver:$(suite) bash -c 'cd /usr/local/tomcat/webapps/ && if [ -f geoserver.war ]; then unzip -q geoserver.war; cat META-INF/MANIFEST.MF; else cat META-INF/MANIFEST.MF; fi' +.PHONY: test-cli +test-cli: $(suite) + @echo Running the $(suite) test suite with teamengine CLI + @docker compose -f compose.yml -f ./$(suite)/compose.override.yml \ + up --force-recreate --exit-code-from teamengine teamengine -test: $(suite) | version ## Will running the Suite test with teamengine. - @echo running the Suite test with teamengine - docker-compose -f docker-compose.yml -f ./$(suite)/docker-compose.override.yml \ - up --force-recreate --exit-code-from teamengine teamengine +.PHONY: test-rest +test-rest: $(suite) +ifdef iut + @echo "Running the $(suite) test suite with the teamengine REST API against $(iut)" + @$(MAKE) start suite=$(suite) services=teamengine + @$(MAKE) run suite=$(suite) iut=$(iut) +else + @echo "Running the $(suite) test suite with the teamengine REST API" + @$(MAKE) start suite=$(suite) + @$(MAKE) run suite=$(suite) +endif + @$(MAKE) validate-testng-results -webUI: ## Will running the Suite test with teamengine. +# Starts service containers +# Usage: make start suite= [services=] +# : if not given, starts all the services in the docker composition for , +# otherwise just the specified ones (e.g. make start suite=ogcapi-features10 services=teamengine) +.PHONY: start +start: ### suite= [services=] Start the docker composition for suite. Optionally limit which services. +ifndef suite + @echo "Error: suite is not specified. Please specify a suite to start the containers." + @echo "Usage: make start suite= [services=]" + @exit 1 +endif + @echo Starting containers + @if [ -n "$(services)" ]; then \ + echo "Starting services: $(services)"; \ + docker compose -f compose.yml -f ./$(suite)/compose.override.yml \ + up -d --force-recreate --no-deps $(services); \ + else \ + docker compose -f compose.yml -f ./$(suite)/compose.override.yml \ + up -d --force-recreate; \ + fi + +.PHONY: stop +stop: ### Shuts down the docker composition. Deos not remove logs/ + @echo Cleaning up previous runs + @docker compose down --remove-orphans -v + @docker compose rm -vfs + + +.PHONY: run +run: $(suite) +ifndef iut + @$(MAKE) wait-for url="http://localhost:18090/geoserver/web/wicket/resource/org.geoserver.web.GeoServerBasePage/img/logo.png" timeout=60 +endif + @$(MAKE) wait-for url="http://localhost:18080/teamengine/site/logo.png" timeout=60 + @docker compose -f compose.yml -f ./$(suite)/compose.override.yml \ + exec teamengine /bin/bash -c "/run-test.sh $(suite) $(iut)" + + +# first prints out a human readable report of test failures, if xmlstarlet is installed, +# and then a summary of passed and failed test counts. This last step will result in a +# non zero exit code if there are test failures. +.PHONY: validate-testng-results +validate-testng-results: $(suite) + @./testng-results-report.sh logs/testng-results.xml + @./testng-results-validate.sh logs/testng-results.xml + + +.PHONY: print-full-failures +print-full-failures: + @if [ -f "logs/testng-results.xml" ]; then \ + ./testng-results-full-error-report.sh logs/testng-results.xml; \ + else \ + echo "The file logs/testng-results.xml does not exist. Skipping the report generation."; \ + fi + +.PHONY: pull +pull: $(suite) + @echo starting containers + @docker compose -f compose.yml -f ./$(suite)/compose.override.yml \ + pull --ignore-buildable + +.PHONY: build-war +build-war: + @mvn -Pogcapi-features \ + clean package -f ../../src/pom.xml \ + -DskipTests -B -ntp -U -T1C -fae -pl :gs-web-app -am + +.PHONY: copy-war +copy-war: + cp ../../src/web/app/target/geoserver.war geoserver/geoserver.war + +# Waits for an url to be available (returning HTTP status code 200 or 302) +# Usage: make wait-for url= timeout= +.PHONY: wait-for +wait-for: + @if [ -z "$(url)" ]; then \ + echo "Error: url parameter is required. Usage: make wait-for url= timeout="; \ + exit 1; \ + fi + @if [ -z "$(timeout)" ]; then \ + echo "Error: timeout parameter is required. Usage: make wait-for url= timeout="; \ + exit 1; \ + fi + @echo "Waiting for $(url) to be available (timeout: $(timeout) seconds)..." + @start_time=$$(date +%s); \ + while true; do \ + elapsed_time=$$(( $$(date +%s) - $$start_time )); \ + if [ $$elapsed_time -ge $(timeout) ]; then \ + echo "Timeout reached: $(url) is not available after $(timeout) seconds"; \ + exit 1; \ + fi; \ + if curl -s -o /dev/null -w "%{http_code}" $(url) | grep -E "^(200|302)$$" > /dev/null; then \ + echo "$(url) is available!"; \ + break; \ + fi; \ + echo "Waiting for $(url)..."; \ + sleep 5; \ + done + +# Prints logs for the specified suite and optionally a specific service. +# Usage: +# make print-logs suite= [service=] +# If 'service' is not specified, logs for all services in the suite will be shown. +.PHONY: print-logs +print-logs: + @if [ -z "$(suite)" ]; then \ + echo "Error: suite variable must be provided. Usage: make print-logs suite= [service=]"; \ + exit 1; \ + fi + @if [ -n "$(service)" ]; then \ + docker compose -f compose.yml -f ./$(suite)/compose.override.yml logs $(service); \ + else \ + docker compose -f compose.yml -f ./$(suite)/compose.override.yml logs; \ + fi + +# Used in CI/CD to print which services and images are going to be run +# Requires `jq`, comes pre-installed in github actions `ubuntu-latest` +.PHONY: print-services +print-services: ### suite= Print the service names and docker images used for a given suite +ifndef suite + @echo "Error: suite is not specified." + @exit 1 +endif + @if ! command -v jq &> /dev/null; then \ + echo "jq is not installed. Please install jq to use this command."; \ + else \ + echo Services used in the $(suite) test suite:; \ + docker compose -f compose.yml -f $(suite)/compose.override.yml config --format=json | jq -r '.services | to_entries | map("\t\(.key):\n \t\timage: \(.value.image)")[]'; \ + fi + +.PHONY: webUI +webUI: ### Start teamengine in interactive mode for the OWS services (excludes ogcapi services). @echo running the Suite test with teamengine webUI - docker-compose -f docker-compose.yml -f ./interactive/docker-compose.override.yml \ - up --force-recreate --no-deps --exit-code-from teamengine teamengine + @docker compose -f compose.yml -f ./interactive/compose.override.yml \ + up --force-recreate --no-deps --exit-code-from teamengine teamengine + diff --git a/build/cite/README.md b/build/cite/README.md index e98ff969d28..dbdf1695083 100644 --- a/build/cite/README.md +++ b/build/cite/README.md @@ -6,27 +6,33 @@ With the `Makefile` you can automate the tests with just a command. make # will show you the help and the commands. ``` * To run clean the ENV. ex: + ```shell make clean suite= ``` * To build the geoserver image. + ```shell make build suite= ``` * To test the suite. + ```shell make test suite= ``` + * To run all the steps from the beginning. + ```shell make clean build test suite= ``` -*Note*: shall match the name of the subdirectory of the suite. - examples below. + +> Note: shall match the name of the subdirectory of the suite. examples below. ### example: Run the `wms11` suite: + ``` make clean build test suite=wms11 ``` diff --git a/build/cite/compose.yml b/build/cite/compose.yml new file mode 100644 index 00000000000..197ca4184a8 --- /dev/null +++ b/build/cite/compose.yml @@ -0,0 +1,43 @@ +volumes: + gs_logs: + gs_gwc_cache_dir: + +services: + geoserver: + image: ogccite/geoserver:${GEOSERVER_TAG:-latest} + build: + context: . + dockerfile: ./geoserver/Dockerfile + args: + SOURCE_FILE: "https://build.geoserver.org/geoserver/main/geoserver-main-latest-war.zip" + # override as appropriate (e.g. ./wfs11/citewfs-1.1) + GEOSERVER_DATA_DIR_SRC: + ports: + - 18090:8080 + env_file: + - ./.env + - ./geoserver/geoserver.env + environment: + JAVA_OPTS: >- + -Xms${HEAP_SIZE_MIN:-1024m} + -Xmx${HEAP_SIZE_MAX:-1024m} + volumes: + - gs_logs:/opt/geoserver_data/logs:rw + - gs_gwc_cache_dir:/opt/geowebcache_data:rw + + teamengine: + # see https://github.com/opengeospatial/teamengine-docker + # there's ogccite/teamengine-production and ogccite/teamengine-beta + image: geoserver-docker.osgeo.org/geoserver-cite:${TEAMENGINE_TAG:-teamengine_latest} + hostname: teamengine.local + ports: + - 18080:8080 + depends_on: + - geoserver + volumes: + - ./logs:/logs:rw + # old teamengine location + - ./logs:/home/teamengine/te_base/users/teamengine:rw + # location used by new teamengine running tests through REST API + - ./logs:/usr/local/tomcat/te_base/users/ogctest/rest:rw + - ./run-test.sh:/run-test.sh diff --git a/build/cite/docker-compose.yml b/build/cite/docker-compose.yml deleted file mode 100644 index 3c1d686d18d..00000000000 --- a/build/cite/docker-compose.yml +++ /dev/null @@ -1,37 +0,0 @@ -version: '3.0' - -services: - geoserver: - image: ogccite/geoserver:${GEOSERVER_TAG:-latest} - build: - context: . - dockerfile: ./geoserver/Dockerfile - args: - GEOSERVER_WEBAPP_SRC: "https://build.geoserver.org/geoserver/main/geoserver-main-latest-war.zip" - ports: - - 8080 - env_file: - - ./.env - - ./geoserver/geoserver.env - environment: - JAVA_OPTS: >- - -Xms${HEAP_SIZE_MIN:-1024m} - -Xmx${HEAP_SIZE_MAX:-1024m} - volumes: - - gs_logs:/var/geoserver/logs:rw - - gs_gwc_cache_dir:/var/geoserver/gwc_cache_dir:rw - - teamengine: - image: geoserver-docker.osgeo.org/geoserver-cite:${TEAMENGINE_TAG:-teamengine_latest} - ports: - - 8080 - depends_on: - - geoserver - volumes: - - ./logs:/home/teamengine/te_base/users/teamengine - - ./run-test.sh:/run-test.sh - -volumes: - gs_datadir: - gs_logs: - gs_gwc_cache_dir: diff --git a/build/cite/geoserver/.gitignore b/build/cite/geoserver/.gitignore new file mode 100644 index 00000000000..bf4f0f99960 --- /dev/null +++ b/build/cite/geoserver/.gitignore @@ -0,0 +1 @@ +geoserver.war diff --git a/build/cite/geoserver/.placeholder b/build/cite/geoserver/.placeholder deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/build/cite/geoserver/Dockerfile b/build/cite/geoserver/Dockerfile index 55e796a43e6..4de4f73cf6c 100644 --- a/build/cite/geoserver/Dockerfile +++ b/build/cite/geoserver/Dockerfile @@ -1,54 +1,67 @@ -FROM tomcat:9-jdk11 -LABEL maintainer="Alessandro Parma" +FROM tomcat:9.0.96-jdk17-temurin-jammy -ENV DEBIAN_FRONTEND noninteractive +# Set environment variables for Java and GeoServer options +ENV EXTRA_JAVA_OPTS="-Xms256m -Xmx1g" +ENV GEOSERVER_DATA_DIR=/opt/geoserver_data +ENV GEOWEBCACHE_CACHE_DIR=/opt/geowebcache_data -ENV CATALINA_BASE "$CATALINA_HOME" +# Define GeoServer-related options +ENV CATALINA_OPTS="$EXTRA_JAVA_OPTS \ + --add-exports=java.desktop/sun.awt.image=ALL-UNNAMED \ + --add-opens=java.base/java.lang=ALL-UNNAMED \ + --add-opens=java.base/java.util=ALL-UNNAMED \ + --add-opens=java.base/java.lang.reflect=ALL-UNNAMED \ + --add-opens=java.base/java.text=ALL-UNNAMED \ + --add-opens=java.desktop/java.awt.font=ALL-UNNAMED \ + --add-opens=java.desktop/sun.awt.image=ALL-UNNAMED \ + --add-opens=java.naming/com.sun.jndi.ldap=ALL-UNNAMED \ + --add-opens=java.desktop/sun.java2d.pipe=ALL-UNNAMED \ + -Djava.awt.headless=true -server \ + -Dfile.encoding=UTF-8 \ + -Djavax.servlet.request.encoding=UTF-8 \ + -Djavax.servlet.response.encoding=UTF-8 \ + -D-XX:SoftRefLRUPolicyMSPerMB=36000 \ + -Xbootclasspath/a:$CATALINA_HOME/lib/marlin.jar \ + -Dsun.java2d.renderer=sun.java2d.marlin.DMarlinRenderingEngine \ + -Dorg.geotools.coverage.jaiext.enabled=true" -ENV GEOSERVER_HOME="/var/geoserver" -ENV GEOSERVER_LOG_DIR="${GEOSERVER_HOME}/logs" -ENV GEOSERVER_DATA_DIR="${GEOSERVER_HOME}/datadir" -ENV \ - GEOSERVER_LOG_LOCATION="${GEOSERVER_LOG_DIR}/geoserver.log" \ - GEOWEBCACHE_CONFIG_DIR="${GEOSERVER_DATA_DIR}/gwc" \ - GEOWEBCACHE_CACHE_DIR="${GEOSERVER_HOME}/gwc_cache_dir" +# Create a non-root user and group for running Tomcat +RUN groupadd -r tomcat && useradd -r -g tomcat -d /usr/local/tomcat -s /sbin/nologin tomcat -RUN mkdir -p \ - "${GEOSERVER_DATA_DIR}" \ - "${GEOSERVER_LOG_DIR}" \ - "${GEOWEBCACHE_CACHE_DIR}" \ - "${GEOWEBCACHE_CONFIG_DIR}" - -# override at run time as needed JAVA_OPTS -ENV JAVA_OPTS="-Xms1024m -Xmx1024m" - -# Optionally remove Tomcat manager, docs, and examples -ARG TOMCAT_EXTRAS=false -ENV TOMCAT_EXTRAS "$TOMCAT_EXTRAS" -RUN \ - if [ "$TOMCAT_EXTRAS" = false ]; then \ - rm -rfv "${CATALINA_HOME}/webapps/*" \ - ; fi +# Expose Tomcat's default port +EXPOSE 8080 -# local dir, tar or remore URLs -ARG GEOSERVER_DATA_DIR_SRC="./.placeholder" -ENV GEOSERVER_DATA_DIR_SRC="${GEOSERVER_DATA_DIR_SRC}" -ADD "${GEOSERVER_DATA_DIR_SRC}" "${GEOSERVER_DATA_DIR}" +# Define arguments for source file and data directory source +ARG SOURCE_FILE +ARG GEOSERVER_DATA_DIR_SRC -# accepts local files and URLs. Tar(s) are automatically extracted -ARG GEOSERVER_WEBAPP_SRC="./.placeholder" -ENV GEOSERVER_WEBAPP_SRC="${GEOSERVER_WEBAPP_SRC}" -ADD "${GEOSERVER_WEBAPP_SRC}" "${CATALINA_BASE}/webapps/" +# Download or copy the GeoServer WAR or ZIP file, or extract if it’s a .zip +ADD ${SOURCE_FILE} "$CATALINA_HOME/webapps/" # zip files require explicit extracion RUN \ - cd "${CATALINA_BASE}/webapps/"; \ - if [ "${GEOSERVER_WEBAPP_SRC##*.}" = "zip" ]; then \ + cd "$CATALINA_HOME/webapps/"; \ + if [ "${SOURCE_FILE##*.}" = "zip" ]; then \ unzip "./*zip"; \ - rm ./*zip; \ - fi + fi; -WORKDIR "$CATALINA_BASE" +# Copy the GeoServer data directory from the specified location +ADD ${GEOSERVER_DATA_DIR_SRC} ${GEOSERVER_DATA_DIR} -ENV TERM xterm -EXPOSE 8080 +# Set ownership and permissions for Tomcat and GeoServer data directories +RUN chown -R tomcat:tomcat /usr/local/tomcat \ + && mkdir -p $GEOSERVER_DATA_DIR \ + && chown -R tomcat:tomcat $GEOSERVER_DATA_DIR \ + && mkdir -p $GEOWEBCACHE_CACHE_DIR \ + && chown -R tomcat:tomcat $GEOWEBCACHE_CACHE_DIR + +# Switch to the unprivileged user +USER tomcat +WORKDIR "$CATALINA_HOME" + +# Define health check for GeoServer +HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \ + CMD curl -f http://localhost:8080/geoserver/web/wicket/resource/org.geoserver.web.GeoServerBasePage/img/logo.png || exit 1 + +# Start Tomcat as the unprivileged user +CMD ["catalina.sh", "run"] \ No newline at end of file diff --git a/build/cite/interactive/docker-compose.override.yml b/build/cite/interactive/compose.override.yml similarity index 97% rename from build/cite/interactive/docker-compose.override.yml rename to build/cite/interactive/compose.override.yml index 903b34e572f..79584f0e0a2 100644 --- a/build/cite/interactive/docker-compose.override.yml +++ b/build/cite/interactive/compose.override.yml @@ -1,5 +1,3 @@ -version: '3.0' - services: teamengine: ports: diff --git a/build/cite/ogcapi-features10/.gitignore b/build/cite/ogcapi-features10/.gitignore new file mode 100644 index 00000000000..00aec50086b --- /dev/null +++ b/build/cite/ogcapi-features10/.gitignore @@ -0,0 +1 @@ +ets-ogcapi-features10 diff --git a/build/cite/ogcapi-features10/README.md b/build/cite/ogcapi-features10/README.md new file mode 100644 index 00000000000..6855afa2881 --- /dev/null +++ b/build/cite/ogcapi-features10/README.md @@ -0,0 +1,159 @@ +# OGC API Features - Conformance Test Suite execution + +These are the instructions on how to run the CITE Conformance Test Suite for the +*GeoServer* OGC API Features service. + +## Goals + +* To run them manually on demand in your local machine +* To run them while you're debugging GeoServer in your IDE +* To run them in an automated CI/CD pipeline (Github actions workflow), and to upload the reports somewhere + +## Requirements + +* A *GeoServer* instance with the `ogcapi-features` extension +* A data set to run the conformance tests against + +## Test Data: + +The datasets included for the default test runs are the vector layers from +the GeoServer *release** data directory. + +### Limited CRS list advertised per FeatureType + +Each `FeatureType` to be tested must have a limited set of advertised CRS's where for which +coordinate reprojection is expected to work. Otherwise the CRS tests will be executed +against all of them. + +For example, querying a collection: + +```json +... + "crs": [ + "http://www.opengis.net/def/crs/OGC/1.3/CRS84", + "http://www.opengis.net/def/crs/EPSG/0/4326", + "http://www.opengis.net/def/crs/EPSG/0/3857" + ], + ... +``` + +as opposed to advertising all the CRS's available in GeoServer. + +In order to automate this, the `release` data directory is configured with `EPSG:4326` and `EPSG:3857` as the +advertised CRS's directly in the global `WFS` settings. + + +## Running + +For the most common case, you'll want to run the `ogcapi-features10` suite against a GeoServer instance from the local `.war` build. + +First, run + +```shell +make war +``` +to build the `geoserver.war` file from `src/web/app`, and + +``` +make build suite=ogcapi-features10 +``` + +To build the GeoServer Docker image that will be exercised. Then run: + +```shell +make test suite=ogcapi-features10 +``` + +These are the same steps the "Run CITE Tests" github actions workflow will follow. + +At the end of each test run, a human readable summary of test failures will be printed out, if any. + +Finally, shut down the docker composition and clean up the `logs/` folder with + +```shell +make clean +``` + + +## Test a local instance + +> ⚠️ **Achtung!**: +> +> In the following examples, some `make` targets receive an `iut` parameter with the URL of the OGC Features API landing page to test, +> external to the `teamengine`'s container network. By default, for **Linux** systems, use the 172.17.0.1 IP address. +> However, if you're running the tests on **MacOS**, replace it with the host.docker.internal hostname instead. +> This difference exists because on Linux, Docker creates a bridge network where the host is accessible via `172.17.0.1`. On MacOS, Docker Desktop for Mac +> runs containers within a virtualization layer, which changes the networking model. As a result, `host.docker.internal` is used to enable containers +> to access the host. + + +For development purposes you may want to run the `Start.java` GeoServer launcher from the `gs-web-app`'s test sources. + +In order to reproduce the Github action CITE tests results, you'll have use the the data directory at `./release` (e.g. make a copy of +the release directory and set the `GEOSERVER_DATA_DIR` environment variable accordingly). + +To hit that instance, if it's running at `localhost:8080`, you can simply run. + + +```shell +make ogcapi-features10-localhost +``` + +Otherwise, you can further customize the target GeoServer URL, port, and virtual service: + +```shell +make test-external suite=ogcapi-features10 iut="http://172.17.0.1:9090/geoserver/sf/archsites/ogc/features/v1" +``` + +The `iut` parameter refers to the *Instance Under Test* and is the URL for the Landing Page document. + +> **Note** +> +> Since `teamengine` is running inside a Docker container, the special IP address `172.17.0.1` +> can be used to reach out to the host as long as the container is running on the default +> Docker bridge network, which is the case in this docker composition. + +Finally, shut down the docker composition and clean up the `logs/` folder with + +```shell +make clean +``` + +### Use TeamEngine interactively + +In some cases it's useful to log in to the TeamEngine and run tests manually. + +You can check which services a given test suite is comprised of with the `make print-services` command: + +```shell +make print-services suite=ogcapi-features10 +Services used in the ogcapi-features10 test suite: + geoserver: + image: ogccite/geoserver:ogcapi-features10 + teamengine: + image: ogccite/ets-ogcapi-features10:1.7.1-teamengine-5.4.1 +``` + +In this case you can simply run the `teamengine` service with: + +```shell +make start suite=ogcapi-features10 services=teamengine +``` + +Check the service is running: + +```shell +docker compose ps +NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS +cite-teamengine-1 ogccite/ets-ogcapi-features10:1.7.1-teamengine-5.4.1 "catalina.sh jpda run" teamengine 11 seconds ago Up 11 seconds (healthy) 0.0.0.0:18080->8080/tcp +``` + +Then open [http://localhost:18080/teamengine/](http://localhost:18080/teamengine/) in your browser, sign in with +username and password `ogctest`, and start a new test session. + + +Once done, shut down the docker composition and clean up the `logs/` folder with + +```shell +make clean +``` diff --git a/build/cite/ogcapi-features10/build-ets.sh b/build/cite/ogcapi-features10/build-ets.sh new file mode 100755 index 00000000000..788f8682be1 --- /dev/null +++ b/build/cite/ogcapi-features10/build-ets.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# build the ets-ogcapi-features10 Docker image from the +# (at the time of writing, ogccite/ets-ogcapi-features10:1.8-SNAPSHOT-teamengine-5.4.1) +# from the geoserver's fork `geoserver/integration` branch, which applies +# patches to the ets that have not yet being released upstream + +echo "Building the ogccite/ets-ogcapi-features10 docker image from the geoserver/integration branch" +rm -rf ets-ogcapi-features10 +git clone https://github.com/geoserver/ets-ogcapi-features10.git +cd ets-ogcapi-features10 +git checkout geoserver/integration && mvn clean install -Pdocker -DskipTests -ntp +cd .. diff --git a/build/cite/ogcapi-features10/compose.override.yml b/build/cite/ogcapi-features10/compose.override.yml new file mode 100644 index 00000000000..4ae3e5e3792 --- /dev/null +++ b/build/cite/ogcapi-features10/compose.override.yml @@ -0,0 +1,22 @@ + +#name: ogcapi-features-conformance + +services: + geoserver: + image: ogccite/geoserver:ogcapi-features10 + build: + args: + GEOSERVER_DATA_DIR_SRC: "./ogcapi-features10/release" + + teamengine: + # see https://github.com/opengeospatial/teamengine-docker + # there's ogccite/teamengine-production and ogccite/teamengine-beta + # that we could use to migrate the other OWS tests to newer teamengine images + # image: ogccite/ets-ogcapi-features10:1.7.1-teamengine-5.4.1 + image: ogccite/ets-ogcapi-features10:1.8-SNAPSHOT-teamengine-5.4.1 + healthcheck: + test: "curl -f http://localhost:8080/teamengine/ || exit 1" + interval: 15s + timeout: 10s + retries: 10 + start_period: 5s diff --git a/build/cite/ogcapi-features10/release/README.md b/build/cite/ogcapi-features10/release/README.md new file mode 100644 index 00000000000..131fbc040bf --- /dev/null +++ b/build/cite/ogcapi-features10/release/README.md @@ -0,0 +1,7 @@ +This is an extract of the [release](../../../../data/release/) data directory +without the raster layers and their corresponding datasets, for the purpose +of executing the ogcapi-features-1.0 conformance test suite against this +well known datasets. + +Note although it adds the shapefiles and geopackage again, they won't incur +in any size overhead for the repository given the way git stores files. diff --git a/build/cite/ogcapi-features10/release/data/ne/natural_earth.gpkg b/build/cite/ogcapi-features10/release/data/ne/natural_earth.gpkg new file mode 100644 index 00000000000..1bbfb34c70d Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/ne/natural_earth.gpkg differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.dbf b/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.dbf new file mode 100644 index 00000000000..3db507ed59c Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.prj b/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.prj new file mode 100644 index 00000000000..7a70628b09a --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] diff --git a/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.qix b/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.qix new file mode 100644 index 00000000000..5206d774731 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.qix differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.shp b/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.shp new file mode 100644 index 00000000000..a1e629342ea Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.shp differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.shx b/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.shx new file mode 100644 index 00000000000..0d13fb9dba8 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/giant_polygon.shx differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/poi.dbf b/build/cite/ogcapi-features10/release/data/nyc/poi.dbf new file mode 100644 index 00000000000..cbe74643617 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/poi.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/poi.prj b/build/cite/ogcapi-features10/release/data/nyc/poi.prj new file mode 100644 index 00000000000..7a70628b09a --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/nyc/poi.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] diff --git a/build/cite/ogcapi-features10/release/data/nyc/poi.qix b/build/cite/ogcapi-features10/release/data/nyc/poi.qix new file mode 100644 index 00000000000..b5f406a948b Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/poi.qix differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/poi.shp b/build/cite/ogcapi-features10/release/data/nyc/poi.shp new file mode 100644 index 00000000000..3a64a82471f Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/poi.shp differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/poi.shx b/build/cite/ogcapi-features10/release/data/nyc/poi.shx new file mode 100644 index 00000000000..6d8ed519bf8 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/poi.shx differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.dbf b/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.dbf new file mode 100644 index 00000000000..dbfc4fe7359 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.prj b/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.prj new file mode 100644 index 00000000000..7a70628b09a --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] diff --git a/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.qix b/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.qix new file mode 100644 index 00000000000..5604a7fa5c4 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.qix differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.shp b/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.shp new file mode 100644 index 00000000000..41efbe8e036 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.shp differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.shx b/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.shx new file mode 100644 index 00000000000..fea12344df3 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/poly_landmarks.shx differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.dbf b/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.dbf new file mode 100644 index 00000000000..bf65cce5992 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.prj b/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.prj new file mode 100644 index 00000000000..7a70628b09a --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] diff --git a/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.qix b/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.qix new file mode 100644 index 00000000000..87134ce9958 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.qix differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.shp b/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.shp new file mode 100644 index 00000000000..92f899c7461 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.shp differ diff --git a/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.shx b/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.shx new file mode 100644 index 00000000000..ec6be4b7d73 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/nyc/tiger_roads.shx differ diff --git a/build/cite/ogcapi-features10/release/data/sf/archsites.dbf b/build/cite/ogcapi-features10/release/data/sf/archsites.dbf new file mode 100644 index 00000000000..93ff16099a9 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/archsites.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/sf/archsites.prj b/build/cite/ogcapi-features10/release/data/sf/archsites.prj new file mode 100644 index 00000000000..94024524a8e --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/sf/archsites.prj @@ -0,0 +1 @@ +PROJCS["NAD27 / UTM zone 13N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26713"]] \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/data/sf/archsites.shp b/build/cite/ogcapi-features10/release/data/sf/archsites.shp new file mode 100644 index 00000000000..2e2b5c5ce0a Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/archsites.shp differ diff --git a/build/cite/ogcapi-features10/release/data/sf/archsites.shx b/build/cite/ogcapi-features10/release/data/sf/archsites.shx new file mode 100644 index 00000000000..b19e73760d7 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/archsites.shx differ diff --git a/build/cite/ogcapi-features10/release/data/sf/bugsites.dbf b/build/cite/ogcapi-features10/release/data/sf/bugsites.dbf new file mode 100644 index 00000000000..c389493daaa Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/bugsites.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/sf/bugsites.prj b/build/cite/ogcapi-features10/release/data/sf/bugsites.prj new file mode 100644 index 00000000000..94024524a8e --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/sf/bugsites.prj @@ -0,0 +1 @@ +PROJCS["NAD27 / UTM zone 13N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26713"]] \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/data/sf/bugsites.shp b/build/cite/ogcapi-features10/release/data/sf/bugsites.shp new file mode 100644 index 00000000000..cd385cc9bb2 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/bugsites.shp differ diff --git a/build/cite/ogcapi-features10/release/data/sf/bugsites.shx b/build/cite/ogcapi-features10/release/data/sf/bugsites.shx new file mode 100644 index 00000000000..533de56715d Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/bugsites.shx differ diff --git a/build/cite/ogcapi-features10/release/data/sf/restricted.dbf b/build/cite/ogcapi-features10/release/data/sf/restricted.dbf new file mode 100644 index 00000000000..8820ce6f95f Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/restricted.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/sf/restricted.prj b/build/cite/ogcapi-features10/release/data/sf/restricted.prj new file mode 100644 index 00000000000..94024524a8e --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/sf/restricted.prj @@ -0,0 +1 @@ +PROJCS["NAD27 / UTM zone 13N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26713"]] \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/data/sf/restricted.shp b/build/cite/ogcapi-features10/release/data/sf/restricted.shp new file mode 100644 index 00000000000..cac5e5fe3f1 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/restricted.shp differ diff --git a/build/cite/ogcapi-features10/release/data/sf/restricted.shx b/build/cite/ogcapi-features10/release/data/sf/restricted.shx new file mode 100644 index 00000000000..f2b31bfd748 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/restricted.shx differ diff --git a/build/cite/ogcapi-features10/release/data/sf/roads.dbf b/build/cite/ogcapi-features10/release/data/sf/roads.dbf new file mode 100644 index 00000000000..650a51715cf Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/roads.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/sf/roads.prj b/build/cite/ogcapi-features10/release/data/sf/roads.prj new file mode 100644 index 00000000000..94024524a8e --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/sf/roads.prj @@ -0,0 +1 @@ +PROJCS["NAD27 / UTM zone 13N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26713"]] \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/data/sf/roads.shp b/build/cite/ogcapi-features10/release/data/sf/roads.shp new file mode 100644 index 00000000000..3cab93024fb Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/roads.shp differ diff --git a/build/cite/ogcapi-features10/release/data/sf/roads.shx b/build/cite/ogcapi-features10/release/data/sf/roads.shx new file mode 100644 index 00000000000..df470eb7157 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/roads.shx differ diff --git a/build/cite/ogcapi-features10/release/data/sf/sfdem.tif b/build/cite/ogcapi-features10/release/data/sf/sfdem.tif new file mode 100644 index 00000000000..54b5373c7c2 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/sfdem.tif differ diff --git a/build/cite/ogcapi-features10/release/data/sf/streams.dbf b/build/cite/ogcapi-features10/release/data/sf/streams.dbf new file mode 100644 index 00000000000..2bb3c53067e Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/streams.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/sf/streams.prj b/build/cite/ogcapi-features10/release/data/sf/streams.prj new file mode 100644 index 00000000000..94024524a8e --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/sf/streams.prj @@ -0,0 +1 @@ +PROJCS["NAD27 / UTM zone 13N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26713"]] \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/data/sf/streams.shp b/build/cite/ogcapi-features10/release/data/sf/streams.shp new file mode 100644 index 00000000000..411d0758f31 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/streams.shp differ diff --git a/build/cite/ogcapi-features10/release/data/sf/streams.shx b/build/cite/ogcapi-features10/release/data/sf/streams.shx new file mode 100644 index 00000000000..2784dfe301c Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/sf/streams.shx differ diff --git a/build/cite/ogcapi-features10/release/data/shapefiles/states.dbf b/build/cite/ogcapi-features10/release/data/shapefiles/states.dbf new file mode 100644 index 00000000000..45b725f8419 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/shapefiles/states.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/shapefiles/states.prj b/build/cite/ogcapi-features10/release/data/shapefiles/states.prj new file mode 100644 index 00000000000..7a70628b09a --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/shapefiles/states.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] diff --git a/build/cite/ogcapi-features10/release/data/shapefiles/states.qix b/build/cite/ogcapi-features10/release/data/shapefiles/states.qix new file mode 100644 index 00000000000..2f72281dabd Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/shapefiles/states.qix differ diff --git a/build/cite/ogcapi-features10/release/data/shapefiles/states.shp b/build/cite/ogcapi-features10/release/data/shapefiles/states.shp new file mode 100644 index 00000000000..40aa5edf5cb Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/shapefiles/states.shp differ diff --git a/build/cite/ogcapi-features10/release/data/shapefiles/states.shx b/build/cite/ogcapi-features10/release/data/shapefiles/states.shx new file mode 100644 index 00000000000..820c398e749 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/shapefiles/states.shx differ diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_cities.dbf b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_cities.dbf new file mode 100644 index 00000000000..008f5c92b72 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_cities.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_cities.prj b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_cities.prj new file mode 100644 index 00000000000..7a70628b09a --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_cities.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_cities.shp b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_cities.shp new file mode 100644 index 00000000000..74c28304d44 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_cities.shp differ diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_cities.shx b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_cities.shx new file mode 100644 index 00000000000..f3ccf7eccb2 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_cities.shx differ diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_roads.dbf b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_roads.dbf new file mode 100644 index 00000000000..bd10b00b7eb Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_roads.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_roads.prj b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_roads.prj new file mode 100644 index 00000000000..7a70628b09a --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_roads.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_roads.shp b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_roads.shp new file mode 100644 index 00000000000..aab18174bd5 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_roads.shp differ diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_roads.shx b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_roads.shx new file mode 100644 index 00000000000..1e90d04212d Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_roads.shx differ diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_state_boundaries.dbf b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_state_boundaries.dbf new file mode 100644 index 00000000000..b245a5e9dc6 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_state_boundaries.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_state_boundaries.prj b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_state_boundaries.prj new file mode 100644 index 00000000000..7a70628b09a --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_state_boundaries.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_state_boundaries.shp b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_state_boundaries.shp new file mode 100644 index 00000000000..85957fa133c Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_state_boundaries.shp differ diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_state_boundaries.shx b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_state_boundaries.shx new file mode 100644 index 00000000000..723490fe02b Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_state_boundaries.shx differ diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_water_bodies.dbf b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_water_bodies.dbf new file mode 100644 index 00000000000..558a3af00e6 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_water_bodies.dbf differ diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_water_bodies.prj b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_water_bodies.prj new file mode 100644 index 00000000000..7a70628b09a --- /dev/null +++ b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_water_bodies.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_water_bodies.shp b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_water_bodies.shp new file mode 100644 index 00000000000..e0f0fd112e2 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_water_bodies.shp differ diff --git a/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_water_bodies.shx b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_water_bodies.shx new file mode 100644 index 00000000000..8aac372c0a5 Binary files /dev/null and b/build/cite/ogcapi-features10/release/data/taz_shapes/tasmania_water_bodies.shx differ diff --git a/build/cite/ogcapi-features10/release/global.xml b/build/cite/ogcapi-features10/release/global.xml new file mode 100644 index 00000000000..0ec9e6609f0 --- /dev/null +++ b/build/cite/ogcapi-features10/release/global.xml @@ -0,0 +1,89 @@ + + + SettingsInfoImpl-68f6c583:154ca420c47:-8000 + + Alexandria + Roman Empire + Egypt + Work + claudius.ptolomaeus@mercury.olympus.gov + OSGeo + Claudius Ptolomaeus + Chief Geographer + https://www.osgeo.org/ + Designed for interoperability, GeoServer publishes data from any major spatial data source using open standards. + + UTF-8 + 7 + http://geoserver.org + false + false + + + + quietOnNotFound + false + + + + false + false + false + false + + + false + false + 5 + 7 + 0.5 + 0.75 + false + true + true + false + false + + + Affine + BandCombine + BandMerge + BandSelect + Binarize + Border + ColorConvert + Crop + ErrorDiffusion + Format + ImageFunction + Lookup + Mosaic + Null + OrderedDither + Rescale + Scale + Stats + Translate + Warp + algebric + operationConst + + + + + 10 + 5 + 30000 + UNBOUNDED + 10240 + + + false + + 326 + 0 + true + 1024 + false + DEFAULT + diff --git a/build/cite/ogcapi-features10/release/gwc-gs.xml b/build/cite/ogcapi-features10/release/gwc-gs.xml new file mode 100644 index 00000000000..eb74a3cfc9a --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-gs.xml @@ -0,0 +1,43 @@ + + 1.1.0 + false + true + true + true + false + false + true + class org.geowebcache.storage.blobstore.memory.guava.GuavaCacheProvider + + + class org.geowebcache.storage.blobstore.memory.guava.GuavaCacheProvider + + 16 + NULL + 4 + 120 + + + + true + true + 4 + 4 + 0 + + EPSG:4326 + EPSG:900913 + + + image/png + image/jpeg + + + image/png + image/jpeg + + + image/png + image/jpeg + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerGroupInfoImpl--570ae188_124761b8d78_-7fab.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerGroupInfoImpl--570ae188_124761b8d78_-7fab.xml new file mode 100644 index 00000000000..b4be41e453d --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerGroupInfoImpl--570ae188_124761b8d78_-7fab.xml @@ -0,0 +1,27 @@ + + LayerGroupInfoImpl--570ae188:124761b8d78:-7fab + true + true + spearfish + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerGroupInfoImpl--570ae188_124761b8d78_-7fac.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerGroupInfoImpl--570ae188_124761b8d78_-7fac.xml new file mode 100644 index 00000000000..8cbdbfd52b1 --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerGroupInfoImpl--570ae188_124761b8d78_-7fac.xml @@ -0,0 +1,27 @@ + + LayerGroupInfoImpl--570ae188:124761b8d78:-7fac + true + true + tasmania + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerGroupInfoImpl--570ae188_124761b8d78_-7fad.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerGroupInfoImpl--570ae188_124761b8d78_-7fad.xml new file mode 100644 index 00000000000..6becc1d69fc --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerGroupInfoImpl--570ae188_124761b8d78_-7fad.xml @@ -0,0 +1,27 @@ + + LayerGroupInfoImpl--570ae188:124761b8d78:-7fad + true + true + tiger-ny + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerGroupInfoImpl-1c443fee_182c0f3f209_-7ff4.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerGroupInfoImpl-1c443fee_182c0f3f209_-7ff4.xml new file mode 100644 index 00000000000..eb66611230f --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerGroupInfoImpl-1c443fee_182c0f3f209_-7ff4.xml @@ -0,0 +1,27 @@ + + LayerGroupInfoImpl-1c443fee:182c0f3f209:-7ff4 + true + true + ne:world + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fb8.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fb8.xml new file mode 100644 index 00000000000..9879fcca320 --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fb8.xml @@ -0,0 +1,34 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fb8 + true + true + topp:tasmania_water_bodies + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + cite_lakes + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fba.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fba.xml new file mode 100644 index 00000000000..bb0946049bb --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fba.xml @@ -0,0 +1,34 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fba + true + true + topp:tasmania_state_boundaries + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + green + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fbc.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fbc.xml new file mode 100644 index 00000000000..ecfcda3af8f --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fbc.xml @@ -0,0 +1,34 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fbc + true + true + topp:tasmania_roads + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + simple_roads + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fbe.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fbe.xml new file mode 100644 index 00000000000..46aaf8f80d5 --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fbe.xml @@ -0,0 +1,34 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fbe + true + true + topp:tasmania_cities + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + capitals + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc0.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc0.xml new file mode 100644 index 00000000000..1279d3d8d69 --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc0.xml @@ -0,0 +1,37 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fc0 + true + true + topp:states + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + polygon + pophatch + + population + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc2.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc2.xml new file mode 100644 index 00000000000..9cf6e2b1173 --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc2.xml @@ -0,0 +1,36 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fc2 + true + true + sf:streams + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + line + + simple_streams + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc4.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc4.xml new file mode 100644 index 00000000000..896d9bc2689 --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc4.xml @@ -0,0 +1,36 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fc4 + true + true + sf:roads + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + line + + simple_roads + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc6.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc6.xml new file mode 100644 index 00000000000..030464eda5f --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc6.xml @@ -0,0 +1,36 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fc6 + true + true + sf:restricted + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + polygon + + restricted + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc8.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc8.xml new file mode 100644 index 00000000000..08ef136232e --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fc8.xml @@ -0,0 +1,37 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fc8 + true + true + sf:bugsites + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + burg + point + + capitals + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fca.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fca.xml new file mode 100644 index 00000000000..84d3f9f0d21 --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fca.xml @@ -0,0 +1,37 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fca + true + true + sf:archsites + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + burg + capitals + + point + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fcc.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fcc.xml new file mode 100644 index 00000000000..196976e8c08 --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fcc.xml @@ -0,0 +1,37 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fcc + true + true + tiger:tiger_roads + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + line + simple_roads + + tiger_roads + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fce.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fce.xml new file mode 100644 index 00000000000..8a8cd7d1362 --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fce.xml @@ -0,0 +1,38 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fce + true + true + tiger:poly_landmarks + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + grass + polygon + restricted + + poly_landmarks + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fd0.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fd0.xml new file mode 100644 index 00000000000..1283a7627bc --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fd0.xml @@ -0,0 +1,37 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fd0 + true + true + tiger:poi + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + burg + point + + poi + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fd2.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fd2.xml new file mode 100644 index 00000000000..257fb8609ce --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--570ae188_124761b8d78_-7fd2.xml @@ -0,0 +1,34 @@ + + LayerInfoImpl--570ae188:124761b8d78:-7fd2 + true + true + tiger:giant_polygon + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + giant_polygon + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--72884701_185db6cdd61_-7ffe.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--72884701_185db6cdd61_-7ffe.xml new file mode 100644 index 00000000000..c1c1a686680 --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl--72884701_185db6cdd61_-7ffe.xml @@ -0,0 +1,34 @@ + + LayerInfoImpl--72884701:185db6cdd61:-7ffe + true + true + ne:disputed_areas + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + ne:disputed + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl-1c443fee_182c0f3f209_-7fef.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl-1c443fee_182c0f3f209_-7fef.xml new file mode 100644 index 00000000000..2c389ee6b7a --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl-1c443fee_182c0f3f209_-7fef.xml @@ -0,0 +1,36 @@ + + LayerInfoImpl-1c443fee:182c0f3f209:-7fef + true + true + ne:coastlines + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + line + + ne:coastline + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl-1c443fee_182c0f3f209_-7ff5.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl-1c443fee_182c0f3f209_-7ff5.xml new file mode 100644 index 00000000000..3cc02bdbd05 --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl-1c443fee_182c0f3f209_-7ff5.xml @@ -0,0 +1,36 @@ + + LayerInfoImpl-1c443fee:182c0f3f209:-7ff5 + true + true + ne:populated_places + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + point + + ne:populated_places + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl-1c443fee_182c0f3f209_-7ff7.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl-1c443fee_182c0f3f209_-7ff7.xml new file mode 100644 index 00000000000..f24aacca04e --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl-1c443fee_182c0f3f209_-7ff7.xml @@ -0,0 +1,36 @@ + + LayerInfoImpl-1c443fee:182c0f3f209:-7ff7 + true + true + ne:boundary_lines + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + line + + ne:boundary_lines + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl-1c443fee_182c0f3f209_-7ff9.xml b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl-1c443fee_182c0f3f209_-7ff9.xml new file mode 100644 index 00000000000..fa795cbe153 --- /dev/null +++ b/build/cite/ogcapi-features10/release/gwc-layers/LayerInfoImpl-1c443fee_182c0f3f209_-7ff9.xml @@ -0,0 +1,37 @@ + + LayerInfoImpl-1c443fee:182c0f3f209:-7ff9 + true + true + ne:countries + + image/png + image/jpeg + + + + EPSG:4326 + + + EPSG:900913 + + + + 4 + 4 + + 0 + 0 + + + STYLES + + + ne:countries + polygon + + ne:countries_mapcolor9 + + + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/layergroups/spearfish.xml b/build/cite/ogcapi-features10/release/layergroups/spearfish.xml new file mode 100644 index 00000000000..6b72d978c57 --- /dev/null +++ b/build/cite/ogcapi-features10/release/layergroups/spearfish.xml @@ -0,0 +1,44 @@ + + LayerGroupInfoImpl--570ae188:124761b8d78:-7fab + spearfish + SINGLE + Spearfish + Spearfish City in Lawrence County, South Dakota + +The area covered by the data set is in the vicinity of Spearfish and includes a majority of the Black Hills National Forest (i.e., Mount Rushmore). + + + LayerInfoImpl--570ae188:124761b8d78:-7fc2 + + + LayerInfoImpl--570ae188:124761b8d78:-7fc4 + + + LayerInfoImpl--570ae188:124761b8d78:-7fc6 + + + LayerInfoImpl--570ae188:124761b8d78:-7fca + + + LayerInfoImpl--570ae188:124761b8d78:-7fc8 + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/burg02.svg b/build/cite/ogcapi-features10/release/styles/burg02.svg new file mode 100644 index 00000000000..f7221483214 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/burg02.svg @@ -0,0 +1,22 @@ + + + + +]> + + + + + diff --git a/build/cite/ogcapi-features10/release/styles/capitals.sld b/build/cite/ogcapi-features10/release/styles/capitals.sld new file mode 100644 index 00000000000..ec5f329458b --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/capitals.sld @@ -0,0 +1,44 @@ + + + + capitals + + capitals + Capital cities + + + Capitals + + + + circle + + + #FFFFFF + + + + + #000000 + + + 2 + + + + + 1.0 + + + 6 + + + + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/capitals.xml b/build/cite/ogcapi-features10/release/styles/capitals.xml new file mode 100644 index 00000000000..af860786af0 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/capitals.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/cite_lakes.xml b/build/cite/ogcapi-features10/release/styles/cite_lakes.xml new file mode 100644 index 00000000000..c3fb4cf4f76 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/cite_lakes.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/default_generic.sld b/build/cite/ogcapi-features10/release/styles/default_generic.sld new file mode 100644 index 00000000000..734b336ba71 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/default_generic.sld @@ -0,0 +1,86 @@ + + + + generic + + Generic + Generic style + + + raster + Opaque Raster + + + + true + + + + 1.0 + + + + Polygon + Grey Polygon + + + + + + 2 + + + + + #AAAAAA + + + #000000 + 1 + + + + + Line + Blue Line + + + + + + 1 + + + + + #0000FF + 1 + + + + + point + Red Square Point + + + + + square + + #FF0000 + + + 6 + + + + first + + + + diff --git a/build/cite/ogcapi-features10/release/styles/default_line.sld b/build/cite/ogcapi-features10/release/styles/default_line.sld new file mode 100644 index 00000000000..f80d632db10 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/default_line.sld @@ -0,0 +1,32 @@ + + + + + default_line + + + Blue Line + A sample style that draws a line + + + + + rule1 + Blue Line + A solid blue line with a 1 pixel width + + + #0000FF + + + + + + + + diff --git a/build/cite/ogcapi-features10/release/styles/default_line2.sld b/build/cite/ogcapi-features10/release/styles/default_line2.sld new file mode 100644 index 00000000000..de59a9ea120 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/default_line2.sld @@ -0,0 +1,40 @@ + + + + + + Default Line + + + + Green line + A sample style that just prints out a green line + + + + + + + Rule 1 + Green Line + A green line with a 2 pixel width + + + + + #319738 + 2 + + + + + + + + + diff --git a/build/cite/ogcapi-features10/release/styles/default_point.sld b/build/cite/ogcapi-features10/release/styles/default_point.sld new file mode 100644 index 00000000000..b8ba3210fdd --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/default_point.sld @@ -0,0 +1,38 @@ + + + + + default_point + + + Red Square Point + A sample style that draws a red square point + + + + + rule1 + Red Square Point + A 6 pixel square with a red fill and no stroke + + + + square + + #FF0000 + + + 6 + + + + + + + + diff --git a/build/cite/ogcapi-features10/release/styles/default_polygon.sld b/build/cite/ogcapi-features10/release/styles/default_polygon.sld new file mode 100644 index 00000000000..531ef9fc84f --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/default_polygon.sld @@ -0,0 +1,35 @@ + + + + + default_polygon + + + Default Polygon + A sample style that draws a polygon + + + + + rule1 + Gray Polygon with Black Outline + A polygon with a gray fill and a 1 pixel black outline + + + #AAAAAA + + + #000000 + 1 + + + + + + + diff --git a/build/cite/ogcapi-features10/release/styles/dem.sld b/build/cite/ogcapi-features10/release/styles/dem.sld new file mode 100644 index 00000000000..9b61775e6dd --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/dem.sld @@ -0,0 +1,28 @@ + + + + gtopo + + dem + Simple DEM style + Classic elevation color progression + + + + 1.0 + + + + + + + + + + + + + + diff --git a/build/cite/ogcapi-features10/release/styles/dem.xml b/build/cite/ogcapi-features10/release/styles/dem.xml new file mode 100644 index 00000000000..95c22851d67 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/dem.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/generic.xml b/build/cite/ogcapi-features10/release/styles/generic.xml new file mode 100644 index 00000000000..838740f23ae --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/generic.xml @@ -0,0 +1,9 @@ + diff --git a/build/cite/ogcapi-features10/release/styles/giant_polygon.sld b/build/cite/ogcapi-features10/release/styles/giant_polygon.sld new file mode 100644 index 00000000000..8235f137f02 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/giant_polygon.sld @@ -0,0 +1,26 @@ + + + + area landmarks + + Border-less gray fill + Light gray polygon fill without a border + + + + + + #DDDDDD + + + 1.0 + + + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/giant_polygon.xml b/build/cite/ogcapi-features10/release/styles/giant_polygon.xml new file mode 100644 index 00000000000..1bbd78ca73f --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/giant_polygon.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/grass.xml b/build/cite/ogcapi-features10/release/styles/grass.xml new file mode 100644 index 00000000000..af4cdff9989 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/grass.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/grass_fill.png b/build/cite/ogcapi-features10/release/styles/grass_fill.png new file mode 100644 index 00000000000..c90c5800d79 Binary files /dev/null and b/build/cite/ogcapi-features10/release/styles/grass_fill.png differ diff --git a/build/cite/ogcapi-features10/release/styles/grass_poly.sld b/build/cite/ogcapi-features10/release/styles/grass_poly.sld new file mode 100644 index 00000000000..2dd39218a33 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/grass_poly.sld @@ -0,0 +1,42 @@ + + + + + Grass + + + grass + Grass fill + A style filling polygons with a grass theme coming from a PNG file + + + Grass + Grass style that uses a texture + + + + + + + image/png + + + 1.0 + + + + + + + #FF0000 + 1 + + + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/green.sld b/build/cite/ogcapi-features10/release/styles/green.sld new file mode 100644 index 00000000000..a1118998c29 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/green.sld @@ -0,0 +1,23 @@ + + + + green + + green + Green polygon + Green fill with black outline + + + + + #66FF66 + + + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/green.xml b/build/cite/ogcapi-features10/release/styles/green.xml new file mode 100644 index 00000000000..e9a2de293bd --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/green.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/line.xml b/build/cite/ogcapi-features10/release/styles/line.xml new file mode 100644 index 00000000000..15e15b5d78e --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/line.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/poi.sld b/build/cite/ogcapi-features10/release/styles/poi.sld new file mode 100644 index 00000000000..d062ed46601 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/poi.sld @@ -0,0 +1,77 @@ + + + + poi + + poi + Points of interest + Manhattan points of interest + + + + + + circle + + #FF0000 + 1.0 + + + 11 + + + + + + circle + + #EDE513 + 1.0 + + + 7 + + + + + 32000 + + + + Arial + Bold + 14 + + + + + 0.5 + 0.5 + + + 0 + -15 + + + + + + 2 + + + #FFFFFF + + + + #000000 + + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/poi.xml b/build/cite/ogcapi-features10/release/styles/poi.xml new file mode 100644 index 00000000000..2aae6f55c5b --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/poi.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/point.xml b/build/cite/ogcapi-features10/release/styles/point.xml new file mode 100644 index 00000000000..492f1489584 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/point.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/poly_landmarks.sld b/build/cite/ogcapi-features10/release/styles/poly_landmarks.sld new file mode 100644 index 00000000000..6dbec344687 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/poly_landmarks.sld @@ -0,0 +1,205 @@ + + + + area landmarks + + + + + Feature + + + + + + + + + + CFCC + D82 + + + CFCC + D83 + + + + CFCC + D84 + + + + CFCC + D85 + + + + + + + + #B4DFB4 + + + 1.0 + + + + + #88B588 + + + + + + + + + + + + + CFCC + H11 + + + CFCC + H31 + + + + CFCC + H41 + + + + CFCC + H51 + + + + + + + + #8AA9D1 + + + 1.0 + + + + + #436C91 + + + + + + + + + + + + + + + + + CFCC + D31 + + + CFCC + D43 + + + + CFCC + D64 + + + + CFCC + D65 + + + + CFCC + D90 + + + + CFCC + E23 + + + + + + + + #A5A5A5 + + + 1.0 + + + + + #6E6E6E + + + + + + + + + + + + + + Times New Roman + Normal + 14 + bold + + + + + 0.5 + 0.5 + + + + + + 2 + + + #FDE5A5 + 0.75 + + + + + #000000 + + true + 100 + + + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/poly_landmarks.xml b/build/cite/ogcapi-features10/release/styles/poly_landmarks.xml new file mode 100644 index 00000000000..9961b6ccc32 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/poly_landmarks.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/polygon.xml b/build/cite/ogcapi-features10/release/styles/polygon.xml new file mode 100644 index 00000000000..83b8f4cd006 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/polygon.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/pophatch.sld b/build/cite/ogcapi-features10/release/styles/pophatch.sld new file mode 100644 index 00000000000..3e5f739add5 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/pophatch.sld @@ -0,0 +1,124 @@ + + + + USA states population + + population + Population in the United States + A sample filter that filters the United States into three + categories of population, drawn in different colors + + + < 2M + + + PERSONS + 2000000 + + + + + + + + shape://slash + + 0xAAAAAA + + + 16 + + + + + + + 2M - 4M + + + PERSONS + + 2000000 + + + 4000000 + + + + + + + + + shape://slash + + 0xAAAAAA + + + 8 + + + + + + + > 4M + + + + PERSONS + 4000000 + + + + + + + + shape://slash + + 0xAAAAAA + + + 4 + + + + + + + Boundary + + + + + + + Times New Roman + Normal + 14 + + + + + 0.5 + 0.5 + + + + + 2 + + 0xFFFFFF + + + + + + + + diff --git a/build/cite/ogcapi-features10/release/styles/pophatch.xml b/build/cite/ogcapi-features10/release/styles/pophatch.xml new file mode 100644 index 00000000000..032232a106a --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/pophatch.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/popshade.sld b/build/cite/ogcapi-features10/release/styles/popshade.sld new file mode 100644 index 00000000000..ada67303d7a --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/popshade.sld @@ -0,0 +1,96 @@ + + + + USA states population + + population + Population in the United States + A sample filter that filters the United States into three + categories of population, drawn in different colors + + + < 2M + + + PERSONS + 2000000 + + + + + + #4DFF4D + 0.7 + + + + + 2M - 4M + + + PERSONS + + 2000000 + + + 4000000 + + + + + + + #FF4D4D + 0.7 + + + + + > 4M + + + + PERSONS + 4000000 + + + + + + #4D4DFF + 0.7 + + + + + Boundary + + + 0.2 + + + + + + Times New Roman + Normal + 14 + + + + + 0.5 + 0.5 + + + + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/population.xml b/build/cite/ogcapi-features10/release/styles/population.xml new file mode 100644 index 00000000000..f0bf8fd5a98 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/population.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/rain.sld b/build/cite/ogcapi-features10/release/styles/rain.sld new file mode 100644 index 00000000000..1d04a5fded7 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/rain.sld @@ -0,0 +1,25 @@ + + + + rain + + rain + Rain distribution + + + + 1.0 + + + + + + + + + + + + diff --git a/build/cite/ogcapi-features10/release/styles/rain.xml b/build/cite/ogcapi-features10/release/styles/rain.xml new file mode 100644 index 00000000000..2d9afc68da1 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/rain.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/raster.sld b/build/cite/ogcapi-features10/release/styles/raster.sld new file mode 100644 index 00000000000..a2dcf3b9239 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/raster.sld @@ -0,0 +1,29 @@ + + + + + default_raster + + + Opaque Raster + A sample style that draws a raster, good for displaying imagery + + + + + rule1 + Opaque Raster + A raster with 100% opacity + + 1.0 + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/raster.xml b/build/cite/ogcapi-features10/release/styles/raster.xml new file mode 100644 index 00000000000..b9ee35f0b8a --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/raster.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/restricted.sld b/build/cite/ogcapi-features10/release/styles/restricted.sld new file mode 100644 index 00000000000..a0fd1b52248 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/restricted.sld @@ -0,0 +1,33 @@ + + + + Restricted areas + + Red, translucent style + A sample style that just prints out a transparent red interior with a red outline + + + + + RedFill RedOutline + 70% opaque red fill with a darker 1px red outline + + + + + #FF0000 + 0.7 + + + #AA0000 + 1 + + + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/restricted.xml b/build/cite/ogcapi-features10/release/styles/restricted.xml new file mode 100644 index 00000000000..775258a3a73 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/restricted.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/simpleRoads.sld b/build/cite/ogcapi-features10/release/styles/simpleRoads.sld new file mode 100644 index 00000000000..1b30ccc948f --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/simpleRoads.sld @@ -0,0 +1,28 @@ + + + + Simple Roads + + + Red Line + Light red line, 2px wide + + + Roads + + + + #AA3333 + + + 2 + + + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/simple_roads.xml b/build/cite/ogcapi-features10/release/styles/simple_roads.xml new file mode 100644 index 00000000000..8d085f49718 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/simple_roads.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/simple_streams.sld b/build/cite/ogcapi-features10/release/styles/simple_streams.sld new file mode 100644 index 00000000000..522fde2a750 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/simple_streams.sld @@ -0,0 +1,29 @@ + + + + Simple Streams + + + Streams + Blue lines, 2px wide + + Feature + + Blue Line + + + + #003EBA + + + 2 + + + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/simple_streams.xml b/build/cite/ogcapi-features10/release/styles/simple_streams.xml new file mode 100644 index 00000000000..59423f308d2 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/simple_streams.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/styles/tiger_roads.sld b/build/cite/ogcapi-features10/release/styles/tiger_roads.sld new file mode 100644 index 00000000000..87f30bee09b --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/tiger_roads.sld @@ -0,0 +1,95 @@ + + + area landmarks + + + Feature + + 32000 + + + + #666666 + + + 2 + + + + + + + 32000 + + + + #666666 + + + 7 + + + + + + + Feature + + 32000 + + + + #FFFFFF + + + 4 + + + + + + + 32000 + + + + + Times New Roman + Normal + 14 + bold + + + + + + + + + 2 + + + #FFFFFF + 0.85 + + + + + #000000 + + + true + + + + + + + + diff --git a/build/cite/ogcapi-features10/release/styles/tiger_roads.xml b/build/cite/ogcapi-features10/release/styles/tiger_roads.xml new file mode 100644 index 00000000000..67df7dd7f60 --- /dev/null +++ b/build/cite/ogcapi-features10/release/styles/tiger_roads.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/user_projections/epsg.properties b/build/cite/ogcapi-features10/release/user_projections/epsg.properties new file mode 100644 index 00000000000..4315d090dc0 --- /dev/null +++ b/build/cite/ogcapi-features10/release/user_projections/epsg.properties @@ -0,0 +1,32 @@ +18001=PROJCS["Geoscience Australia Standard National Scale Lambert Projection",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1978",6378135,298.26],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",134.0],PARAMETER["latitude_of_origin",0.0],PARAMETER["standard_parallel_1",-18.0],PARAMETER["standard_parallel_2",-36.0],UNIT["Meter",1]] +41001=PROJCS["WGS84 / Simple Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],UNIT["Meter",1]] +42101=PROJCS["WGS 84 / LCC Canada",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],PARAMETER["false_northing",-8000000.0],UNIT["Meter",1]] +42102=PROJCS["BC_Albers",GEOGCS["GCS_North_American_1983",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Albers_Conic_Equal_Area"],PARAMETER["False_Easting",1000000],PARAMETER["Central_Meridian",-126],PARAMETER["Standard_Parallel_1",50],PARAMETER["Standard_Parallel_2",58.5],PARAMETER["Latitude_Of_Origin",45],UNIT["Meter",1]] +42103=PROJCS["WGS 84 / LCC USA",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1978",6378135,298.26]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-100.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",33.0],PARAMETER["standard_parallel_2",45.0],UNIT["Meter",1]] +42104=PROJCS["NAD83 / MTM zone 8 Qubec",GEOGCS["GRS80",DATUM["GRS_1980",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-73.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],UNIT["Meter",1]] +42105=PROJCS["WGS84 / Merc NorthAm",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",-96],UNIT["Meter",1]] +42106=PROJCS["WGS84 / Lambert Azim Mozambique",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Azimuthal_Equal_Area"],PARAMETER["latitude_of_origin",5],PARAMETER["central_meridian",20],UNIT["Meter",1]] +42301=PROJCS["NAD27 / Polar Stereographic / CM=-98",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.978698213901],TOWGS84[-9,151,185]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Stereographic"],PARAMETER["latitude_of_origin",90],PARAMETER["central_meridian",-98.0],PARAMETER["scale_factor",0.9996],UNIT["Meter",1]] +42302=PROJCS["JapanOrtho.09 09",GEOGCS["Lon/Lat.Tokyo Datum",DATUM["Tokyo Datum",SPHEROID["anon",6377397.155,299.15281310608]],PRIMEM["Greenwich",0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",139.833333333333],PARAMETER["Latitude_of_Origin",36],PARAMETER["Scale_Factor",0.9999],UNIT["Meter",1]] +42303=PROJCS["NAD83 / Albers NorthAm",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Albers_conic_equal_area"],PARAMETER["central_meridian",-96.0],PARAMETER["latitude_of_origin",23],PARAMETER["standard_parallel_1",29.5],PARAMETER["standard_parallel_2",45.5],UNIT["Meter",1]] +42304=PROJCS["NAD83 / NRCan LCC Canada",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",49.0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],UNIT["Meter",1]] +42305=PROJCS["France_II",GEOGCS["GCS_NTF_Paris",DATUM["Nouvelle_Triangulation_Francaise",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Paris",2.337229166666667],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["False_Easting",600000],PARAMETER["False_Northing",2200000],PARAMETER["Central_Meridian",0],PARAMETER["Standard_Parallel_1",45.898918964419],PARAMETER["Standard_Parallel_2",47.696014502038],PARAMETER["Latitude_Of_Origin",46.8],UNIT["Meter",1]] +42306=PROJCS["NAD83/QC_LCC",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-68.5],PARAMETER["latitude_of_origin",44],PARAMETER["standard_parallel_1",46],PARAMETER["standard_parallel_2",60],UNIT["Meter",1]] +42307=PROJCS["NAD83 / Texas Central - feet",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",31.8833333333333],PARAMETER["standard_parallel_2",30.1166666666667],PARAMETER["latitude_of_origin",29.6666666666667],PARAMETER["central_meridian",-100.333333333333],PARAMETER["false_easting",2296583.33333333333333],PARAMETER["false_northing",9842500],UNIT["US_Foot",0.30480060960121924]] +42308=PROJCS["NAD27 / California Albers",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.978698213901],TOWGS84[-9,151,185]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Albers_conic_equal_area"],PARAMETER["central_meridian",-120.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",34],PARAMETER["standard_parallel_2",40.5],PARAMETER["false_northing",-4000000],UNIT["Meter",1]] +42309=PROJCS["NAD 83 / LCC Canada AVHRR-2",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],UNIT["Meter",1]] +42310=PROJCS["WGS84+GRS80 / Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],UNIT["Meter",1]] +42311=PROJCS["NAD83 / LCC Statcan",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-91.866667],PARAMETER["latitude_of_origin",63.390675],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",77],PARAMETER["false_easting",6200000],PARAMETER["false_northing",3000000],UNIT["Meter",1]] +45555=PROJCS["WRF_Lambert_Conformal_Conic 2",GEOGCS["GCS_North_American_1983",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.25722356300003]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943299]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",-97],PARAMETER["Standard_Parallel_1",33],PARAMETER["Standard_Parallel_2",60],PARAMETER["Latitude_Of_Origin",40.003338],UNIT["Meter",1],AUTHORITY["EPSG","45555"]] +45556=PROJCS["Albers Equal area",GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AUTHORITY["EPSG","4326"]], PROJECTION["Albers Equal Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -96.0], PARAMETER["latitude_of_origin", 37.5], PARAMETER["standard_parallel_1", 29.833333333333336], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 45.833333333333336], UNIT["m", 1.0], AUTHORITY["EPSG","45556"]] +53029=PROJCS["Sphere_Van_der_Grinten_I",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Van_der_Grinten_I"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]] +54004=PROJCS["WGS84 / Simple Mercator", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS_1984", 6378137.0, 298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295]], PROJECTION["Mercator_1SP_Google"], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["x", EAST], AXIS["y", NORTH], AUTHORITY["EPSG","54004"]] +54009=PROJCS["World_Mollweide",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mollweide"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]] +54012=PROJCS["World_Eckert_IV",GEOGCS["WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_IV"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]] +54029=PROJCS["World_Van_der_Grinten_I",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Van_der_Grinten_I"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]] +100001=GEOGCS["NAD83 / NFIS Seconds",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Second",4.84813681109536e-06]] +100002=PROJCS["NAD83 / Austin",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",31.8833333333333],PARAMETER["standard_parallel_2",30.1166666666667],PARAMETER["latitude_of_origin",29.6666666666667],PARAMETER["central_meridian",-100.333333333333],PARAMETER["false_easting",2296583.333333],PARAMETER["false_northing",9842500.0000000],UNIT["Meter",1]] +100003=PROJCS["WGS84 / Google Mercator", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator (1SP)", AUTHORITY["EPSG","9804"]], PARAMETER["semi_major", 6378137.0], PARAMETER["semi_minor", 6378137.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AUTHORITY["EPSG","900913"]] +102113=PROJCS["WGS84 / Google Mercator", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator (1SP)", AUTHORITY["EPSG","9804"]], PARAMETER["semi_major", 6378137.0], PARAMETER["semi_minor", 6378137.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AUTHORITY["EPSG","102113"]] +900913=PROJCS["WGS84 / Google Mercator", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator (1SP)", AUTHORITY["EPSG","9804"]], PARAMETER["semi_major", 6378137.0], PARAMETER["semi_minor", 6378137.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AUTHORITY["EPSG","900913"]] +391141=PROJCS["Equal Earth",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Equal Earth"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]] diff --git a/build/cite/ogcapi-features10/release/wcs.xml b/build/cite/ogcapi-features10/release/wcs.xml new file mode 100644 index 00000000000..71cd7128e38 --- /dev/null +++ b/build/cite/ogcapi-features10/release/wcs.xml @@ -0,0 +1,40 @@ + + wcs + true + WCS + Web Coverage Service + + http://geoserver.org/comm + This server implements the WCS specification 1.0 and 1.1.1, it's reference implementation of WCS 1.1.1. All layers published by this service are available on WMS also. + + NONE + NONE + + + 1.0.0 + + + 1.1.1 + + + 2.0.1 + + + + WCS + GEOSERVER + + + undef + http://geoserver.sourceforge.net/html/index.php + other + + false + http://geoserver.org + http://schemas.opengis.net + false + false + false + 0 + 0 + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/wfs.xml b/build/cite/ogcapi-features10/release/wfs.xml new file mode 100644 index 00000000000..1712be61546 --- /dev/null +++ b/build/cite/ogcapi-features10/release/wfs.xml @@ -0,0 +1,70 @@ + + wfs + true + WFS + GeoServer Web Feature Service + + http://geoserver.org/comm + This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction. + + NONE + NONE + + + 1.0.0 + + + 1.1.0 + + + 2.0.0 + + + + WFS + GEOSERVER + + + false + http://geoserver.org + http://schemas.opengis.net + false + + false + + + + V_10 + + XML + true + + + + V_20 + + URN2 + false + + + + V_11 + + URN + false + + + + COMPLETE + 1000000 + false + false + false + false + false + + 4326 + 4087 + + false + diff --git a/build/cite/ogcapi-features10/release/wms.xml b/build/cite/ogcapi-features10/release/wms.xml new file mode 100644 index 00000000000..7a842f30715 --- /dev/null +++ b/build/cite/ogcapi-features10/release/wms.xml @@ -0,0 +1,68 @@ + + wms + true + WMS + GeoServer Web Map Service + + http://geoserver.org/comm + A compliant implementation of WMS plus most of the SLD extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS + + NONE + NONE + + + 1.1.1 + + + 1.3.0 + + + + WMS + GEOSERVER + + + false + http://geoserver.org + http://schemas.opengis.net + false + + false + auto + refresh + true + true + false + 40 + true + 25 + 25 + false + true + true + Batik + + false + + + false + BOT_RIGHT + 0 + + Nearest + false + false + false + false + 25 + 65536 + 60 + 1000 + + + + false + 1000 + 51200 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/wmts.xml b/build/cite/ogcapi-features10/release/wmts.xml new file mode 100644 index 00000000000..126a53ff034 --- /dev/null +++ b/build/cite/ogcapi-features10/release/wmts.xml @@ -0,0 +1,22 @@ + + WMTSInfoImpl--3ef31051:182c1e8b194:-8000 + true + WMTS + GeoServer Web Map Tile Service + http://geoserver.org/com + A compliant implementation of WMTS service. + NONE + NONE + + + 1.0.0 + + + + WMTS + + false + http://geoserver.org + http://schemas.opengis.net + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/default.xml b/build/cite/ogcapi-features10/release/workspaces/default.xml new file mode 100644 index 00000000000..65ac817341f --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/default.xml @@ -0,0 +1,7 @@ + + WorkspaceInfoImpl-1c443fee:182c0f3f209:-7ffe + ne + false + 2022-08-21 15:10:28.234 UTC + 2022-09-27 23:39:44.130 UTC + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/boundary_lines/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/boundary_lines/featuretype.xml new file mode 100644 index 00000000000..794fb11d3d6 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/boundary_lines/featuretype.xml @@ -0,0 +1,55 @@ + + FeatureTypeInfoImpl-1c443fee:182c0f3f209:-7ff8 + boundary_lines + boundary_lines_land + + NamespaceInfoImpl-1c443fee:182c0f3f209:-7ffd + + Boundary Lines + Country boundaries on land and offshore. + + features + boundary_lines_land + + GEOGCS["WGS 84", + DATUM["World Geodetic System 1984", + SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], + AUTHORITY["EPSG","6326"]], + PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], + UNIT["degree", 0.017453292519943295], + AXIS["Geodetic longitude", EAST], + AXIS["Geodetic latitude", NORTH], + AUTHORITY["EPSG","4326"]] + EPSG:4326 + + -140.99778 + 141.0338517600138 + -54.89681 + 70.16419 + EPSG:4326 + + + -140.99778 + 141.0338517600138 + -54.89681 + 70.16419 + EPSG:4326 + + FORCE_DECLARED + true + + false + + + DataStoreInfoImpl-1c443fee:182c0f3f209:-7ffb + + false + false + 0 + 0 + false + false + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/boundary_lines/layer.xml b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/boundary_lines/layer.xml new file mode 100644 index 00000000000..6f5592ae546 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/boundary_lines/layer.xml @@ -0,0 +1,22 @@ + + boundary_lines + LayerInfoImpl-1c443fee:182c0f3f209:-7ff7 + VECTOR + + StyleInfoImpl-1c443fee:182c0f3f209:-7fe4 + + + + + + FeatureTypeInfoImpl-1c443fee:182c0f3f209:-7ff8 + + + 0 + 0 + + 2022-08-21 15:25:56.948 UTC + 2022-08-21 16:15:02.807 UTC + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/coastlines/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/coastlines/featuretype.xml new file mode 100644 index 00000000000..e52b76a4a7b --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/coastlines/featuretype.xml @@ -0,0 +1,55 @@ + + FeatureTypeInfoImpl-1c443fee:182c0f3f209:-7ff0 + coastlines + coastlines + + NamespaceInfoImpl-1c443fee:182c0f3f209:-7ffd + + Coastlines + Ocean coastline, including major islands. + + features + coastlines + + GEOGCS["WGS 84", + DATUM["World Geodetic System 1984", + SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], + AUTHORITY["EPSG","6326"]], + PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], + UNIT["degree", 0.017453292519943295], + AXIS["Geodetic longitude", EAST], + AXIS["Geodetic latitude", NORTH], + AUTHORITY["EPSG","4326"]] + EPSG:4326 + + -180.0 + 180.0000004418103 + -85.60903777459772 + 83.64513 + EPSG:4326 + + + -180.0 + 180.0000004418103 + -85.60903777459772 + 83.64513 + EPSG:4326 + + FORCE_DECLARED + true + + false + + + DataStoreInfoImpl-1c443fee:182c0f3f209:-7ffb + + false + false + 0 + 0 + false + false + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/coastlines/layer.xml b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/coastlines/layer.xml new file mode 100644 index 00000000000..9d50df4bb11 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/coastlines/layer.xml @@ -0,0 +1,22 @@ + + coastlines + LayerInfoImpl-1c443fee:182c0f3f209:-7fef + VECTOR + + StyleInfoImpl-1c443fee:182c0f3f209:-7fee + + + + + + FeatureTypeInfoImpl-1c443fee:182c0f3f209:-7ff0 + + + 0 + 0 + + 2022-08-21 15:41:25.144 UTC + 2022-08-21 16:14:14.428 UTC + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/countries/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/countries/featuretype.xml new file mode 100644 index 00000000000..d799a379547 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/countries/featuretype.xml @@ -0,0 +1,55 @@ + + FeatureTypeInfoImpl-1c443fee:182c0f3f209:-7ffa + countries + countries + + NamespaceInfoImpl-1c443fee:182c0f3f209:-7ffd + + Countries + Country boundaries on land and offshore. + + features + countries + + GEOGCS["WGS 84", + DATUM["World Geodetic System 1984", + SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], + AUTHORITY["EPSG","6326"]], + PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], + UNIT["degree", 0.017453292519943295], + AXIS["Geodetic longitude", EAST], + AXIS["Geodetic latitude", NORTH], + AUTHORITY["EPSG","4326"]] + EPSG:4326 + + -180.0 + 180.0 + -90.0 + 83.64513 + EPSG:4326 + + + -180.0 + 180.0 + -90.0 + 83.64513 + EPSG:4326 + + FORCE_DECLARED + true + + false + + + DataStoreInfoImpl-1c443fee:182c0f3f209:-7ffb + + false + false + 0 + 0 + false + false + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/countries/layer.xml b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/countries/layer.xml new file mode 100644 index 00000000000..cd15fee43d3 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/countries/layer.xml @@ -0,0 +1,25 @@ + + countries + LayerInfoImpl-1c443fee:182c0f3f209:-7ff9 + VECTOR + + StyleInfoImpl-1c443fee:182c0f3f209:-7fd7 + + + + + + + FeatureTypeInfoImpl-1c443fee:182c0f3f209:-7ffa + + + 0 + 0 + + 2022-08-21 15:24:36.787 UTC + 2022-09-26 06:57:39.147 UTC + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/datastore.xml b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/datastore.xml new file mode 100644 index 00000000000..b03f60111fa --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/datastore.xml @@ -0,0 +1,22 @@ + + DataStoreInfoImpl-1c443fee:182c0f3f209:-7ffb + NaturalEarth + GeoPackage + true + + WorkspaceInfoImpl-1c443fee:182c0f3f209:-7ffe + + + 1 + file:data/ne/natural_earth.gpkg + 1000 + false + true + geopkg + https://www.naturalearthdata.com + + <__default>false + 2022-08-21 15:20:30.885 UTC + 2023-01-22 22:31:38.598 UTC + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/disputed_areas/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/disputed_areas/featuretype.xml new file mode 100644 index 00000000000..da35a5d3f7a --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/disputed_areas/featuretype.xml @@ -0,0 +1,52 @@ + + FeatureTypeInfoImpl--72884701:185db6cdd61:-7fff + disputed_areas + disputed_areas + + NamespaceInfoImpl-1c443fee:182c0f3f209:-7ffd + + Disputed Areas + Disputed areas and breakaway regions. + + features + disputed_areas + + GEOGCS["WGS 84", + DATUM["World Geodetic System 1984", + SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], + AUTHORITY["EPSG","6326"]], + PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], + UNIT["degree", 0.017453292519943295], + AXIS["Geodetic longitude", EAST], + AXIS["Geodetic latitude", NORTH], + AUTHORITY["EPSG","4326"]] + EPSG:4326 + + -58.4273066880497 + 148.8371480653835 + 1.475362453615232 + 48.70561341257376 + EPSG:4326 + + + -58.4273066880497 + 148.8371480653835 + 1.475362453615232 + 48.70561341257376 + EPSG:4326 + + FORCE_DECLARED + true + + DataStoreInfoImpl-1c443fee:182c0f3f209:-7ffb + + false + false + 0 + 0 + false + false + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/disputed_areas/layer.xml b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/disputed_areas/layer.xml new file mode 100644 index 00000000000..47bc072ab9d --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/disputed_areas/layer.xml @@ -0,0 +1,17 @@ + + disputed_areas + LayerInfoImpl--72884701:185db6cdd61:-7ffe + VECTOR + + StyleInfoImpl--72884701:185db6cdd61:-7ffd + + + FeatureTypeInfoImpl--72884701:185db6cdd61:-7fff + + + 0 + 0 + + 2023-01-22 21:43:37.670 UTC + 2023-01-22 21:47:54.745 UTC + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/populated_places/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/populated_places/featuretype.xml new file mode 100644 index 00000000000..e7c2887e30f --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/populated_places/featuretype.xml @@ -0,0 +1,55 @@ + + FeatureTypeInfoImpl-1c443fee:182c0f3f209:-7ff6 + populated_places + populated_places + + NamespaceInfoImpl-1c443fee:182c0f3f209:-7ffd + + Populated Places + City and town points + + features + populated_places + + GEOGCS["WGS 84", + DATUM["World Geodetic System 1984", + SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], + AUTHORITY["EPSG","6326"]], + PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], + UNIT["degree", 0.017453292519943295], + AXIS["Geodetic longitude", EAST], + AXIS["Geodetic latitude", NORTH], + AUTHORITY["EPSG","4326"]] + EPSG:4326 + + -175.2205644999999 + 179.2166470999999 + -41.29206799231509 + 64.14345946317033 + EPSG:4326 + + + -175.2205644999999 + 179.2166470999999 + -41.29206799231509 + 64.14345946317033 + EPSG:4326 + + FORCE_DECLARED + true + + false + + + DataStoreInfoImpl-1c443fee:182c0f3f209:-7ffb + + false + false + 0 + 0 + false + false + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/populated_places/layer.xml b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/populated_places/layer.xml new file mode 100644 index 00000000000..a513f9ca00c --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/NaturalEarth/populated_places/layer.xml @@ -0,0 +1,22 @@ + + populated_places + LayerInfoImpl-1c443fee:182c0f3f209:-7ff5 + VECTOR + + StyleInfoImpl-1c443fee:182c0f3f209:-7fcf + + + + + + FeatureTypeInfoImpl-1c443fee:182c0f3f209:-7ff6 + + + 0 + 0 + + 2022-08-21 15:26:37.327 UTC + 2022-09-27 23:54:36.502 UTC + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/layergroups/world.xml b/build/cite/ogcapi-features10/release/workspaces/ne/layergroups/world.xml new file mode 100644 index 00000000000..063901951cb --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/layergroups/world.xml @@ -0,0 +1,49 @@ + + LayerGroupInfoImpl-1c443fee:182c0f3f209:-7ff4 + world + NAMED + World Map + World map constructed with Natural Earth countries, boundaries and populated places. + + WorkspaceInfoImpl-1c443fee:182c0f3f209:-7ffe + + + + + + LayerInfoImpl-1c443fee:182c0f3f209:-7ff9 + + + LayerInfoImpl--72884701:185db6cdd61:-7ffe + + + LayerInfoImpl-1c443fee:182c0f3f209:-7fef + + + LayerInfoImpl-1c443fee:182c0f3f209:-7ff7 + + + LayerInfoImpl-1c443fee:182c0f3f209:-7ff5 + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/styles/coastline.sld b/build/cite/ogcapi-features10/release/workspaces/ne/styles/coastline.sld new file mode 100644 index 00000000000..1ed84ba69e6 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/styles/coastline.sld @@ -0,0 +1,56 @@ + + + + coastline + + + + Coastline + 7.0E7 + + + #B3CCD1 + 0.5 + + + + + Coastline + 3.5E7 + 7.0E7 + + + #B3CCD1 + 0.75 + + + + + Coastline + 2.0E7 + 3.5E7 + + + #B3CCD1 + 1.00 + + + + + Coastline + 2.0E7 + + + #B3CCD1 + 1.50 + + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/styles/coastline.xml b/build/cite/ogcapi-features10/release/workspaces/ne/styles/coastline.xml new file mode 100644 index 00000000000..ffb22820555 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/styles/coastline.xml @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/styles/countries.sld b/build/cite/ogcapi-features10/release/workspaces/ne/styles/countries.sld new file mode 100644 index 00000000000..74c8dbec9fb --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/styles/countries.sld @@ -0,0 +1,264 @@ + + + + ne:countries + + countries_transparent + Countries + Alternate on mapcolor9 theme for ne:countries layer. This presentation uses a slight transparencyto allow background to show through as part of a layer group or map. Labeling is done at a lower priority than populated places to allow cities to take precedence + + + Countries + + + #8DD3C7 + + legendOnly + + + + + + + + MAPCOLOR9 + 1 + #8dd3c7 + 2 + #ffffb3 + 3 + #bebada + 4 + #fb8072 + 5 + #80b1d3 + 6 + #fdb462 + 7 + #b3de69 + 8 + #fccde5 + 9 + #d9d9d9 + + + 0.75 + + mapOnly + + + + + + + MIN_ZOOM + 2 + + + 14.0E7 + + + + + NAME_LEN + 8 + + + + + NAME + en + NAME + it + NAME_IT + fr + NAME_FR + + ABBREV + + + + SansSerif + 10 + + + + + 0.5 + 0.5 + + + + + #777777 + + + + 50 + LABELRANK + + + 20 + 8 + 1 + 70 + 0.95 + mapOnly + + + + + + MIN_ZOOM + 3 + + + 7.0E7 + 14.0E7 + + + + + + NAME + en + NAME + it + NAME_IT + fr + NAME_FR + + + + SansSerif + 12 + + + + + 0.5 + 0.5 + + + + + #777777 + + + + 5 + LABELRANK + + + 20 + 8 + 1 + 70 + 0.95 + mapOnly + + + + + + MIN_ZOOM + 50 + + + 3.5E7 + 7.0E7 + + + + + + NAME + en + NAME + it + NAME_IT + fr + NAME_FR + + + + SansSerif + 14 + bold + + + + + 0.5 + 0.5 + + + + + #777777 + + + + 50 + LABELRANK + + + 40 + 8 + 1 + 90 + 1.0 + mapOnly + + + + 3.5E7 + + + + + + NAME + en + NAME + it + NAME_IT + fr + NAME_FR + + + + SansSerif + 16 + bold + + + + + 0.5 + 0.5 + + + + + #777777 + + + + 50 + LABELRANK + + + 50 + 10 + 1 + 100 + 1.00 + mapOnly + + + + + + + diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/styles/countries.xml b/build/cite/ogcapi-features10/release/workspaces/ne/styles/countries.xml new file mode 100644 index 00000000000..f92e20e06e2 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/styles/countries.xml @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/styles/countries_mapcolor9.sld b/build/cite/ogcapi-features10/release/workspaces/ne/styles/countries_mapcolor9.sld new file mode 100644 index 00000000000..230d564bd48 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/styles/countries_mapcolor9.sld @@ -0,0 +1,57 @@ + + + + ne:countries + + countries_mapcolor_9 + Countries Mapcolor9 + Theme using mapcolor9 for ne:countries layer. + + + + Countries + + + #8DD3C7 + + legendOnly + + + + + + + + MAPCOLOR9 + 1 + #8dd3c7 + 2 + #ffffb3 + 3 + #bebada + 4 + #fb8072 + 5 + #80b1d3 + 6 + #fdb462 + 7 + #b3de69 + 8 + #fccde5 + 9 + #d9d9d9 + + + + mapOnly + + + + + + diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/styles/countries_mapcolor9.xml b/build/cite/ogcapi-features10/release/workspaces/ne/styles/countries_mapcolor9.xml new file mode 100644 index 00000000000..1f64e3d07b1 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/styles/countries_mapcolor9.xml @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/styles/disputed.sld b/build/cite/ogcapi-features10/release/workspaces/ne/styles/disputed.sld new file mode 100644 index 00000000000..24b04525ecd --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/styles/disputed.sld @@ -0,0 +1,25 @@ + + + + disputed + + Disputed Area + + + disputed + + + #CCCCCC + 0.75 + + + + + + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/styles/disputed.xml b/build/cite/ogcapi-features10/release/workspaces/ne/styles/disputed.xml new file mode 100644 index 00000000000..4e365f8a5af --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/styles/disputed.xml @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/styles/populated_places.sld b/build/cite/ogcapi-features10/release/workspaces/ne/styles/populated_places.sld new file mode 100644 index 00000000000..aeeec6b4686 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/styles/populated_places.sld @@ -0,0 +1,243 @@ + + + + + ne:populated_places + + populated_places + Populated Places + Dynamic presentation of populated places with level of detail depending on scale. Dymanic styling is used to determine mark symbol shown based on feature classification. Label is introduced at lower scales. + + places + + + + min_zoom + 2 + + + 14.0E7 + + + + circle + + #777777 + + + 3 + + + + + + + + + min_zoom + 3 + + + 7.0E7 + 14.0E7 + + + + circle + + #777777 + + + 4 + + + + + + + + + min_zoom + 3 + + + featurecla + Admin-0 + + + + 7.0E7 + 14.0E7 + + + + star + + #777777 + + + 5 + + + + + + + + + + min_zoom + 5 + + + 3.5E7 + 7.0E7 + + + + ${if_then_else(equalTo(featurecla,'Admin-0 capital'),'star','circle')} + + #999999 + + + #666666 + 1.0 + + + + + + featurecla + Admin-0 capital + + 7 + 5 + + + + true + + + + name + + + SansSerif + 12 + + + + + + + 0.5 + 1 + + + 0 + -5 + + + + + + 0.75 + + #FFFFFF + 0.75 + + + + + + #000000 + + + + 100 + labelrank + + + + 10 + + + + + + 3.5E7 + + + + ${if_then_else(equalTo(featurecla,'Admin-0 capital'),'star','circle')} + + #999999 + + + #666666 + 1.5 + + + + + + featurecla + Admin-0 capital + + 8 + 6 + + + + true + + + + name + + + SansSerif + 14 + + + + + 0.5 + 1 + + + 0 + -5 + + + + + 1.5 + + #FFFFFF + 0.75 + + + + + #000000 + + + + 100 + labelrank + + + 12 + 5 + + + + + + + diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/styles/populated_places.xml b/build/cite/ogcapi-features10/release/workspaces/ne/styles/populated_places.xml new file mode 100644 index 00000000000..320ac748e60 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/styles/populated_places.xml @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/wcs.xml b/build/cite/ogcapi-features10/release/workspaces/ne/wcs.xml new file mode 100644 index 00000000000..b3aa2e7da6b --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/wcs.xml @@ -0,0 +1,47 @@ + + WCSInfoImpl-1c443fee:182c0f3f209:-7f96 + + WorkspaceInfoImpl-1c443fee:182c0f3f209:-7ffe + + true + WCS + GeoServer Natural Earth Raster data and imagery + + http://geoserver.org/comm + Direct access to Natural Earth raster data and imagery. + + NONE + NONE + + + 1.0.0 + + + 1.1.1 + + + 2.0.1 + + + + WCS + GEOSERVER + + + undef + http://geoserver.sourceforge.net/html/index.php + other + + false + http://geoserver.org + http://schemas.opengis.net + false + false + false + 0 + 0 + 9 + true + IGNORE + 100 + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/wfs.xml b/build/cite/ogcapi-features10/release/workspaces/ne/wfs.xml new file mode 100644 index 00000000000..0c41f986ddc --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/wfs.xml @@ -0,0 +1,71 @@ + + WFSInfoImpl-1c443fee:182c0f3f209:-7f97 + + WorkspaceInfoImpl-1c443fee:182c0f3f209:-7ffe + + true + WFS + GeoServer Natural Earth Vector data + + http://geoserver.org/comm + Natural Earth feature data. + + NONE + NONE + + + 1.0.0 + + + 1.1.0 + + + 2.0.0 + + + + WFS + WMS + GEOSERVER + + + false + http://geoserver.org + http://schemas.opengis.net + false + + false + + + + V_11 + + URN + false + + + + V_20 + + URN2 + false + + + + V_10 + + XML + true + + + + COMPLETE + 1000000 + false + false + false + false + false + true + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/wms.xml b/build/cite/ogcapi-features10/release/workspaces/ne/wms.xml new file mode 100644 index 00000000000..c9421614598 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/wms.xml @@ -0,0 +1,78 @@ + + WMSInfoImpl-1c443fee:182c0f3f209:-7f99 + + WorkspaceInfoImpl-1c443fee:182c0f3f209:-7ffe + + true + WMS + GeoServer Natural Earth Maps + + http://geoserver.org/comm + Map images generated from Natural Earth vector data, raster data and imagery. + + NONE + NONE + + + 1.1.1 + + + 1.3.0 + + + + WMS + GEOSERVER + + + false + http://geoserver.org + http://schemas.opengis.net + false + + false + auto + refresh + true + false + false + 40 + true + 25 + 25 + false + true + true + Batik + + false + + false + + false + BOT_RIGHT + 0 + + Nearest + false + false + false + false + 25 + 65536 + 60 + 1000 + Natural Earth + Natural Earth is a public domain map dataset available featuring tightly integrated vector and raster data. + + + 100 + + false + 1000 + 51200 + + 60000 + 30000 + true + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/wmts.xml b/build/cite/ogcapi-features10/release/workspaces/ne/wmts.xml new file mode 100644 index 00000000000..bcf8861ccb3 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/wmts.xml @@ -0,0 +1,25 @@ + + WMTSInfoImpl-1c443fee:182c0f3f209:-7f98 + + WorkspaceInfoImpl-1c443fee:182c0f3f209:-7ffe + + true + WMTS + GeoServer Natural Earth Tiles + http://geoserver.org/com + Map tiles generated from Natural Earth vector data, raster data and imagery. + NONE + NONE + + + 1.0.0 + + + + WMTS + + false + http://geoserver.org + http://schemas.opengis.net + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/ne/workspace.xml b/build/cite/ogcapi-features10/release/workspaces/ne/workspace.xml new file mode 100644 index 00000000000..70801684944 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/ne/workspace.xml @@ -0,0 +1,7 @@ + + WorkspaceInfoImpl-1c443fee:182c0f3f209:-7ffe + ne + false + 2022-08-21 15:10:28.234 UTC + 2022-09-23 08:29:42.450 UTC + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/namespace.xml b/build/cite/ogcapi-features10/release/workspaces/sf/namespace.xml new file mode 100644 index 00000000000..8dfbb0cd4a5 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/namespace.xml @@ -0,0 +1,5 @@ + + NamespaceInfoImpl--570ae188:124761b8d78:-8000 + sf + http://www.openplans.org/spearfish + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/sf/archsites/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/sf/sf/archsites/featuretype.xml new file mode 100644 index 00000000000..a95d5dfdeb9 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/sf/archsites/featuretype.xml @@ -0,0 +1,89 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fcb + archsites + archsites + + NamespaceInfoImpl--570ae188:124761b8d78:-8000 + + Spearfish archeological sites + Sample data from GRASS, archeological sites location, Spearfish, South Dakota, USA + + archsites + spearfish + sfArchsites + archeology + + PROJCS["NAD27 / UTM zone 13N", + GEOGCS["NAD27", + DATUM["North American Datum 1927", + SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], + TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], + AUTHORITY["EPSG","6267"]], + PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], + UNIT["degree", 0.017453292519943295], + AXIS["Geodetic longitude", EAST], + AXIS["Geodetic latitude", NORTH], + AUTHORITY["EPSG","4267"]], + PROJECTION["Transverse_Mercator"], + PARAMETER["central_meridian", -105.0], + PARAMETER["latitude_of_origin", 0.0], + PARAMETER["scale_factor", 0.9996], + PARAMETER["false_easting", 500000.0], + PARAMETER["false_northing", 0.0], + UNIT["m", 1.0], + AXIS["Easting", EAST], + AXIS["Northing", NORTH], + AUTHORITY["EPSG","26713"]] + EPSG:26713 + + 589851.4376666048 + 608346.4603107043 + 4914490.882968263 + 4926501.8980334345 + EPSG:26713 + + + -103.8725637911543 + -103.63794182141925 + 44.37740330855979 + 44.48804280772808 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + sfArchsites_archsites + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fdb + + 0 + 0 + + + the_geom + 0 + 1 + false + + + cat + 0 + 1 + false + + + str1 + 0 + 1 + false + + + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/sf/archsites/layer.xml b/build/cite/ogcapi-features10/release/workspaces/sf/sf/archsites/layer.xml new file mode 100644 index 00000000000..41002163ada --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/sf/archsites/layer.xml @@ -0,0 +1,25 @@ + + archsites + LayerInfoImpl--570ae188:124761b8d78:-7fca + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7fdf + + + + + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fcb + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/sf/bugsites/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/sf/sf/bugsites/featuretype.xml new file mode 100644 index 00000000000..3583663b19f --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/sf/bugsites/featuretype.xml @@ -0,0 +1,90 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fc9 + bugsites + bugsites + + NamespaceInfoImpl--570ae188:124761b8d78:-8000 + + Spearfish bug locations + Sample data from GRASS, bug sites location, Spearfish, South Dakota, USA + + spearfish + sfBugsites + insects + bugsites + tiger_beetles + + PROJCS["NAD27 / UTM zone 13N", + GEOGCS["NAD27", + DATUM["North American Datum 1927", + SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], + TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], + AUTHORITY["EPSG","6267"]], + PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], + UNIT["degree", 0.017453292519943295], + AXIS["Geodetic longitude", EAST], + AXIS["Geodetic latitude", NORTH], + AUTHORITY["EPSG","4267"]], + PROJECTION["Transverse_Mercator"], + PARAMETER["central_meridian", -105.0], + PARAMETER["latitude_of_origin", 0.0], + PARAMETER["scale_factor", 0.9996], + PARAMETER["false_easting", 500000.0], + PARAMETER["false_northing", 0.0], + UNIT["m", 1.0], + AXIS["Easting", EAST], + AXIS["Northing", NORTH], + AUTHORITY["EPSG","26713"]] + EPSG:26713 + + 590223.4382724703 + 608462.4604629107 + 4914107.882513998 + 4920523.89081033 + EPSG:26713 + + + -103.86796131703647 + -103.63773523234195 + 44.373938816704396 + 44.43418821380063 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + sfBugsites_bugsites + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fdb + + 0 + 0 + + + the_geom + 0 + 1 + false + + + cat + 0 + 1 + false + + + str1 + 0 + 1 + false + + + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/sf/bugsites/layer.xml b/build/cite/ogcapi-features10/release/workspaces/sf/sf/bugsites/layer.xml new file mode 100644 index 00000000000..677c734da26 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/sf/bugsites/layer.xml @@ -0,0 +1,25 @@ + + bugsites + LayerInfoImpl--570ae188:124761b8d78:-7fc8 + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7ff0 + + + + + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fc9 + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/sf/datastore.xml b/build/cite/ogcapi-features10/release/workspaces/sf/sf/datastore.xml new file mode 100644 index 00000000000..f3302961a15 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/sf/datastore.xml @@ -0,0 +1,17 @@ + + DataStoreInfoImpl--570ae188:124761b8d78:-7fdb + sf + Vector data for Spearfish City in Lawrence County, South Dakota. The area covered by the data set is in the vicinity of Spearfish and includes a majority of the Black Hills National Forest (i.e., Mount Rushmore). + true + + WorkspaceInfoImpl--570ae188:124761b8d78:-7fff + + + false + false + http://www.openplans.org/spearfish + false + file:data/sf + + <__default>false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/sf/restricted/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/sf/sf/restricted/featuretype.xml new file mode 100644 index 00000000000..879f8b97ea5 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/sf/restricted/featuretype.xml @@ -0,0 +1,83 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fc7 + restricted + restricted + + NamespaceInfoImpl--570ae188:124761b8d78:-8000 + + Spearfish restricted areas + Sample data from GRASS, restricted areas, Spearfish, South Dakota, USA + + spearfish + restricted + areas + sfRestricted + + PROJCS["NAD27 / UTM zone 13N", + GEOGCS["NAD27", + DATUM["North American Datum 1927", + SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], + TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], + AUTHORITY["EPSG","6267"]], + PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], + UNIT["degree", 0.017453292519943295], + AXIS["Geodetic longitude", EAST], + AXIS["Geodetic latitude", NORTH], + AUTHORITY["EPSG","4267"]], + PROJECTION["Transverse_Mercator"], + PARAMETER["central_meridian", -105.0], + PARAMETER["latitude_of_origin", 0.0], + PARAMETER["scale_factor", 0.9996], + PARAMETER["false_easting", 500000.0], + PARAMETER["false_northing", 0.0], + UNIT["m", 1.0], + AXIS["Easting", EAST], + AXIS["Northing", NORTH], + AUTHORITY["EPSG","26713"]] + EPSG:26713 + + 591579.1858092896 + 599648.9251686076 + 4916236.662227167 + 4925872.146218054 + EPSG:26713 + + + -103.85057172920756 + -103.74741494853805 + 44.39436387625042 + 44.48215752041131 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + sfRestricted_restricted + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fdb + + 0 + 0 + + + the_geom + 0 + 1 + false + + + cat + 0 + 1 + false + + + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/sf/restricted/layer.xml b/build/cite/ogcapi-features10/release/workspaces/sf/sf/restricted/layer.xml new file mode 100644 index 00000000000..c48d735be79 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/sf/restricted/layer.xml @@ -0,0 +1,22 @@ + + restricted + LayerInfoImpl--570ae188:124761b8d78:-7fc6 + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7fed + + + + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fc7 + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/sf/roads/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/sf/sf/roads/featuretype.xml new file mode 100644 index 00000000000..48a2428fb77 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/sf/roads/featuretype.xml @@ -0,0 +1,88 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fc5 + roads + roads + + NamespaceInfoImpl--570ae188:124761b8d78:-8000 + + Spearfish roads + Sample data from GRASS, road layout, Spearfish, South Dakota, USA + + sfRoads + spearfish + roads + + PROJCS["NAD27 / UTM zone 13N", + GEOGCS["NAD27", + DATUM["North American Datum 1927", + SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], + TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], + AUTHORITY["EPSG","6267"]], + PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], + UNIT["degree", 0.017453292519943295], + AXIS["Geodetic longitude", EAST], + AXIS["Geodetic latitude", NORTH], + AUTHORITY["EPSG","4267"]], + PROJECTION["Transverse_Mercator"], + PARAMETER["central_meridian", -105.0], + PARAMETER["latitude_of_origin", 0.0], + PARAMETER["scale_factor", 0.9996], + PARAMETER["false_easting", 500000.0], + PARAMETER["false_northing", 0.0], + UNIT["m", 1.0], + AXIS["Easting", EAST], + AXIS["Northing", NORTH], + AUTHORITY["EPSG","26713"]] + EPSG:26713 + + 589434.8564686741 + 609527.2102150217 + 4914006.337837095 + 4928063.398014731 + EPSG:26713 + + + -103.87741691493184 + -103.62231404880659 + 44.37087275281798 + 44.50015918338962 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + sfRoads_roads + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fdb + + 0 + 0 + + + the_geom + 0 + 1 + false + + + cat + 0 + 1 + false + + + label + 0 + 1 + false + + + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/sf/roads/layer.xml b/build/cite/ogcapi-features10/release/workspaces/sf/sf/roads/layer.xml new file mode 100644 index 00000000000..1c472813f18 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/sf/roads/layer.xml @@ -0,0 +1,22 @@ + + roads + LayerInfoImpl--570ae188:124761b8d78:-7fc4 + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7fe8 + + + + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fc5 + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/sf/streams/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/sf/sf/streams/featuretype.xml new file mode 100644 index 00000000000..2234e533fbf --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/sf/streams/featuretype.xml @@ -0,0 +1,88 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fc3 + streams + streams + + NamespaceInfoImpl--570ae188:124761b8d78:-8000 + + Spearfish streams + Sample data from GRASS, streams, Spearfish, South Dakota, USA + + spearfish + sfStreams + streams + + PROJCS["NAD27 / UTM zone 13N", + GEOGCS["NAD27", + DATUM["North American Datum 1927", + SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], + TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], + AUTHORITY["EPSG","6267"]], + PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], + UNIT["degree", 0.017453292519943295], + AXIS["Geodetic longitude", EAST], + AXIS["Geodetic latitude", NORTH], + AUTHORITY["EPSG","4267"]], + PROJECTION["Transverse_Mercator"], + PARAMETER["central_meridian", -105.0], + PARAMETER["latitude_of_origin", 0.0], + PARAMETER["scale_factor", 0.9996], + PARAMETER["false_easting", 500000.0], + PARAMETER["false_northing", 0.0], + UNIT["m", 1.0], + AXIS["Easting", EAST], + AXIS["Northing", NORTH], + AUTHORITY["EPSG","26713"]] + EPSG:26713 + + 589434.4971235897 + 609518.2117427464 + 4913947.342298816 + 4928071.049965891 + EPSG:26713 + + + -103.87789019829768 + -103.62287788915457 + 44.372335260095554 + 44.502218486214815 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + sfStreams_streams + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fdb + + 0 + 0 + + + the_geom + 0 + 1 + false + + + cat + 0 + 1 + false + + + label + 0 + 1 + false + + + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/sf/streams/layer.xml b/build/cite/ogcapi-features10/release/workspaces/sf/sf/streams/layer.xml new file mode 100644 index 00000000000..2b513b61c4d --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/sf/streams/layer.xml @@ -0,0 +1,22 @@ + + streams + LayerInfoImpl--570ae188:124761b8d78:-7fc2 + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7fef + + + + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fc3 + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/sf/workspace.xml b/build/cite/ogcapi-features10/release/workspaces/sf/workspace.xml new file mode 100644 index 00000000000..1195519b286 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/sf/workspace.xml @@ -0,0 +1,4 @@ + + WorkspaceInfoImpl--570ae188:124761b8d78:-7fff + sf + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/tiger/namespace.xml b/build/cite/ogcapi-features10/release/workspaces/tiger/namespace.xml new file mode 100644 index 00000000000..d02b61ffc22 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/tiger/namespace.xml @@ -0,0 +1,5 @@ + + NamespaceInfoImpl--570ae188:124761b8d78:-7ff6 + tiger + http://www.census.gov + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/datastore.xml b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/datastore.xml new file mode 100644 index 00000000000..c461e775304 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/datastore.xml @@ -0,0 +1,17 @@ + + DataStoreInfoImpl--570ae188:124761b8d78:-7fda + nyc + Topologically Integrated Geographic Encoding and Referencing (TIGER) dataset + true + + WorkspaceInfoImpl--570ae188:124761b8d78:-7ff5 + + + false + false + http://www.census.gov + false + file:data/nyc + + <__default>false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/giant_polygon/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/giant_polygon/featuretype.xml new file mode 100644 index 00000000000..a4574bf6b2a --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/giant_polygon/featuretype.xml @@ -0,0 +1,61 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fd3 + giant_polygon + giant_polygon + + NamespaceInfoImpl--570ae188:124761b8d78:-7ff6 + + World rectangle + A simple rectangular polygon covering most of the world, it's only used for the purpose of providing a background (WMS bgcolor could be used instead) + + DS_giant_polygon + giant_polygon + + GEOGCS["GCS_WGS_1984", + DATUM["WGS_1984", + SPHEROID["WGS_1984", 6378137.0, 298.257223563]], + PRIMEM["Greenwich", 0.0], + UNIT["degree", 0.017453292519943295], + AXIS["Longitude", EAST], + AXIS["Latitude", NORTH]] + EPSG:4326 + + -180.0 + 180.0 + -90.0 + 90.0 + EPSG:4326 + + + -180.0 + 180.0 + -90.0 + 90.0 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + DS_giant_polygon_giant_polygon + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fda + + 0 + 0 + + + the_geom + 0 + 1 + false + + + false + false + false + diff --git a/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/giant_polygon/layer.xml b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/giant_polygon/layer.xml new file mode 100644 index 00000000000..e6be7cb8098 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/giant_polygon/layer.xml @@ -0,0 +1,17 @@ + + giant_polygon + LayerInfoImpl--570ae188:124761b8d78:-7fd2 + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7ff1 + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fd3 + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/poi/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/poi/featuretype.xml new file mode 100644 index 00000000000..0f7a247a8d1 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/poi/featuretype.xml @@ -0,0 +1,81 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fd1 + poi + poi + + NamespaceInfoImpl--570ae188:124761b8d78:-7ff6 + + Manhattan (NY) points of interest + Points of interest in New York, New York (on Manhattan). One of the attributes contains the name of a file with a picture of the point of interest. + + poi + Manhattan + DS_poi + points_of_interest + + GEOGCS["GCS_WGS_1984", + DATUM["WGS_1984", + SPHEROID["WGS_1984", 6378137.0, 298.257223563]], + PRIMEM["Greenwich", 0.0], + UNIT["degree", 0.017453292519943295], + AXIS["Longitude", EAST], + AXIS["Latitude", NORTH]] + EPSG:4326 + + -74.0118315772888 + -74.00153046439813 + 40.70754683896324 + 40.719885123828675 + EPSG:4326 + + + -74.0118315772888 + -74.00857344353275 + 40.70754683896324 + 40.711945649065406 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + DS_poi_poi + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fda + + 0 + 0 + + + the_geom + 0 + 1 + false + + + NAME + 0 + 1 + false + + + THUMBNAIL + 0 + 1 + false + + + MAINPAGE + 0 + 1 + false + + + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/poi/layer.xml b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/poi/layer.xml new file mode 100644 index 00000000000..e7120290539 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/poi/layer.xml @@ -0,0 +1,25 @@ + + poi + LayerInfoImpl--570ae188:124761b8d78:-7fd0 + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7fde + + + + + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fd1 + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/poly_landmarks/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/poly_landmarks/featuretype.xml new file mode 100644 index 00000000000..d6d574a0ec3 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/poly_landmarks/featuretype.xml @@ -0,0 +1,81 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fcf + poly_landmarks + poly_landmarks + + NamespaceInfoImpl--570ae188:124761b8d78:-7ff6 + + Manhattan (NY) landmarks + Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs + + landmarks + DS_poly_landmarks + manhattan + poly_landmarks + + GEOGCS["GCS_WGS_1984", + DATUM["WGS_1984", + SPHEROID["WGS_1984", 6378137.0, 298.257223563]], + PRIMEM["Greenwich", 0.0], + UNIT["degree", 0.017453292519943295], + AXIS["Longitude", EAST], + AXIS["Latitude", NORTH]] + EPSG:4326 + + -74.047185 + -73.90782 + 40.679648 + 40.882078 + EPSG:4326 + + + -74.047185 + -73.90782 + 40.679648 + 40.882078 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + DS_poly_landmarks_poly_landmarks + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fda + + 0 + 0 + + + the_geom + 0 + 1 + false + + + LAND + 0 + 1 + false + + + CFCC + 0 + 1 + false + + + LANAME + 0 + 1 + false + + + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/poly_landmarks/layer.xml b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/poly_landmarks/layer.xml new file mode 100644 index 00000000000..f2e5091dda1 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/poly_landmarks/layer.xml @@ -0,0 +1,28 @@ + + poly_landmarks + LayerInfoImpl--570ae188:124761b8d78:-7fce + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7feb + + + + + + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fcf + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/tiger_roads/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/tiger_roads/featuretype.xml new file mode 100644 index 00000000000..6e88ab6bfcd --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/tiger_roads/featuretype.xml @@ -0,0 +1,74 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fcd + tiger_roads + tiger_roads + + NamespaceInfoImpl--570ae188:124761b8d78:-7ff6 + + Manhattan (NY) roads + Highly simplified road layout of Manhattan in New York.. + + DS_tiger_roads + tiger_roads + roads + + GEOGCS["GCS_WGS_1984", + DATUM["WGS_1984", + SPHEROID["WGS_1984", 6378137.0, 298.257223563]], + PRIMEM["Greenwich", 0.0], + UNIT["degree", 0.017453292519943295], + AXIS["Longitude", EAST], + AXIS["Latitude", NORTH]] + EPSG:4326 + + -74.02722 + -73.907005 + 40.684221 + 40.878178 + EPSG:4326 + + + -74.02722 + -73.907005 + 40.684221 + 40.878178 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + DS_tiger_roads_tiger_roads + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fda + + 0 + 0 + + + the_geom + 0 + 1 + false + + + CFCC + 0 + 1 + false + + + NAME + 0 + 1 + false + + + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/tiger_roads/layer.xml b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/tiger_roads/layer.xml new file mode 100644 index 00000000000..0f862c09027 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/tiger/nyc/tiger_roads/layer.xml @@ -0,0 +1,25 @@ + + tiger_roads + LayerInfoImpl--570ae188:124761b8d78:-7fcc + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7fec + + + + + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fcd + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/tiger/workspace.xml b/build/cite/ogcapi-features10/release/workspaces/tiger/workspace.xml new file mode 100644 index 00000000000..0aac5249c43 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/tiger/workspace.xml @@ -0,0 +1,4 @@ + + WorkspaceInfoImpl--570ae188:124761b8d78:-7ff5 + tiger + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/namespace.xml b/build/cite/ogcapi-features10/release/workspaces/topp/namespace.xml new file mode 100644 index 00000000000..bd95e44758b --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/namespace.xml @@ -0,0 +1,5 @@ + + NamespaceInfoImpl--570ae188:124761b8d78:-7ffe + topp + http://www.openplans.org/topp + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/datastore.xml b/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/datastore.xml new file mode 100644 index 00000000000..bdc5b68851b --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/datastore.xml @@ -0,0 +1,12 @@ + + DataStoreInfoImpl--570ae188:124761b8d78:-7fd9 + states_shapefile + true + + WorkspaceInfoImpl--570ae188:124761b8d78:-7ffd + + + http://www.openplans.org/topp + file:data/shapefiles/states.shp + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/states/description.ftl b/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/states/description.ftl new file mode 100644 index 00000000000..df9f8b57887 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/states/description.ftl @@ -0,0 +1,7 @@ +This is the state of ${STATE_NAME.value}. +${PERSONS.value} people live in an area of ${LAND_KM.value} square +kilometers, and only ${PUBTRANS.value} take public transportation. +
+
+ +Map by:
OpenGeo diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/states/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/states/featuretype.xml new file mode 100644 index 00000000000..df924506d26 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/states/featuretype.xml @@ -0,0 +1,193 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fc1 + states + states + + NamespaceInfoImpl--570ae188:124761b8d78:-7ffe + + USA Population + This is some census data on the states. + + census + united + boundaries + state + states + + GEOGCS["GCS_WGS_1984", + DATUM["WGS_1984", + SPHEROID["WGS_1984", 6378137.0, 298.257223563]], + PRIMEM["Greenwich", 0.0], + UNIT["degree", 0.017453292519943295], + AXIS["Longitude", EAST], + AXIS["Latitude", NORTH]] + EPSG:4326 + + -124.73142200000001 + -66.969849 + 24.955967 + 49.371735 + EPSG:4326 + + + -124.731422 + -66.969849 + 24.955967 + 49.371735 + EPSG:4326 + + FORCE_DECLARED + true + + 3600 + 10 + false + true + states + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fd9 + + + + the_geom + 0 + 1 + false + + + STATE_NAME + 0 + 1 + false + + + STATE_FIPS + 0 + 1 + false + + + SUB_REGION + 0 + 1 + false + + + STATE_ABBR + 0 + 1 + false + + + LAND_KM + 0 + 1 + false + + + WATER_KM + 0 + 1 + false + + + PERSONS + 0 + 1 + false + + + FAMILIES + 0 + 1 + false + + + HOUSHOLD + 0 + 1 + false + + + MALE + 0 + 1 + false + + + FEMALE + 0 + 1 + false + + + WORKERS + 0 + 1 + false + + + DRVALONE + 0 + 1 + false + + + CARPOOL + 0 + 1 + false + + + PUBTRANS + 0 + 1 + false + + + EMPLOYED + 0 + 1 + false + + + UNEMPLOY + 0 + 1 + false + + + SERVICE + 0 + 1 + false + + + MANUAL + 0 + 1 + false + + + P_MALE + 0 + 1 + false + + + P_FEMALE + 0 + 1 + false + + + SAMP_POP + 0 + 1 + false + + + 0 + 0 + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/states/layer.xml b/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/states/layer.xml new file mode 100644 index 00000000000..0b5526154e8 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/states/layer.xml @@ -0,0 +1,25 @@ + + states + LayerInfoImpl--570ae188:124761b8d78:-7fc0 + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7fe5 + + + + + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fc1 + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/states/title.ftl b/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/states/title.ftl new file mode 100644 index 00000000000..00cb89cb238 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/states_shapefile/states/title.ftl @@ -0,0 +1 @@ +${STATE_NAME.value} diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/datastore.xml b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/datastore.xml new file mode 100644 index 00000000000..82ed90c0151 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/datastore.xml @@ -0,0 +1,17 @@ + + DataStoreInfoImpl--570ae188:124761b8d78:-7fdc + taz_shapes + Tasmania vector data derived from Digital Chart of the World. + true + + WorkspaceInfoImpl--570ae188:124761b8d78:-7ffd + + + false + false + http://www.openplans.org/topp + false + file:data/taz_shapes + + <__default>false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_cities/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_cities/featuretype.xml new file mode 100644 index 00000000000..6f0786cf640 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_cities/featuretype.xml @@ -0,0 +1,91 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fbf + tasmania_cities + tasmania_cities + + NamespaceInfoImpl--570ae188:124761b8d78:-7ffe + + Tasmania cities + Cities in Tasmania (actually, just the capital) + + cities + Tasmania + + GEOGCS["GCS_WGS_1984", + DATUM["WGS_1984", + SPHEROID["WGS_1984", 6378137.0, 298.257223563]], + PRIMEM["Greenwich", 0.0], + UNIT["degree", 0.017453292519943295], + AXIS["Longitude", EAST], + AXIS["Latitude", NORTH]] + EPSG:4326 + + 145.19754 + 148.27298000000002 + -43.423512 + -40.852802 + EPSG:4326 + + + 145.19754 + 148.27298000000002 + -43.423512 + -40.852802 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + tasmania_cities + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fdc + + 0 + 0 + + + the_geom + 0 + 1 + false + + + CITY_NAME + 0 + 1 + false + + + ADMIN_NAME + 0 + 1 + false + + + CNTRY_NAME + 0 + 1 + false + + + STATUS + 0 + 1 + false + + + POP_CLASS + 0 + 1 + false + + + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_cities/layer.xml b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_cities/layer.xml new file mode 100644 index 00000000000..881159c9c57 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_cities/layer.xml @@ -0,0 +1,17 @@ + + tasmania_cities + LayerInfoImpl--570ae188:124761b8d78:-7fbe + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7ff0 + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fbf + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_roads/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_roads/featuretype.xml new file mode 100644 index 00000000000..f4a0c79ac7c --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_roads/featuretype.xml @@ -0,0 +1,67 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fbd + tasmania_roads + tasmania_roads + + NamespaceInfoImpl--570ae188:124761b8d78:-7ffe + + Tasmania roads + Main Tasmania roads + + Roads + Tasmania + + GEOGCS["GCS_WGS_1984", + DATUM["WGS_1984", + SPHEROID["WGS_1984", 6378137.0, 298.257223563]], + PRIMEM["Greenwich", 0.0], + UNIT["degree", 0.017453292519943295], + AXIS["Longitude", EAST], + AXIS["Latitude", NORTH]] + EPSG:4326 + + 145.19754 + 148.27298000000002 + -43.423512 + -40.852802 + EPSG:4326 + + + 145.19754 + 148.27298000000002 + -43.423512 + -40.852802 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + tasmania_roads + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fdc + + 0 + 0 + + + the_geom + 0 + 1 + false + + + TYPE + 0 + 1 + false + + + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_roads/layer.xml b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_roads/layer.xml new file mode 100644 index 00000000000..c082c49bc21 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_roads/layer.xml @@ -0,0 +1,17 @@ + + tasmania_roads + LayerInfoImpl--570ae188:124761b8d78:-7fbc + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7fe8 + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fbd + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_state_boundaries/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_state_boundaries/featuretype.xml new file mode 100644 index 00000000000..b5f894dd3ca --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_state_boundaries/featuretype.xml @@ -0,0 +1,86 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fbb + tasmania_state_boundaries + tasmania_state_boundaries + + NamespaceInfoImpl--570ae188:124761b8d78:-7ffe + + Tasmania state boundaries + Tasmania state boundaries + + boundaries + tasmania_state_boundaries + Tasmania + + GEOGCS["GCS_WGS_1984", + DATUM["WGS_1984", + SPHEROID["WGS_1984", 6378137.0, 298.257223563]], + PRIMEM["Greenwich", 0.0], + UNIT["degree", 0.017453292519943295], + AXIS["Longitude", EAST], + AXIS["Latitude", NORTH]] + EPSG:4326 + + 143.83482400000003 + 148.47914100000003 + -43.648056 + -39.573891 + EPSG:4326 + + + 143.83482400000003 + 148.47914100000003 + -43.648056 + -39.573891 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + tasmania_state_boundaries + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fdc + + 0 + 0 + + + the_geom + 0 + 1 + false + + + STATE + 0 + 1 + false + + + COUNTRY + 0 + 1 + false + + + CURR_TYPE + 0 + 1 + false + + + CURR_CODE + 0 + 1 + false + + + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_state_boundaries/layer.xml b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_state_boundaries/layer.xml new file mode 100644 index 00000000000..2fbe65d6e84 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_state_boundaries/layer.xml @@ -0,0 +1,17 @@ + + tasmania_state_boundaries + LayerInfoImpl--570ae188:124761b8d78:-7fba + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7fea + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fbb + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_water_bodies/featuretype.xml b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_water_bodies/featuretype.xml new file mode 100644 index 00000000000..2f0bd3bea10 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_water_bodies/featuretype.xml @@ -0,0 +1,94 @@ + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fb9 + tasmania_water_bodies + tasmania_water_bodies + + NamespaceInfoImpl--570ae188:124761b8d78:-7ffe + + Tasmania water bodies + Tasmania water bodies + + Lakes + Bodies + Australia + Water + Tasmania + + GEOGCS["GCS_WGS_1984", + DATUM["WGS_1984", + SPHEROID["WGS_1984", 6378137.0, 298.257223563]], + PRIMEM["Greenwich", 0.0], + UNIT["degree", 0.017453292519943295], + AXIS["Longitude", EAST], + AXIS["Latitude", NORTH]] + EPSG:4326 + + 145.97161899999998 + 147.219696 + -43.031944 + -41.775558 + EPSG:4326 + + + 145.97161899999998 + 147.219696 + -43.031944 + -41.775558 + EPSG:4326 + + FORCE_DECLARED + true + + 10 + 3600 + true + false + tasmania_water_bodies + + + DataStoreInfoImpl--570ae188:124761b8d78:-7fdc + + 0 + 0 + + + the_geom + 0 + 1 + false + + + AREA + 0 + 1 + false + + + PERIMETER + 0 + 1 + false + + + WATER_TYPE + 0 + 1 + false + + + CNTRY_NAME + 0 + 1 + false + + + CONTINENT + 0 + 1 + false + + + false + false + false + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_water_bodies/layer.xml b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_water_bodies/layer.xml new file mode 100644 index 00000000000..1a11f128594 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/taz_shapes/tasmania_water_bodies/layer.xml @@ -0,0 +1,17 @@ + + tasmania_water_bodies + LayerInfoImpl--570ae188:124761b8d78:-7fb8 + / + VECTOR + + StyleInfoImpl--570ae188:124761b8d78:-7fdd + + + FeatureTypeInfoImpl--570ae188:124761b8d78:-7fb9 + + true + + 0 + 0 + + \ No newline at end of file diff --git a/build/cite/ogcapi-features10/release/workspaces/topp/workspace.xml b/build/cite/ogcapi-features10/release/workspaces/topp/workspace.xml new file mode 100644 index 00000000000..270560c98f3 --- /dev/null +++ b/build/cite/ogcapi-features10/release/workspaces/topp/workspace.xml @@ -0,0 +1,4 @@ + + WorkspaceInfoImpl--570ae188:124761b8d78:-7ffd + topp + \ No newline at end of file diff --git a/build/cite/postgres/postgres.env b/build/cite/postgres/postgres.env index a533a4103cc..425067f4e2f 100644 --- a/build/cite/postgres/postgres.env +++ b/build/cite/postgres/postgres.env @@ -1,3 +1,3 @@ -POSTGRES_USER=postgres -POSTGRES_PASSWORD=postgres -POSTGRES_DB=postgres +POSTGRES_USER=cite +POSTGRES_PASSWORD=cite +POSTGRES_DB=cite diff --git a/build/cite/run-test.sh b/build/cite/run-test.sh index c9af6d07f1f..e8b81a103d7 100755 --- a/build/cite/run-test.sh +++ b/build/cite/run-test.sh @@ -3,61 +3,64 @@ # fail on error # set -e -TE_LOG_DIR="$TE_BASE/users/teamengine" -TE_FORMS_DIR="$TE_BASE/forms" +if [ -d /home/teamengine/te_base/bin/unix/ ]; then + TE_LOG_DIR="$TE_BASE/users/teamengine" + TE_FORMS_DIR="$TE_BASE/forms" + + mkdir -p "$TE_FORMS_DIR" + + cd "/home/teamengine/te_base/bin/unix/" + + # test.sh comes from https://github.com/opengeospatial/teamengine/blob/master/teamengine-console/src/main/scripts/shell/unix/test.sh + # viewlog.sh comes from https://github.com/opengeospatial/teamengine/blob/master/teamengine-console/src/main/scripts/shell/unix/viewlog.sh + + _show_logs() { + ./viewlog.sh \ + -logdir="$TE_LOG_DIR" \ + -session=s0001 + } + + set -o pipefail + _parse_logs(){ + _show_logs | grep -iw "Failed" + local grep_exit_code=$? + if [ "$grep_exit_code" -eq "0" ]; then + echo "Failed tests found in logs! (grep exit code: $grep_exit_code)" >&2 + return 3 + else + echo "No Failed tests found in logs" >&2 + return 0 + fi + } + + _run() { + ./test.sh \ + -source="$source" \ + -form="$form" + local rc=$? + if [ "$rc" -ne "0" ]; then + echo "test.sh failed!" >&2 + rc=10 + fi + + _show_logs + if [ "$?" -ne "0" ]; then + echo "viewlog.sh failed, I cannot tell if the tests failed or not." >&2 + return 20 + fi + + _parse_logs + if [ "$?" -ne "0" ]; then + echo "The log shows a failed test!" >&2 + rc=3 + fi + + return $rc + } + set +o pipefail + +fi; -mkdir -p "$TE_FORMS_DIR" - -cd "/home/teamengine/te_base/bin/unix/" - - -# test.sh comes from https://github.com/opengeospatial/teamengine/blob/master/teamengine-console/src/main/scripts/shell/unix/test.sh -# viewlog.sh comes from https://github.com/opengeospatial/teamengine/blob/master/teamengine-console/src/main/scripts/shell/unix/viewlog.sh - -_show_logs() { - ./viewlog.sh \ - -logdir="$TE_LOG_DIR" \ - -session=s0001 -} - -set -o pipefail -_parse_logs(){ - _show_logs | grep -iw "Failed" - local grep_exit_code=$? - if [ "$grep_exit_code" -eq "0" ]; then - echo "Failed tests found in logs! (grep exit code: $grep_exit_code)" >&2 - return 3 - else - echo "No Failed tests found in logs" >&2 - return 0 - fi -} - -_run() { - ./test.sh \ - -source="$source" \ - -form="$form" - local rc=$? - if [ "$rc" -ne "0" ]; then - echo "test.sh failed!" >&2 - rc=10 - fi - - _show_logs - if [ "$?" -ne "0" ]; then - echo "viewlog.sh failed, I cannot tell if the tests failed or not." >&2 - return 20 - fi - - _parse_logs - if [ "$?" -ne "0" ]; then - echo "The log shows a failed test!" >&2 - rc=3 - fi - - return $rc -} -set +o pipefail wms11 () { echo $0 @@ -101,6 +104,89 @@ wcs11 () { _run } +ogcapi-features10() { + echo $0 + + teamenginehost=$(hostname) + apiurl="http://$teamenginehost:8080/teamengine/rest/suites/ogcapi-features-1.0/run" + iut="http://geoserver:8080/geoserver/ogc/features/v1" + testurl="$apiurl?noofcollections=-1&iut=$iut" + credentials="ogctest:ogctest" + targetfile="/logs/testng-results.xml" + + echo + echo Running tests + echo api URL: $apiurl + echo iut: $iut + echo Will save the XML report to $targetfile + echo This may take a while... + # if requesting application/zip, ogccite/teamengine-production will include both the html and xml results, + # but ogccite/ets-ogcapi-features10 won't. + + # requesting application/xml as it's the one we can parse to fail the build if there are test failures + curl -v -s -u "$credentials" "$testurl" -H "Accept: application/xml" > $targetfile + # Check if the first curl command failed + if [ $? -ne 0 ]; then + echo "Error: Failed to run tests" + exit 1 + fi +} + + +# Usage: +# ogcapi-features10([iut]) +# - iut: optional. URL of landing page. Defaults to 'default_iut="http://geoserver:8080/geoserver/ogc/features/v1' +ogcapi-features10() { + # Define the default Instance Under Test + default_iut="http://geoserver:8080/geoserver/ogc/features/v1" + + # Use provided argument if given, otherwise use the default value + iut="${1:-$default_iut}" + + # Call the generic function with iut as the first argument and default values for the others + run_rest_test 'ogcapi-features-1.0' "$iut" +} + +# Usage: +# run_rest_test(suitename iut) +# - suitename: name of the test suite to run (e.g. 'ogcapi-features-1.0') +# - iut: URL of the Instance Under Test's landing page or GetCapabilities document +run_rest_test() { + + local suitename="${1}" + local iut="${2}" + + local teamenginehost=$(hostname) + + # Check if required arguments are provided + if [ -z "$suitename" ] || [ -z "$iut" ]; then + echo "run-rest-test()> Invalid arguments. Expected run-rest-test(suitename, iut)" + echo "suitename: name of the test suite to run (e.g., 'ogcapi-features-1.0')" + echo "iut: URL of the Instance Under Test's landing page or GetCapabilities document" + exit 1 + fi + + apiurl="http://$teamenginehost:8080/teamengine/rest/suites/$suitename/run" + testurl="$apiurl?noofcollections=-1&iut=$iut" + credentials="ogctest:ogctest" + targetfile="/logs/testng-results.xml" + + echo + echo Running tests + echo api URL: $apiurl + echo iut: $iut + echo Will save the XML report to $targetfile + echo This may take a while... + + # Requesting application/xml as it's the one we can parse to fail the build if there are test failures + curl -v -s -u "$credentials" "$testurl" -H "Accept: application/xml" > $targetfile + # Check if the curl command failed + if [ $? -ne 0 ]; then + echo "Error: Failed to run tests" + exit 1 + fi +} + interactive () { /usr/local/tomcat/bin/startup.sh while true; do sleep 100000; done diff --git a/build/cite/testng-results-full-error-report.sh b/build/cite/testng-results-full-error-report.sh new file mode 100755 index 00000000000..fa281598960 --- /dev/null +++ b/build/cite/testng-results-full-error-report.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +# This script processes a TestNG results XML file to print the full contents of +# elements with status="FAIL". It checks if 'xmlstarlet' is installed; +# if not, it prompts the user to install it. +# If 'bat' is available, the output is piped to 'bat' with XML syntax highlighting. +# If no failed tests are found, it prints a message indicating this. + +# Check if xmlstarlet is installed +if ! command -v xmlstarlet &> /dev/null; then + echo "xmlstarlet is not available. Please install it to process the XML file." + exit 1 +fi + +# File to process (assumed as argument) +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +file="$1" +if [ ! -f "$file" ]; then + echo "Error: File '$file' not found!" + exit 1 +fi + +# Count the number of failed test-method elements +num_failed=$(xmlstarlet sel -t -v "count(//test-method[@status='FAIL'])" "$file") + +if [ "$num_failed" -eq 0 ]; then + echo "No failed tests found in $file" + exit 0 +fi + +# Use xmlstarlet to find and print the full contents of failed test-method elements +echo "Full Contents of Failed Test Methods:" +echo "-------------------------------------" + +output=$(xmlstarlet sel -t \ + -m "//test-method[@status='FAIL']" \ + -c . -n \ + "$file") + +# Check if 'batcat' or 'bat' is installed +# On linux it's now batcat, bat would install something different +# On macos brew install bat would do +if command -v batcat &> /dev/null; then + echo "$output" | batcat --language=xml --theme=Coldark-Dark #--paging=never +elif command -v bat &> /dev/null; then + echo "$output" | bat --language=xml --theme=Coldark-Dark #--paging=never +else + echo "$output" +fi \ No newline at end of file diff --git a/build/cite/testng-results-report.sh b/build/cite/testng-results-report.sh new file mode 100755 index 00000000000..342b2c408d3 --- /dev/null +++ b/build/cite/testng-results-report.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# This script processes a TestNG results XML file to generate a report of failed tests. +# It checks if 'xmlstarlet' is installed; if not, it prompts the user to install it. +# If 'xmlstarlet' is available, the script extracts all elements with +# status="FAIL" and prints a formatted report to the console, including the test method name, +# description, dependent groups, status, and any associated exception text. +# Leading and trailing whitespace is removed from the exception text. +# If no failed tests are found, it prints a message indicating this. + +# Check if xmlstarlet is installed +if ! command -v xmlstarlet &> /dev/null; then + echo "xmlstarlet is not available. Please install it to get a report of test failures." + exit 1 +fi + +# File to process (assumed as argument) +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +file="$1" +if [ ! -f "$file" ]; then + echo "Error: File '$file' not found!" + exit 1 +fi + +# Count the number of failed test-method elements +num_failed=$(xmlstarlet sel -t -v "count(//test-method[@status='FAIL'])" "$file") + +if [ "$num_failed" -eq 0 ]; then + echo "No failed tests found in $file" + exit 0 +fi + +# Use xmlstarlet to find and print failed test methods +echo "Report of Failed Test Methods:" +echo "------------------------------" + +xmlstarlet sel -t \ + -m "//test-method[@status='FAIL']" \ + -v "concat('test-method: ', @name)" -n \ + -v "concat('description: ', @description)" -n \ + -v "concat('depends-on-groups: ', @depends-on-groups)" -n \ + -v "concat('status: ', @status)" -n \ + -o "exception: " \ + -m "exception" \ + -v "normalize-space(.)" -b -n \ + -o "Request URI: " \ + -m "attributes/attribute[@name='request']" \ + -v "normalize-space(substring-after(., 'Request URI:'))" -b -n \ + -n \ + "$file" \ No newline at end of file diff --git a/build/cite/testng-results-validate.sh b/build/cite/testng-results-validate.sh new file mode 100755 index 00000000000..ed7701fb735 --- /dev/null +++ b/build/cite/testng-results-validate.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# This script reads a testNG results XML file with a root element like: +# +# It extracts the number of passed, failed, and skipped tests, and prints +# the results with ANSI colors: green for passed, red for failed, and no color for skipped. +# If there are any failed tests (failed > 0), the script exits with a status code of 1. +# +# This script is used in the Makefile to fail the test run if there are failures, since +# when using the teamengine REST API to produce the xml report, it will always return a 200 HTTP status code. +# +# Contrary to testng-results-report.sh, this script does not require xmlstarlet to be installed, +# and can be used to fail the build if there are test failures rergardless of whether a detailed +# report can be printed out. + + +# Check if a filename is provided +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +# Read the XML file +file="$1" +if [ ! -f "$file" ]; then + echo "Error: File '$file' not found!" + exit 1 +fi + +# Extract the values using sed +skipped=$(sed -n 's/.*skipped="\([0-9]*\)".*/\1/p' "$file") +failed=$(sed -n 's/.*failed="\([0-9]*\)".*/\1/p' "$file") +passed=$(sed -n 's/.*passed="\([0-9]*\)".*/\1/p' "$file") + +# ANSI escape sequences for colors +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' # No Color + +# Print the results +echo -e "Passed: ${GREEN}${passed}${NC}" +echo -e "Failed: ${RED}${failed}${NC}" +echo -e "Skipped: ${skipped}" + +# Exit with status 1 if there are any failed tests +if [ "$failed" -gt 0 ]; then + exit 1 +fi diff --git a/build/cite/wcs10/docker-compose.override.yml b/build/cite/wcs10/compose.override.yml similarity index 94% rename from build/cite/wcs10/docker-compose.override.yml rename to build/cite/wcs10/compose.override.yml index 23f6d568eb8..2a3ae0f50e2 100644 --- a/build/cite/wcs10/docker-compose.override.yml +++ b/build/cite/wcs10/compose.override.yml @@ -1,5 +1,3 @@ -version: '3.0' - services: geoserver: image: ogccite/geoserver:wcs10 diff --git a/build/cite/wcs11/docker-compose.override.yml b/build/cite/wcs11/compose.override.yml similarity index 94% rename from build/cite/wcs11/docker-compose.override.yml rename to build/cite/wcs11/compose.override.yml index 8af1e177e03..1603e719644 100644 --- a/build/cite/wcs11/docker-compose.override.yml +++ b/build/cite/wcs11/compose.override.yml @@ -1,5 +1,3 @@ -version: '3.0' - services: geoserver: image: ogccite/geoserver:wcs11 diff --git a/build/cite/wfs10/01-init-user.sh b/build/cite/wfs10/01-init-user.sh index 4b47e870d4e..abe80093f53 100644 --- a/build/cite/wfs10/01-init-user.sh +++ b/build/cite/wfs10/01-init-user.sh @@ -2,7 +2,12 @@ set -e psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - CREATE USER cite; + CREATE USER cite PASSWORD 'cite'; CREATE DATABASE cite; GRANT ALL PRIVILEGES ON DATABASE cite TO cite; EOSQL + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "cite" <<-EOSQL + CREATE EXTENSION postgis; + GRANT ALL PRIVILEGES ON SCHEMA public TO cite; +EOSQL diff --git a/build/cite/wfs10/02-init-db.sql.gz b/build/cite/wfs10/02-init-db.sql.gz deleted file mode 100644 index cd49c7b7bb9..00000000000 Binary files a/build/cite/wfs10/02-init-db.sql.gz and /dev/null differ diff --git a/build/cite/wfs10/citewfs-1.0/README.txt b/build/cite/wfs10/citewfs-1.0/README.txt index 2a6f29d704d..c0db3289aef 100644 --- a/build/cite/wfs10/citewfs-1.0/README.txt +++ b/build/cite/wfs10/citewfs-1.0/README.txt @@ -5,7 +5,7 @@ Here's the summary: 1. get postgis 1.0, make a "cite" super-user 2. run "dropdb cite -U cite" to delete the database (always do this before you run!) 3. run the postgis double-click install and create a "cite" database -4. run "psql -f cite_data.sql cite -U cite" +4. run "psql -f cite_data_postgis2.sql cite -U cite" 5. set the build.properties file so it has the line "test.type=citeWFSPostGIS" 6. run geoserver 7. setup and run a cite test http://cite.occamlab.com/tsOGC/interface/MainMenu diff --git a/build/cite/wfs10/citewfs-1.0/cite_data.sql b/build/cite/wfs10/citewfs-1.0/cite_data.sql deleted file mode 100644 index 4b9a3bb54da..00000000000 --- a/build/cite/wfs10/citewfs-1.0/cite_data.sql +++ /dev/null @@ -1,602 +0,0 @@ --- This file inserts all the appropriate cite data into postgis to run with --- geoserver. To work with the tar file of featureType directories it --- should be run in a database called cite, that either has a user with --- a password of cite, cite, or that allows anyone read/write access. --- You can also just run this script in whatever database you like with --- your user name, but then you have to modify all the user access info --- of the info.xml files. Uncommenting lines at 253 will create the cite --- user and grant access to it on all the relavant tables, the user you are --- connecting with must have the appropriate permissions to do that. - - --- Uncomment and change this to the user who has permissions to drop and --- create tables in this db. --- \connect - cite - - - - ---uncomment these if you want to reset everything. -drop table "Nulls"; -drop table "Points"; -drop table "Other"; -drop table "Lines"; -drop table "Polygons"; -drop table "MLines"; -drop table "MPolygons"; -drop table "MPoints"; -drop table "Seven"; -drop table "Fifteen"; -drop table "Updates"; -drop table "Inserts"; -drop table "Deletes"; -drop table "Locks"; -delete from "geometry_columns" where srid=32615; - - - - --- --- TOC Entry ID 23 (OID 312261) --- --- Name: SevenFeature Type: TABLE Owner: ciesin --- - -CREATE TABLE "Seven" ( - "boundedBy" geometry, - "pointProperty" geometry, - CHECK ((srid("pointProperty") = 32615)), - CHECK (((geometrytype("pointProperty") = 'POINT'::text) OR ("pointProperty" IS NULL))), - CHECK ((srid("boundedBy") = 32615)), - CHECK (((geometrytype("boundedBy") = 'POLYGON'::text) OR ("boundedBy" IS NULL))) -) WITH OIDS; - - --- --- TOC Entry ID 24 (OID 312275) --- --- Name: NullFeature Type: TABLE Owner: cite --- - -CREATE TABLE "Nulls" ( - "description" character varying, - "name" character varying, - "boundedBy" geometry, - "integers" integer, - "dates" date, - "pointProperty" geometry, - CHECK ((srid("pointProperty") = 32615)), - CHECK (((geometrytype("pointProperty") = 'POINT'::text) OR ("pointProperty" IS NULL))), - CHECK ((srid("boundedBy") = 32615)), - CHECK (((geometrytype("boundedBy") = 'POLYGON'::text) OR ("boundedBy" IS NULL))) -) WITH OIDS; - --- --- TOC Entry ID 25 (OID 312300) --- --- Name: DeleteFeature Type: TABLE Owner: cite --- - -CREATE TABLE "Deletes" ( - "boundedBy" geometry, - "id" character varying, - "pointProperty" geometry, - CHECK ((srid("pointProperty") = 32615)), - CHECK (((geometrytype("pointProperty") = 'POINT'::text) OR ("pointProperty" IS NULL))), - CHECK ((srid("boundedBy") = 32615)), - CHECK (((geometrytype("boundedBy") = 'POLYGON'::text) OR ("boundedBy" IS NULL))) - -) WITH OIDS; - --- --- TOC Entry ID 26 (OID 312305) --- --- Name: InsertFeature Type: TABLE Owner: cite --- - -CREATE TABLE "Inserts" ( - "boundedBy" geometry, - "id" character varying, - "pointProperty" geometry, - CHECK ((srid("pointProperty") = 32615)), - CHECK (((geometrytype("pointProperty") = 'POINT'::text) OR ("pointProperty" IS NULL))), - CHECK ((srid("boundedBy") = 32615)), - CHECK (((geometrytype("boundedBy") = 'POLYGON'::text) OR ("boundedBy" IS NULL))) -) WITH OIDS; - - --- --- TOC Entry ID 27 (OID 312310) --- --- Name: UpdateFeature Type: TABLE Owner: cite --- - -CREATE TABLE "Updates" ( - "boundedBy" geometry, - "id" character varying, - "pointProperty" geometry, - CHECK ((srid("pointProperty") = 32615)), - CHECK (((geometrytype("pointProperty") = 'POINT'::text) OR ("pointProperty" IS NULL))), - CHECK ((srid("boundedBy") = 32615)), - CHECK (((geometrytype("boundedBy") = 'POLYGON'::text) OR ("boundedBy" IS NULL))) -) WITH OIDS; - --- --- TOC Entry ID 28 (OID 312315) --- --- Name: PointFeature Type: TABLE Owner: cite --- - -CREATE TABLE "Points" ( - "id" character varying, - "pointProperty" geometry, - CHECK ((srid("pointProperty") = 32615)), - CHECK (((geometrytype("pointProperty") = 'POINT'::text) OR ("pointProperty" IS NULL))) -) WITH OIDS; - --- --- TOC Entry ID 29 (OID 312322) --- --- Name: LineStringFeature Type: TABLE Owner: cite --- - -CREATE TABLE "Lines" ( - "id" character varying, - "lineStringProperty" geometry, - CHECK ((srid("lineStringProperty") = 32615)), - CHECK (((geometrytype("lineStringProperty") = 'LINESTRING'::text) OR ("lineStringProperty" IS NULL))) -) WITH OIDS; - --- --- TOC Entry ID 30 (OID 312329) --- --- Name: PolygonFeature Type: TABLE Owner: cite --- - -CREATE TABLE "Polygons" ( - "id" character varying, - "polygonProperty" geometry, - CHECK ((srid("polygonProperty") = 32615)), - CHECK (((geometrytype("polygonProperty") = 'POLYGON'::text) OR ("polygonProperty" IS NULL))) -) WITH OIDS; - --- --- TOC Entry ID 31 (OID 312335) --- --- Name: MultiPointFeature Type: TABLE Owner: cite --- - -CREATE TABLE "MPoints" ( - "id" character varying, - "multiPointProperty" geometry, - CHECK ((srid("multiPointProperty") = 32615)), - CHECK (((geometrytype("multiPointProperty") = 'MULTIPOINT'::text) OR ("multiPointProperty" IS NULL))) -) WITH OIDS; - --- --- TOC Entry ID 32 (OID 312341) --- --- Name: MultiLineStringFeature Type: TABLE Owner: cite --- - -CREATE TABLE "MLines" ( - "id" character varying, - "multiLineStringProperty" geometry, - CHECK ((srid("multiLineStringProperty") = 32615)), - CHECK (((geometrytype("multiLineStringProperty") = 'MULTILINESTRING'::text) OR ("multiLineStringProperty" IS NULL))) -) WITH OIDS; - --- --- TOC Entry ID 33 (OID 312348) --- --- Name: MultiPolygonFeature Type: TABLE Owner: cite --- - -CREATE TABLE "MPolygons" ( - "id" character varying, - "multiPolygonProperty" geometry, - CHECK ((srid("multiPolygonProperty") = 32615)), - CHECK (((geometrytype("multiPolygonProperty") = 'MULTIPOLYGON'::text) OR ("multiPolygonProperty" IS NULL))) -) WITH OIDS; - --- --- TOC Entry ID 34 (OID 312391) --- --- Name: FifteenFeature Type: TABLE Owner: cite --- - -CREATE TABLE "Fifteen" ( - "boundedBy" geometry, - "pointProperty" geometry, - CHECK ((srid("pointProperty") = 32615)), - CHECK (((geometrytype("pointProperty") = 'POINT'::text) OR ("pointProperty" IS NULL))), - CHECK ((srid("boundedBy") = 32615)), - CHECK (((geometrytype("boundedBy") = 'POLYGON'::text) OR ("boundedBy" IS NULL))) -) WITH OIDS; - --- --- TOC Entry ID 35 (OID 312430) --- --- Name: LockFeature Type: TABLE Owner: cite --- - -CREATE TABLE "Locks" ( - "boundedBy" geometry, - "id" character varying, - "pointProperty" geometry, - CHECK ((srid("pointProperty") = 32615)), - CHECK (((geometrytype("pointProperty") = 'POINT'::text) OR ("pointProperty" IS NULL))), - CHECK ((srid("boundedBy") = 32615)), - CHECK (((geometrytype("boundedBy") = 'POLYGON'::text) OR ("boundedBy" IS NULL))) -) WITH OIDS; - --- --- TOC Entry ID 36 (OID 312570) --- --- Name: OtherFeature Type: TABLE Owner: cite --- - -CREATE TABLE "Other" ( - "description" character varying, - "name" character varying, - "boundedBy" geometry, - "pointProperty" geometry, - "string1" character varying NOT NULL, - "string2" character varying, - "integers" integer, - "dates" date, - CHECK ((srid("pointProperty") = 32615)), - CHECK (((geometrytype("pointProperty") = 'POINT'::text) OR ("pointProperty" IS NULL))), - CHECK ((srid("boundedBy") = 32615)), - CHECK (((geometrytype("boundedBy") = 'POLYGON'::text) OR ("boundedBy" IS NULL))) -) WITH OIDS; - --- --- Data for TOC Entry ID 37 (OID 16560) --- --- Name: spatial_ref_sys Type: TABLE DATA Owner: cite --- - ---uncomment this line if cite user has not yet been created. ---create user cite; - ---uncomment these to grant permissions to cite. These occur here --- as the tables need to be created before granting privelages. ---GRANT ALL ON "Nulls" TO cite; ---GRANT ALL ON "Points" TO cite; ---GRANT ALL ON "Other" TO cite; ---GRANT ALL ON "Lines" TO cite; ---GRANT ALL ON "Polygons" TO cite; ---GRANT ALL ON "MLines" TO cite; ---GRANT ALL ON "MPolygons" TO cite; ---GRANT ALL ON "MPoints" TO cite; ---GRANT ALL ON "Seven" TO cite; ---GRANT ALL ON "Fifteen" TO cite; ---GRANT ALL ON "Updates" TO cite; ---GRANT ALL ON "Deletes" TO cite; ---GRANT ALL ON "Inserts" TO cite; ---GRANT ALL ON "Locks" TO cite; ---GRANT ALL ON "geometry_columns" TO cite; - - -COPY "geometry_columns" FROM stdin; - public Nulls pointProperty 2 32615 POINT - public Nulls boundedBy 2 32615 POLYGON - public Points pointProperty 2 32615 POINT - public Other pointProperty 2 32615 POINT - public Lines lineStringProperty 2 32615 LINESTRING - public Polygons polygonProperty 2 32615 POLYGON - public MPolygons multiPolygonProperty 2 32615 MULTIPOLYGON - public MPoints multiPointProperty 2 32615 MULTIPOINT - public MLines multiLineStringProperty 2 32615 MULTILINESTRING - public Other boundedBy 2 32615 POLYGON - public Seven pointProperty 2 32615 POINT - public Seven boundedBy 2 32615 POLYGON - public Fifteen pointProperty 2 32615 POINT - public Fifteen boundedBy 2 32615 POLYGON - public Updates pointProperty 2 32615 POINT - public Updates boundedBy 2 32615 POLYGON - public Inserts pointProperty 2 32615 POINT - public Inserts boundedBy 2 32615 POLYGON - public Deletes pointProperty 2 32615 POINT - public Deletes boundedBy 2 32615 POLYGON - public Locks pointProperty 2 32615 POINT - public Locks boundedBy 2 32615 POLYGON -\. --- --- Data for TOC Entry ID 39 (OID 113496) --- --- Name: county Type: TABLE DATA Owner: public --- - - - - -COPY "Seven" FROM stdin; -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -\. --- --- Data for TOC Entry ID 59 (OID 312275) --- --- Name: NullFeature Type: TABLE DATA Owner: public --- - - -COPY "Nulls" FROM stdin; -nullFeature \N SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) \N \N \N -\. --- --- Data for TOC Entry ID 60 (OID 312300) --- --- Name: DeleteFeature Type: TABLE DATA Owner: public --- - - -COPY "Deletes" FROM stdin; -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) td0001 SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) td0002 SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) td0003 SRID=32615;POINT(500050 500050) -\. --- --- Data for TOC Entry ID 61 (OID 312305) --- --- Name: InsertFeature Type: TABLE DATA Owner: public --- - - -COPY "Inserts" FROM stdin; -\. --- --- Data for TOC Entry ID 62 (OID 312310) --- --- Name: UpdateFeature Type: TABLE DATA Owner: public --- - - -COPY "Updates" FROM stdin; -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) tu0001 SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) tu0002 SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) tu0003 SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) tu0004 SRID=32615;POINT(500050 500050) -\. --- --- Data for TOC Entry ID 63 (OID 312315) --- --- Name: PointFeature Type: TABLE DATA Owner: public --- - - -COPY "Points" FROM stdin; -t0000 SRID=32615;POINT(500050 500050) -\. --- --- Data for TOC Entry ID 64 (OID 312322) --- --- Name: LineStringFeature Type: TABLE DATA Owner: public --- - - -COPY "Lines" FROM stdin; -t0001 SRID=32615;LINESTRING(500125 500025,500175 500075) -\. --- --- Data for TOC Entry ID 65 (OID 312329) --- --- Name: PolygonFeature Type: TABLE DATA Owner: public --- - - -COPY "Polygons" FROM stdin; -t0002 SRID=32615;POLYGON((500225 500025,500225 500075,500275 500050,500275 500025,500225 500025)) -\. --- --- Data for TOC Entry ID 66 (OID 312335) --- --- Name: MultiPointFeature Type: TABLE DATA Owner: public --- - - -COPY "MPoints" FROM stdin; -t0003 SRID=32615;MULTIPOINT(500325 500025,500375 500075) -\. --- --- Data for TOC Entry ID 67 (OID 312341) --- --- Name: MultiLineStringFeature Type: TABLE DATA Owner: public --- - - -COPY "MLines" FROM stdin; -t0004 SRID=32615;MULTILINESTRING((500425 500025,500475 500075),(500425 500075,500475 500025)) -\. --- --- Data for TOC Entry ID 68 (OID 312348) --- --- Name: MultiPolygonFeature Type: TABLE DATA Owner: public --- - - -COPY "MPolygons" FROM stdin; -t0005 SRID=32615;MULTIPOLYGON(((500525 500025,500550 500050,500575 500025,500525 500025)),((500525 500050,500525 500075,500550 500075,500550 500050,500525 500050))) -\. --- --- Data for TOC Entry ID 69 (OID 312391) --- --- Name: FifteenFeature Type: TABLE DATA Owner: public --- - - -COPY "Fifteen" FROM stdin; -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) -\. --- --- Data for TOC Entry ID 70 (OID 312430) --- --- Name: LockFeature Type: TABLE DATA Owner: public --- - - -COPY "Locks" FROM stdin; -\N lfla0001 \N -\N lfla0002 \N -\N lfla0003 \N -\N lfla0004 \N -\N gfwlla0001 \N -\N gfwlla0002 \N -\N gfwlla0003 \N -\N gfwlla0004 \N -\N lfbt0001 \N -\N lfbt0002 \N -\N lfbt0003 \N -\N lfbt0004 \N -\N lfbt0005 \N -\N lfbt0006 \N -\N gfwlbt0001 \N -\N gfwlbt0002 \N -\N gfwlbt0003 \N -\N gfwlbt0004 \N -\N gfwlbt0005 \N -\N gfwlbt0006 \N -\N lfe0001 \N -\N lfe0002 \N -\N lfe0003 \N -\N lfe0004 \N -\N gfwle0001 \N -\N gfwle0002 \N -\N gfwle0003 \N -\N gfwle0004 \N -\N lfra0001 \N -\N lfra0002 \N -\N lfra0003 \N -\N lfra0004 \N -\N lfra0005 \N -\N lfra0006 \N -\N lfra0007 \N -\N lfra0008 \N -\N lfra0009 \N -\N lfra0010 \N -\N gfwlra0001 \N -\N gfwlra0002 \N -\N gfwlra0003 \N -\N gfwlra0004 \N -\N gfwlra0005 \N -\N gfwlra0006 \N -\N gfwlra0007 \N -\N gfwlra0008 \N -\N gfwlra0009 \N -\N gfwlra0010 \N -\N lfrs0001 \N -\N lfrs0002 \N -\N lfrs0003 \N -\N lfrs0004 \N -\N lfrs0005 \N -\N lfrs0006 \N -\N lfrs0007 \N -\N lfrs0008 \N -\N lfrs0009 \N -\N lfrs0010 \N -\N gfwlrs0001 \N -\N gfwlrs0002 \N -\N gfwlrs0003 \N -\N gfwlrs0004 \N -\N gfwlrs0005 \N -\N gfwlrs0006 \N -\N gfwlrs0007 \N -\N gfwlrs0008 \N -\N gfwlrs0009 \N -\N gfwlrs0010 \N -\. - -UPDATE "Locks" SET "boundedBy" = GeometryFromText('POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000))', 32615) WHERE TRUE; -UPDATE "Locks" SET "pointProperty" = GeometryFromText('POINT(500050 500050)', 32615) WHERE TRUE; - --- --- Data for TOC Entry ID 71 (OID 312570) --- --- Name: OtherFeature Type: TABLE DATA Owner: public --- - - -COPY "Other" FROM stdin; -A Single Feature used to test returning of properties singleFeature SRID=32615;POLYGON((500000 500000,500000 500100,500100 500100,500100 500000,500000 500000)) SRID=32615;POINT(500050 500050) always sometimes 7 2002-12-02 -\. - --- --- Fixes to have primary keys and no oids --- -alter table "Deletes" add column pkey serial; -alter table "Deletes" add primary key (pkey); -alter table "Deletes" set without oids; - -alter table "Fifteen" add column pkey serial; -alter table "Fifteen" add primary key (pkey); -alter table "Fifteen" set without oids; - -alter table "Inserts" add column pkey serial; -alter table "Inserts" add primary key (pkey); -alter table "Inserts" set without oids; - -alter table "Lines" add column pkey serial; -alter table "Lines" add primary key (pkey); -alter table "Lines" set without oids; - -alter table "Locks" add column pkey serial; -alter table "Locks" add primary key (pkey); -alter table "Locks" set without oids; - -alter table "MLines" add column pkey serial; -alter table "MLines" add primary key (pkey); -alter table "MLines" set without oids; - -alter table "MPoints" add column pkey serial; -alter table "MPoints" add primary key (pkey); -alter table "MPoints" set without oids; - -alter table "MPolygons" add column pkey serial; -alter table "MPolygons" add primary key (pkey); -alter table "MPolygons" set without oids; - -alter table "Nulls" add column pkey serial; -alter table "Nulls" add primary key (pkey); -alter table "Nulls" set without oids; - -alter table "Other" add column pkey serial; -alter table "Other" add primary key (pkey); -alter table "Other" set without oids; - -alter table "Points" add column pkey serial; -alter table "Points" add primary key (pkey); -alter table "Points" set without oids; - -alter table "Polygons" add column pkey serial; -alter table "Polygons" add primary key (pkey); -alter table "Polygons" set without oids; - -alter table "Seven" add column pkey serial; -alter table "Seven" add primary key (pkey); -alter table "Seven" set without oids; - -alter table "Updates" add column pkey serial; -alter table "Updates" add primary key (pkey); -alter table "Updates" set without oids; - diff --git a/build/cite/wfs10/citewfs-1.0/cite_data_postgis2.sql b/build/cite/wfs10/citewfs-1.0/cite_data_postgis2.sql index 5ed5235c4ed..85197c60051 100644 --- a/build/cite/wfs10/citewfs-1.0/cite_data_postgis2.sql +++ b/build/cite/wfs10/citewfs-1.0/cite_data_postgis2.sql @@ -11,27 +11,27 @@ -- Uncomment and change this to the user who has permissions to drop and -- create tables in this db. --- \connect - cite +\connect cite cite -create extension postgis; +--create extension postgis; --uncomment these if you want to reset everything. -drop table "Nulls"; -drop table "Points"; -drop table "Other"; -drop table "Lines"; -drop table "Polygons"; -drop table "MLines"; -drop table "MPolygons"; -drop table "MPoints"; -drop table "Seven"; -drop table "Fifteen"; -drop table "Updates"; -drop table "Inserts"; -drop table "Deletes"; -drop table "Locks"; -delete from "geometry_columns" where srid=32615; +--drop table "Nulls"; +--drop table "Points"; +--drop table "Other"; +--drop table "Lines"; +--drop table "Polygons"; +--drop table "MLines"; +--drop table "MPolygons"; +--drop table "MPoints"; +--drop table "Seven"; +--drop table "Fifteen"; +--drop table "Updates"; +--drop table "Inserts"; +--drop table "Deletes"; +--drop table "Locks"; +--delete from "geometry_columns" where srid=32615; @@ -142,7 +142,7 @@ CREATE TABLE "Polygons" ( CREATE TABLE "MPoints" ( "id" character varying, "multiPointProperty" geometry('MULTIPOINT', 32615) -) WITH OIDS; +); -- -- TOC Entry ID 32 (OID 312341) @@ -449,57 +449,44 @@ A Single Feature used to test returning of properties singleFeature SRID=32615;P -- alter table "Deletes" add column pkey serial; alter table "Deletes" add primary key (pkey); -alter table "Deletes" set without oids; alter table "Fifteen" add column pkey serial; alter table "Fifteen" add primary key (pkey); -alter table "Fifteen" set without oids; alter table "Inserts" add column pkey serial; alter table "Inserts" add primary key (pkey); -alter table "Inserts" set without oids; alter table "Lines" add column pkey serial; alter table "Lines" add primary key (pkey); -alter table "Lines" set without oids; alter table "Locks" add column pkey serial; alter table "Locks" add primary key (pkey); -alter table "Locks" set without oids; alter table "MLines" add column pkey serial; alter table "MLines" add primary key (pkey); -alter table "MLines" set without oids; alter table "MPoints" add column pkey serial; alter table "MPoints" add primary key (pkey); -alter table "MPoints" set without oids; alter table "MPolygons" add column pkey serial; alter table "MPolygons" add primary key (pkey); -alter table "MPolygons" set without oids; alter table "Nulls" add column pkey serial; alter table "Nulls" add primary key (pkey); -alter table "Nulls" set without oids; alter table "Other" add column pkey serial; alter table "Other" add primary key (pkey); -alter table "Other" set without oids; alter table "Points" add column pkey serial; alter table "Points" add primary key (pkey); -alter table "Points" set without oids; alter table "Polygons" add column pkey serial; alter table "Polygons" add primary key (pkey); -alter table "Polygons" set without oids; alter table "Seven" add column pkey serial; alter table "Seven" add primary key (pkey); -alter table "Seven" set without oids; alter table "Updates" add column pkey serial; alter table "Updates" add primary key (pkey); -alter table "Updates" set without oids; + diff --git a/build/cite/wfs10/docker-compose.override.yml b/build/cite/wfs10/compose.override.yml similarity index 50% rename from build/cite/wfs10/docker-compose.override.yml rename to build/cite/wfs10/compose.override.yml index 17e00522278..10385da2961 100644 --- a/build/cite/wfs10/docker-compose.override.yml +++ b/build/cite/wfs10/compose.override.yml @@ -1,5 +1,3 @@ -version: '3.0' - services: geoserver: image: ogccite/geoserver:wfs10 @@ -15,20 +13,14 @@ services: command: /run-test.sh wfs10 postgres: - image: ogccite/postgres:wfs10 - build: - context: . - dockerfile: ./postgres/Dockerfile + image: postgis/postgis:15-3.5-alpine ports: - - 5432 - env_file: - - ./.env - - ./postgres/postgres.env + - 15432:5432 + environment: + POSTGRES_DB: geoserver + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres volumes: - - pg_data:${PGDATA:-/var/lib/postgresql/data}:rw - ./wfs10/01-init-user.sh:/docker-entrypoint-initdb.d/01-init-user.sh - - ./wfs10/02-init-db.sql.gz:/docker-entrypoint-initdb.d/02-init-db.sql.gz - - ./wfs10/postgresql.conf:/etc/postgresql/postgresql.conf + - ./wfs10/citewfs-1.0/cite_data_postgis2.sql:/docker-entrypoint-initdb.d/02-init-db.sql -volumes: - pg_data: diff --git a/build/cite/wfs11/01-init-user.sh b/build/cite/wfs11/01-init-user.sh index 4b47e870d4e..633af9aad1a 100644 --- a/build/cite/wfs11/01-init-user.sh +++ b/build/cite/wfs11/01-init-user.sh @@ -2,7 +2,13 @@ set -e psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - CREATE USER cite; + CREATE USER cite PASSWORD 'cite'; CREATE DATABASE cite; GRANT ALL PRIVILEGES ON DATABASE cite TO cite; EOSQL + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "cite" <<-EOSQL + CREATE EXTENSION postgis; + GRANT ALL PRIVILEGES ON SCHEMA public TO cite; +EOSQL + diff --git a/build/cite/wfs11/02-init-db.sql.gz b/build/cite/wfs11/02-init-db.sql.gz deleted file mode 100644 index cd49c7b7bb9..00000000000 Binary files a/build/cite/wfs11/02-init-db.sql.gz and /dev/null differ diff --git a/build/cite/wfs11/citewfs-1.1/dataset-sf0-postgis2.sql b/build/cite/wfs11/citewfs-1.1/dataset-sf0-postgis2.sql index 97ef620e798..b162345a3b9 100644 --- a/build/cite/wfs11/citewfs-1.1/dataset-sf0-postgis2.sql +++ b/build/cite/wfs11/citewfs-1.1/dataset-sf0-postgis2.sql @@ -3,7 +3,9 @@ -- psql -U < dataset-sf0.sql SET client_encoding = 'UTF8'; -drop table "PrimitiveGeoFeature"; +\connect cite cite + +--drop table "PrimitiveGeoFeature"; create table "PrimitiveGeoFeature" ( description varchar, name varchar, @@ -26,7 +28,7 @@ INSERT INTO "PrimitiveGeoFeature" VALUES ('description-f008', 'name-f008', ST_G INSERT INTO "PrimitiveGeoFeature" VALUES (NULL, 'name-f015', NULL, ST_GeomFromText('POINT(-10.52 34.94)',4326), NULL, -900, NULL, 2.4, NULL, NULL, 7.90, 'f015'); -drop table "AggregateGeoFeature"; +--drop table "AggregateGeoFeature"; create table "AggregateGeoFeature" ( description varchar, name varchar, @@ -46,7 +48,7 @@ INSERT INTO "AggregateGeoFeature" VALUES ('description-f010','name-f010',NULL,NU INSERT INTO "AggregateGeoFeature" VALUES (NULL,'name-f016',NULL,NULL,ST_GeomFromText('MULTIPOLYGON(((6.0 57.5, 8.0 57.5, 8.0 60.0, 9.0 62.5, 5.0 62.5,6.0 60.0,6.0 57.5),(6.5 58.0,6.5 59.0,7.0 59.0,6.5 58.0)))',4326),-182.9,NULL,'In rhoncus nisl sit amet sem.','EE010','f016'); -drop table "EntitéGénérique"; +--drop table "EntitéGénérique"; create table "EntitéGénérique" ( description varchar, name varchar, diff --git a/build/cite/wfs11/docker-compose.override.yml b/build/cite/wfs11/compose.override.yml similarity index 53% rename from build/cite/wfs11/docker-compose.override.yml rename to build/cite/wfs11/compose.override.yml index 33959cf822c..46e3894e91e 100644 --- a/build/cite/wfs11/docker-compose.override.yml +++ b/build/cite/wfs11/compose.override.yml @@ -1,5 +1,3 @@ -version: '3.0' - services: geoserver: image: ogccite/geoserver:wfs11 @@ -15,20 +13,16 @@ services: command: /run-test.sh wfs11 postgres: - image: ogccite/postgres:wfs11 - build: - context: . - dockerfile: ./postgres/Dockerfile + image: postgis/postgis:15-3.5-alpine ports: - - 5432 - env_file: - - ./.env - - ./postgres/postgres.env + - 15432:5432 + environment: + POSTGRES_DB: geoserver + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres volumes: - - pg_data:${PGDATA:-/var/lib/postgresql/data}:rw - ./wfs11/01-init-user.sh:/docker-entrypoint-initdb.d/01-init-user.sh - - ./wfs11/02-init-db.sql.gz:/docker-entrypoint-initdb.d/02-init-db.sql.gz - - ./wfs11/postgresql.conf:/etc/postgresql/postgresql.conf + - ./wfs11/citewfs-1.1/dataset-sf0-postgis2.sql:/docker-entrypoint-initdb.d/02-init-db.sql volumes: pg_data: diff --git a/build/cite/wms11/docker-compose.override.yml b/build/cite/wms11/compose.override.yml similarity index 94% rename from build/cite/wms11/docker-compose.override.yml rename to build/cite/wms11/compose.override.yml index 3fd04e67ca4..83971559980 100644 --- a/build/cite/wms11/docker-compose.override.yml +++ b/build/cite/wms11/compose.override.yml @@ -1,5 +1,3 @@ -version: '3.0' - services: geoserver: image: ogccite/geoserver:wms11 diff --git a/build/cite/wms13/docker-compose.override.yml b/build/cite/wms13/compose.override.yml similarity index 94% rename from build/cite/wms13/docker-compose.override.yml rename to build/cite/wms13/compose.override.yml index 2a55d1f57c6..51f61651ec0 100644 --- a/build/cite/wms13/docker-compose.override.yml +++ b/build/cite/wms13/compose.override.yml @@ -1,5 +1,3 @@ -version: '3.0' - services: geoserver: image: ogccite/geoserver:wms13 diff --git a/doc/en/developer/source/cite-test-guide/index.rst b/doc/en/developer/source/cite-test-guide/index.rst index 8b45d2dbb63..95e935fa90e 100644 --- a/doc/en/developer/source/cite-test-guide/index.rst +++ b/doc/en/developer/source/cite-test-guide/index.rst @@ -69,6 +69,7 @@ Set-up the environment |-- wms11 |-- wms13 |-- wfs11 + |-- ogcapi-features10 |-- interactive |-- logs |-- docker-compose.yml @@ -95,10 +96,26 @@ automate all the commands, and the second one is running the test through WebUI: .. code:: makefile - clean: $(suite) This will clean the Environment of previous runs. - build: $(suite) This will build the GeoServer Docker Image for the Environment. - test: $(suite) This will run the Suite test with teamengine. - webUI: $(suite) This will run the Suite test with teamengine. + Usage: + + # Main targets in suggested order: + + war: Build the geoserver.war file to use for testing and place it in ./geoserver/geoserver.war + build: suite= Build the GeoServer Docker Image for the Environment. + test: suite= Run the Test Suite with teamengine and GeoServer on docker compose. + clean: Clean the Environment of previous runs. + + # Additional helper targets: + + test-localhost: suite= Run the Test Suite against a local host GeoServer instance (http://172.17.0.1:8080) + test-external: suite= iut= Run the Test Suite against a GeoServer instance at a provided URL + version: suite= Print the version of the GeoServer on the current docker. + ogcapi-features10-localhost: Shortcut for make test-localhost suite=ogcapi-features10 + start: suite= [services=] Start the docker composition for suite. Optionally limit which services. + stop: Shuts down the docker composition. Deos not remove logs/ + print-services: suite= Print the service names and docker images used for a given suite + webUI: Start teamengine in interactive mode for the OWS services (excludes ogcapi services). + - Choose which test to run, this is an example: @@ -119,14 +136,15 @@ automate all the commands, and the second one is running the test through WebUI: * wfs11 * wms11 * wms13 + * ogcapi-features10 - - Choose which GeoServer war file to test by setting the ``war_url`` environment variable inside the ``Makefile``, ex: + - Build the ``geoserver.war`` file to test against : .. code:: C - war_url = "https://build.geoserver.org/geoserver/main/geoserver-main-latest-war.zip" + make war -2. If you don't want to do it inside the ``Makefile`` you have the option of adding the variable in the command when you build the docker images. +2. Build the GeoServer Docker image set up to run a specific test suite - To clean the local environment. @@ -140,12 +158,14 @@ automate all the commands, and the second one is running the test through WebUI: make build suite= - - Alternative, with the ``war_url`` variable include: + - Alternative, specify a ``war_url`` variable to fetch the ``geoserver.war`` from an URL: .. code:: make build suite= war_url= + The ``war_url`` can point to a ``.war`` or ``.zip`` file containing the ``.war`` like in ``https://build.geoserver.org/geoserver/main/geoserver-main-latest-war.zip`` + - To run the suite test. .. code:: shell @@ -578,6 +598,119 @@ Run WMS 1.3 tests .. image:: ./image/tewms-1_3.png +Run OGC Features 1.0 tests +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Newer test suites like the ``ogcapi-features10`` one, are executed by calling teamengine's REST API, +with a teamengine Docker image `provided by OGC `_ (see `Using the REST API `_ section +on the teamengine's user guide). + +As a result of the test run, a ``logs/testng-results.xml`` file will be generated, and a human readable summary of test +failures, if any, will be printed to the console. + +Run with the locally built .war +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Make sure you've prepared the ``geoserver.war`` as instructed above with ``make war``. + + .. code-block:: shell + + make clean build test suite=ogcapi-features10 + +If there are test errors, a human readable summary will be printed to the console, similar to this: + + .. code-block:: shell + + test-method: verifyCollectionsPathCollectionCrsPropertyContainsDefaultCrs + description: Implements A.1 Discovery, Abstract Test 2 (Requirement /req/crs/fc-md-crs-list B), crs property contains default crs in the collection objects in the path /collections + depends-on-groups: crs-conformance + status: FAIL + exception: Collection with id 'sf:restricted' at collections path /collections does not specify one of the default CRS 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' or 'http://www.opengis.net/def/crs/OGC/0/CRS84h' but provides at least one spatial feature collections + Request URI: + + test-method: verifyCollectionsPathCollectionCrsPropertyContainsDefaultCrs + description: Implements A.1 Discovery, Abstract Test 2 (Requirement /req/crs/fc-md-crs-list B), crs property contains default crs in the collection objects in the path /collections + depends-on-groups: crs-conformance + status: FAIL + exception: Collection with id 'sf:roads' at collections path /collections does not specify one of the default CRS 'http://www.opengis.net/def/crs/OGC/1.3/CRS84' or 'http://www.opengis.net/def/crs/OGC/0/CRS84h' but provides at least one spatial feature collections + Request URI: + + Passed: 2153 + Failed: 9 + Skipped: 96 + make[2]: *** [validate-testng-results] Error 1 + make[1]: *** [test-rest] Error 2 + make: *** [test] Error 2 + + +Either way, both the ``teamengine`` and ``geoserver`` containers will keep on running. + +Run ``make clean`` to shut them down and clean up the ``logs/`` directory. + +Test a GeoServer instance external to the docker composition +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Since teamengine runs as a Docker container, in order to reach out to a GeoServer instance running on the host, +it needs a Landing Page URL that points to the host network. In docker there's a special IP address for that purpose, +`172.17.0.1`, as long as the container is running on the default docker bridge network. Check out the docker [docs](Networking with standalone containers) for more info. + +.. attention:: + + In the following examples, some ``make`` targets receive an ``iut`` parameter with the URL of the OGC Features API landing page to test, + external to the ``teamengine``'s container network. By default, for **Linux** systems, use the **172.17.0.1** IP address. + However, if you're running the tests on **MacOS**, replace it with the **host.docker.internal** hostname instead. + This difference exists because on Linux, Docker creates a bridge network where the host is accessible via ``172.17.0.1``. On MacOS, Docker Desktop for Mac + runs containers within a virtualization layer, which changes the networking model. As a result, ``host.docker.internal`` is used to enable containers + to access the host. + + +For the case of the ``ogcapi-features10``, you can simply run + + .. code-block:: shell + + make ogcapi-features10-localhost + +And it'll print out + + .. code-block:: shell + + Running the ogcapi-features10 test suite with the teamengine REST API against http://172.17.0.1:8080/geoserver/ogc/features/v1 + +The ``ogcapi-features10-localhost`` target is a special case of ``test-external``, which assumes the most common +case of GeoServer running on ``localhost:8080``. + +During development or troubleshooting, you might want to either use a different GeoServer port, or +test only a specific workspace or feature type. For that you can use a custom ``iut`` (Instance Under Test) +URL for the ``test-external`` make target. For example, to hit a GeoServer instance running on the host +at port ``9090``, and address only the ``sf:archsites`` layer, you can use a ``iut`` URL combining the +``172.17.0.1`` IP address and GeoServer's ``/sf/archsites`` virtual service: + + .. code-block:: shell + + make test-external suite=ogcapi-features10 iut="http://172.17.0.1:9090/geoserver/sf/archsites/ogc/features/v1" + + +And it'll print out + + .. code-block:: shell + + Running the ogcapi-features10 test suite with the teamengine REST API against http://172.17.0.1:9090/geoserver/sf/archsites/ogc/features/v1 + +Finally, run + + .. code-block:: shell + + make clean + +to stop the docker composition and clean up the ``logs/`` directory, or + + .. code-block:: shell + + make stop + +to just shut down the docker composition wihtout cleaning up the ``logs/`` directory. + .. _commandline: .. _teamengine: + diff --git a/doc/en/user/source/community/ogc-api/features/img/features.png b/doc/en/user/source/community/ogc-api/features/img/features.png index 729791adb20..2f9fdc87b06 100644 Binary files a/doc/en/user/source/community/ogc-api/features/img/features.png and b/doc/en/user/source/community/ogc-api/features/img/features.png differ diff --git a/doc/en/user/source/community/ogc-api/features/index.rst b/doc/en/user/source/community/ogc-api/features/index.rst index e2a5f7d3cde..2d2deea627e 100644 --- a/doc/en/user/source/community/ogc-api/features/index.rst +++ b/doc/en/user/source/community/ogc-api/features/index.rst @@ -16,23 +16,32 @@ Features Implementation status - Version - Implementation status * - Part 1: Core - - `1.0.0 `__ + - `1.0.1 `__ - Passes compliance tests * - Part 2: Coordinate Systems by Reference - - `1.0.0 `__ + - `1.0.1 `__ - Passes compliance tests * - Part 3: Filtering - - `Draft `__ - - Draft implemented (mind, the draft does not include a filtering language) + - `1.0.0 `__ + - Implemented an earlier draft, being updated to final (no CITE tests yet) + * - Common Query Language (CQL2) + - `1.0.0 `__ + - Implemented an earlier draft, being updated to final (no CITE tests yet) * - Part 4: Create, Replace, Update and Delete - - `Draft `__ + - `1.0.0 `__ + - Not implemented (volunteers/sponsoring wanted) + * - Part 5: search + - `Proposal DRAFT `__ + - A search endpoint for complex queries is implemented at the single collection level (POST to immediately get a response, no support for stored queries). + * - Part 6 - Schemas + - `Proposal DRAFT `__ - Not implemented (volunteers/sponsoring wanted) - * - Common Query Language (CQL2) - - `Draft `__ - - Implements an earlier draft for for both text and JSON encodings. To be updated. * - Part n: Query by IDs - - `Proposal `__ + - `Proposal DRAFT `__ - Proposal implemented, but syntax and semantic is subject to change in a future release. Thus said, usage should be carefully considered. + * - Sorting + - `DRAFT in github `__ + - Partial implementation borrowed by OGC API Records, using the sortby parameter. Sortables are not exposed. Installing the GeoServer OGC API Features module ------------------------------------------------ @@ -48,7 +57,7 @@ Installing the GeoServer OGC API Features module Use of OGC API - Features service --------------------------------- -The OGC API Features Service is accessed via the :guilabel:`FEATURES` version :guilabel:`1.0` link on the home page. +The OGC API Features Service is accessed via the :guilabel:`Features` version :guilabel:`1.0.1` link on the home page. Capabilities '''''''''''' @@ -66,48 +75,27 @@ The service is self described using: .. code-block:: json { - "title": "GeoServer Web Feature Service", - "description": "This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction.", + "title": "GeoServer Features services", + "description": "This services delivers vector data in raw form, including both geometries and attributes.", "links": [ { - "href": "http://localhost:8080/geoserver/ogc/features/?f=application%2Fx-yaml", - "rel": "alternate", - "type": "application/x-yaml", - "title": "This document as application/x-yaml" - }, - { - "href": "http://localhost:8080/geoserver/ogc/features/?f=application%2Fjson", + "href": "https://gs-main.geosolutionsgroup.com/geoserver/ogc/features/v1/?f=application%2Fjson", "rel": "self", "type": "application/json", "title": "This document" }, { - "href": "http://localhost:8080/geoserver/ogc/features/?f=text%2Fhtml", + "href": "https://gs-main.geosolutionsgroup.com/geoserver/ogc/features/v1/?f=application%2Fx-yaml", + "rel": "alternate", + "type": "application/x-yaml", + "title": "This document as application/x-yaml" + }, + { + "href": "https://gs-main.geosolutionsgroup.com/geoserver/ogc/features/v1/?f=text%2Fhtml", "rel": "alternate", "type": "text/html", "title": "This document as text/html" - } - -* ``application/x-yaml``: A collection of :file:`yaml` documents, with references between each document for programmatic access. - - .. code-block:: yaml - - title: GeoServer Web Feature Service - description: This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports - all WFS operations including Transaction. - links: - - href: http://localhost:8080/geoserver/ogc/features/?f=application%2Fx-yaml - rel: self - type: application/x-yaml - title: This document - - href: http://localhost:8080/geoserver/ogc/features/?f=application%2Fjson - rel: alternate - type: application/json - title: This document as application/json - - href: http://localhost:8080/geoserver/ogc/features/?f=text%2Fhtml - rel: alternate - type: text/html - title: This document as text/html + }, The service title and description are provided by the existing :ref:`wfs` settings. @@ -177,6 +165,7 @@ To override an OGC API Features template: #. Create a file in this location, using the GeoServer |release| examples below: + * :download:`ogc/features/v1/landingPage.ftl ` * :download:`ogc/features/v1/collection.ftl ` * :download:`ogc/features/v1/collection_include.ftl ` * :download:`ogc/features/v1/collections.ftl ` @@ -185,15 +174,14 @@ To override an OGC API Features template: The above built-in examples are for GeoServer |release|, please check for any changes when upgrading GeoServer. -The templates for listing feature content are shared between OGC API services. To override a template used to list features: +To override a template used to list features: -#. Use the directory in the location you wish to override: +#. Use the directory in the location you wish to override (can be general, specific to a workspace, datastore, or feature type): * :file:`GEOSERVER_DATA_DIR/templates` * :file:`GEOSERVER_DATA_DIR/workspace/{workspace}` * :file:`GEOSERVER_DATA_DIR/workspace/{workspace}/{datastore}` * :file:`GEOSERVER_DATA_DIR/workspace/{workspace}/{datastore}/{featuretype}` - * :download:`ogc/features/landingPage.ftl ` #. Create a file in this location, using the GeoServer |release| examples below: @@ -231,7 +219,7 @@ As an example customize how collections are listed: Presently each family of templates manages its own :file:`common-header.ftl` (as shown in the difference between :file:`ogc/features` service templates, and getfeature templates above). -#. A restart is required, as templates are cached. +#. A restart is not required, the system will notice when the template is updated and apply the changes automatically. .. figure:: img/template_override.png diff --git a/doc/en/user/source/data/database/sqlserver.rst b/doc/en/user/source/data/database/sqlserver.rst index 180d1e3c683..edc8b1c8b49 100644 --- a/doc/en/user/source/data/database/sqlserver.rst +++ b/doc/en/user/source/data/database/sqlserver.rst @@ -10,7 +10,7 @@ Microsoft's `SQL Server `_ is a relational d Supported versions ------------------ -The extension supports SQL Server 2008 - 2019 and SQL Azure. +The extension supports SQL Server 2019 - 2022 and SQL Azure, older versions down to 2008 may work. .. _sqlserver_install: diff --git a/doc/en/user/source/extensions/mapml/images/mapml_tcrs_menu.png b/doc/en/user/source/extensions/mapml/images/mapml_tcrs_menu.png new file mode 100644 index 00000000000..2e0fdaf49b2 Binary files /dev/null and b/doc/en/user/source/extensions/mapml/images/mapml_tcrs_menu.png differ diff --git a/doc/en/user/source/extensions/mapml/images/mapml_tcrs_selector.png b/doc/en/user/source/extensions/mapml/images/mapml_tcrs_selector.png new file mode 100644 index 00000000000..5dc71756f83 Binary files /dev/null and b/doc/en/user/source/extensions/mapml/images/mapml_tcrs_selector.png differ diff --git a/doc/en/user/source/extensions/mapml/images/mapml_utm_gridset.png b/doc/en/user/source/extensions/mapml/images/mapml_utm_gridset.png new file mode 100644 index 00000000000..d5b1a7b82d7 Binary files /dev/null and b/doc/en/user/source/extensions/mapml/images/mapml_utm_gridset.png differ diff --git a/doc/en/user/source/extensions/mapml/installation.rst b/doc/en/user/source/extensions/mapml/installation.rst index 1272d9405ac..2c8ee983f92 100644 --- a/doc/en/user/source/extensions/mapml/installation.rst +++ b/doc/en/user/source/extensions/mapml/installation.rst @@ -47,6 +47,39 @@ If the ``Represent multi-layer requests as multiple elements`` is checked (and t .. figure:: images/mapml_wms_multi_extent.png +TiledCRS +-------- +MapML supports 4 built-in TiledCRS: + +- MapML:WGS84 (or EPSG:4326) +- MapML:OSMTILE (or EPSG:3857) +- MapML:CBMTILE (or EPSG:3978) +- MapML:APSTILE (or EPSG:5936) + +In addition, is it possible to configure custom TiledCRS based on the available WMTS GridSets. +A new MapML TCRS Settings menu is available in the GeoServer UI on the Settings section: + +.. figure:: images/mapml_tcrs_menu.png + + +It provides a selector containing available GridSets. Administrator can select GridSets from the left list that will be converted to TiledCRSs. + + +.. figure:: images/mapml_tcrs_selector.png + + +Notes: + +- Gridsets containing ":" character in the name won't be listed +- Gridsets with non-numeric levels or without a common prefix won't be listed + + +For example, the UTM14WGS84Quad specified in the above selector has the following definition, which only contains numeric level names. + +.. figure:: images/mapml_utm_gridset.png + + + Styles ------ @@ -262,7 +295,7 @@ MapML resources will be available for any published WMS layers by making a GetMa **SRS/CRS** -Note that the WMS SRS or CRS must be one of the projections supported by MapML: +Note that the WMS SRS or CRS must be one of the built-in projections supported by MapML or one of the TCRS configured through the dedicated section. Built-in MapML CRS are: - MapML:WGS84 (or EPSG:4326) - MapML:OSMTILE (or EPSG:3857) diff --git a/doc/en/user/source/extensions/wmts-multidimensional/images/sidecar.png b/doc/en/user/source/extensions/wmts-multidimensional/images/sidecar.png index 318728d9c9a..4e8037ebc18 100644 Binary files a/doc/en/user/source/extensions/wmts-multidimensional/images/sidecar.png and b/doc/en/user/source/extensions/wmts-multidimensional/images/sidecar.png differ diff --git a/doc/en/user/source/extensions/wmts-multidimensional/performance.rst b/doc/en/user/source/extensions/wmts-multidimensional/performance.rst index b92526b8b6a..c23d61b9654 100644 --- a/doc/en/user/source/extensions/wmts-multidimensional/performance.rst +++ b/doc/en/user/source/extensions/wmts-multidimensional/performance.rst @@ -28,6 +28,9 @@ in place of the original table, for any domain extraction purpose: *Setting up a sidecar table.* +The summary table is normally looked up in the same store, but if needed, it can be also found +in a different store, as long as it's accessible to the GeoServer instance. Leave the sidecar +store empty in case the summary table is in the same store as the original table. Conditions for the sidecar table to work: diff --git a/doc/en/user/source/geowebcache/webadmin/defaults.rst b/doc/en/user/source/geowebcache/webadmin/defaults.rst index 322c0c9ede4..b883e4d4e63 100644 --- a/doc/en/user/source/geowebcache/webadmin/defaults.rst +++ b/doc/en/user/source/geowebcache/webadmin/defaults.rst @@ -77,6 +77,20 @@ Enable Data Security Enables the :ref:`gwc_data_security` in the embedded GeoWebCache. +Metatiling threads count +~~~~~~~~~~~~~~~~~~~~~~~~ + +This setting determines the number of threads that will be used to encode and save metatiles. +By default, a user requested tile will be encoded on main request thread and immediately returned, +but the remaining tiles will be encoded and saved on asynchronous threads to decrease latency +experienced by the user. + +Possible values for this setting: + +* **unset**, which will use a default thread pool size, equal to 2 times the number of cores +* **0**, which will disable concurrency and all tiles belonging to the metatile will be encoded/saved on the main request thread +* **a positive integer**, which will set the number of threads to the specified value + Default Caching Options for GeoServer Layers -------------------------------------------- @@ -107,6 +121,15 @@ The disadvantage of metatiling is that at large sizes, memory consumption can be The size of the default metatile can be adjusted here. By default, GeoServer sets a metatile size of **4x4**, which strikes a balance between performance, memory usage, and rendering accuracy. +Metatiling threads +~~~~~~~~~~~~~~~~~~ + +After a metatile (see above) is produced, it is then split into a total of 16 individual tiles to be encoded and saved to the cache. By default, a user requested tile will be encoded and saved on the main request thread but the remaining tiles will be encoded and saved on asynchronous threads to decrease latency experienced by the user. + +Leaving this value blank will use a default thread pool size, equal to 2 times the number of cores. Setting to 0 will disable concurrency and all tiles belonging to the metatile will be encoded/saved on the main request thread. + +This setting only affects user requests and is not used when seeding (seeding will encode an entire metatile on each seeding thread). + Default gutter size ~~~~~~~~~~~~~~~~~~~ diff --git a/doc/en/user/source/geowebcache/webadmin/img/defaults_services.png b/doc/en/user/source/geowebcache/webadmin/img/defaults_services.png index 684a03dfa91..b73ddf1b79d 100644 Binary files a/doc/en/user/source/geowebcache/webadmin/img/defaults_services.png and b/doc/en/user/source/geowebcache/webadmin/img/defaults_services.png differ diff --git a/doc/en/user/source/installation/upgrade.rst b/doc/en/user/source/installation/upgrade.rst index 820e3b70cbb..7f062fb31bd 100644 --- a/doc/en/user/source/installation/upgrade.rst +++ b/doc/en/user/source/installation/upgrade.rst @@ -103,6 +103,16 @@ If the above did not help, then a full cleanup of the GeoServer configuration is #. Recreate the stores and layers using the known procedures. +Disk Quota validation query (GeoServer 2.25.4 and newer) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When using the JDBC Disk Quota: + +* Validation query for ``H2`` is limited to ``SELECT 1``. +* Validation query for ``Oracle`` is limited to ``SELECT 1 FROM DUAL``. +* Validation query for other JDBC formats receive a warning in the logs if is not one of the common examples above. + +.. note:: If you find your JDBC Disk Quota is no longer loaded on startup: check the logs for message about validation query, edit the configuration, and restart. External Entity Allow List default (GeoServer 2.25 and newer) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/en/user/source/production/config.rst b/doc/en/user/source/production/config.rst index 017e1a03930..70bce1349da 100644 --- a/doc/en/user/source/production/config.rst +++ b/doc/en/user/source/production/config.rst @@ -79,21 +79,21 @@ If you would like some users to be able to modify data, set the service level :g If you would like some users to be able to modify some but not all of your data, set the :guilabel:`Service Level` to ``Transactional`` (or ``Complete``), and use :ref:`security_layer` to limit write access to specific layers. Data security can be used to allow write access based on workspace, datastore, or layer security. -GeoServer Data Admin Guidance ------------------------------ +GeoServer Workspace Admin Guidance +---------------------------------- -Establishing a data administrator user is a recommended configuration to privileged users with limited access to the Admin Console to manage the publication of information, but are not intended to be trusted as a GeoServer Administrator with responsibility for the full global settings and system integration controls. +Establishing a workspace administrator user is a recommended configuration providing limited access to the Admin Console to manage the publication of information, but are not intended to be trusted as a GeoServer Administrator with responsibility for the global settings and system integration controls. -1. Create a role to be used for data administration. +1. Create a role to be used for workspace administration. -2. Provide this role to the Users (or Groups) requiring data admin access. +2. Provide this role to the Users (or Groups) requiring workspace admin access. 3. Provide this role :ref:`data security ` admin access ``a`` to: * :ref:`workspace ` administration * :ref:`layer ` administration -4. Recommendation: The combination of data admin permission for a workspace and GROUP_ADMIN access provides a good combination for an individual responsible for a workspace. This provides the ability to manage and control access to the data products in a workspace. +4. Recommendation: The combination of workspace admin permission and GROUP_ADMIN access provides a effective combination for an individual responsible for a workspace. This provides the ability to both manage and control access to the data products in a workspace. GeoServer Administrator Guidance -------------------------------- diff --git a/doc/en/user/source/services/wms/get_legend_graphic/index.rst b/doc/en/user/source/services/wms/get_legend_graphic/index.rst index 34a2ff049b4..ee73d5cacf2 100644 --- a/doc/en/user/source/services/wms/get_legend_graphic/index.rst +++ b/doc/en/user/source/services/wms/get_legend_graphic/index.rst @@ -234,14 +234,14 @@ In order to support it the GetLegendGraphic call needs the following extra param * BBOX * SRS or CRS (depending on the WMS version, SRS for 1.1.1 and CRS for 1.3.0) * SRCWIDTH and SRCHEIGHT, the size of the reference map (width and height already have a different meaning in GetLegendGraphic) + +and the following LEGEND_OPTIONS parameters: + + * countMatched: adds the number of features matching the particular rule at the end of the rule label (requires visible labels to work). Applicable only to vector layers. + * hideEmptyRules: hides rules that are not matching any feature. Other parameters can also be added to better match the GetMap request, for example, it is recommended to mirror filtering vendor parameters such as, for example, CQL_FILTER,FILTER,FEATUREID,TIME,ELEVATION. - -Content dependent evaluation is enabled via the following LEGEND_OPTIONS parameters: - - * countMatched: adds the number of features matching the particular rule at the end of the rule label (requires visible labels to work). Applicable only to vector layers. - * hideEmptyRules: hides rules that are not matching any feature. Applicable only if countMatched is true. For example, let's assume the following layout is added to GeoServer (``legend.xml`` to be placed in ``GEOSERVER_DATA_DIR/layouts``):: diff --git a/doc/en/user/source/webadmin/index.rst b/doc/en/user/source/webadmin/index.rst index e30cacfa29d..f211d8e2071 100644 --- a/doc/en/user/source/webadmin/index.rst +++ b/doc/en/user/source/webadmin/index.rst @@ -45,7 +45,7 @@ Data The :ref:`Data` section contains configuration options for all the different data-related settings. -* The :ref:`Layer Preview ` page provides links to layer previews in various output formats, including the common OpenLayers and KML formats. This page helps to visually verify and explore the configuration of a particular layer. +* The :ref:`Layer Preview ` page provides links to layer previews in different output formats, including the frequently used OpenLayers and KML formats. This page helps to visually verify and explore the configuration of a particular layer. **You do not need to be logged into GeoServer to access the Layer Preview.** @@ -61,7 +61,7 @@ The :ref:`Data` section contains configuration options for all the different dat In each of these pages that contain a table, there are three different ways to locate an object: sorting, searching, and paging. To alphabetically sort a data type, click on the column header. For simple searching, enter the search criteria in the search box and hit Enter. And to page through the entries (25 at a time), use the arrow buttons located on the bottom and top of the table. -**These pages are shown to administrators, and users that have data admin permissions.** +**These pages are shown to administrators, and users that have workspace or layer admin permissions.** Services -------- diff --git a/src/community/app-schema/webservice-test/pom.xml b/src/community/app-schema/webservice-test/pom.xml index 9339032858e..7f8f693428e 100644 --- a/src/community/app-schema/webservice-test/pom.xml +++ b/src/community/app-schema/webservice-test/pom.xml @@ -46,12 +46,10 @@ org.geotools gt-webservice - ${gt.version} org.geotools gt-webservice - ${gt.version} tests test @@ -62,7 +60,6 @@ org.geotools gt-jdbc - ${gt.version} test-jar test @@ -73,7 +70,6 @@ org.geotools gt-app-schema - ${gt.version} tests test diff --git a/src/community/backup-restore/pom.xml b/src/community/backup-restore/pom.xml index 7c837b961a6..fa6fb0edf50 100644 --- a/src/community/backup-restore/pom.xml +++ b/src/community/backup-restore/pom.xml @@ -51,7 +51,6 @@ org.geotools.jdbc gt-jdbc-h2 - ${gt.version} test diff --git a/src/community/cog/cog-s3/src/assembly/assembly.xml b/src/community/cog/cog-s3/src/assembly/assembly.xml index 305c1a95c5c..1e8ed93c2c6 100644 --- a/src/community/cog/cog-s3/src/assembly/assembly.xml +++ b/src/community/cog/cog-s3/src/assembly/assembly.xml @@ -27,6 +27,7 @@ imageio-ext-*rangereader*.jar jackson-datatype*.jar jackson-module*.jar + json-utils-2.*.jar kotlin-stdlib*.jar *netty*.jar okhttp*.jar @@ -35,6 +36,8 @@ protocol-core-2.*.jar reactive-streams*.jar regions-2.*.jar + retries-2.*.jar + retries-spi-2.*.jar rxjava*.jar s3-2.*.jar sdk-core-2.*.jar @@ -45,6 +48,7 @@ http-auth-*2*.jar identity-spi*.jar metrics-spi-2.*.jar + third-party-jackson-core-2.*.jar diff --git a/src/community/cog/pom.xml b/src/community/cog/pom.xml index 937b2ec10ed..21bd65235a6 100644 --- a/src/community/cog/pom.xml +++ b/src/community/cog/pom.xml @@ -30,7 +30,6 @@ org.geotools gt-geotiff - ${gt.version} org.geoserver.web @@ -57,7 +56,6 @@ org.geotools.jdbc gt-jdbc-h2 - ${gt.version} test diff --git a/src/community/datadir-catalog-loader/pom.xml b/src/community/datadir-catalog-loader/pom.xml index a6d57bfc929..9e9c558a920 100644 --- a/src/community/datadir-catalog-loader/pom.xml +++ b/src/community/datadir-catalog-loader/pom.xml @@ -33,7 +33,6 @@ org.geotools.jdbc gt-jdbc-postgis - ${gt.version} test diff --git a/src/community/dds/pom.xml b/src/community/dds/pom.xml index f8437bb1d36..9c1e91ccb4a 100644 --- a/src/community/dds/pom.xml +++ b/src/community/dds/pom.xml @@ -60,7 +60,6 @@ org.geotools gt-sample-data - ${gt.version} org.geoserver diff --git a/src/community/elasticsearch/pom.xml b/src/community/elasticsearch/pom.xml index 117e7c9e193..47232d3bc54 100644 --- a/src/community/elasticsearch/pom.xml +++ b/src/community/elasticsearch/pom.xml @@ -20,7 +20,6 @@ org.geotools gt-elasticsearch - ${gt.version} diff --git a/src/community/features-autopopulate/features-autopopulate-core/pom.xml b/src/community/features-autopopulate/features-autopopulate-core/pom.xml index 806b58cbd7f..53ff0507bc6 100644 --- a/src/community/features-autopopulate/features-autopopulate-core/pom.xml +++ b/src/community/features-autopopulate/features-autopopulate-core/pom.xml @@ -33,7 +33,6 @@ org.geotools gt-main - ${gt.version} org.geoserver @@ -57,26 +56,22 @@ org.geotools gt-sample-data - ${gt.version} test org.geotools gt-jdbc - ${gt.version} tests test org.geotools gt-jdbc - ${gt.version} test org.geotools.jdbc gt-jdbc-postgis - ${gt.version} test diff --git a/src/community/features-templating/features-templating-core/pom.xml b/src/community/features-templating/features-templating-core/pom.xml index a0b7dae6949..6df84057e8c 100644 --- a/src/community/features-templating/features-templating-core/pom.xml +++ b/src/community/features-templating/features-templating-core/pom.xml @@ -33,17 +33,14 @@ org.geotools gt-main - ${gt.version} org.geotools gt-complex - ${gt.version} org.geotools gt-geojson-core - ${gt.version} com.github.jsonld-java @@ -53,17 +50,14 @@ org.geotools gt-app-schema - ${gt.version} org.geotools gt-http - ${gt.version} org.geotools gt-referencing - ${gt.version} org.geoserver @@ -88,33 +82,28 @@ org.geotools gt-app-schema - ${gt.version} tests test org.geotools gt-sample-data - ${gt.version} test org.geotools gt-jdbc - ${gt.version} tests test org.geotools gt-jdbc - ${gt.version} test org.geotools.jdbc gt-jdbc-postgis - ${gt.version} test diff --git a/src/community/features-templating/features-templating-ogcapi/pom.xml b/src/community/features-templating/features-templating-ogcapi/pom.xml index 61a213fc49a..305317c1e52 100644 --- a/src/community/features-templating/features-templating-ogcapi/pom.xml +++ b/src/community/features-templating/features-templating-ogcapi/pom.xml @@ -75,13 +75,11 @@ org.geotools gt-app-schema - ${gt.version} test org.geotools gt-app-schema - ${gt.version} tests test @@ -95,26 +93,22 @@ org.geotools gt-sample-data - ${gt.version} test org.geotools gt-jdbc - ${gt.version} tests test org.geotools gt-jdbc - ${gt.version} test org.geotools.jdbc gt-jdbc-postgis - ${gt.version} test diff --git a/src/community/features-templating/features-templating-ows/pom.xml b/src/community/features-templating/features-templating-ows/pom.xml index fc27d6c1828..c158b545915 100644 --- a/src/community/features-templating/features-templating-ows/pom.xml +++ b/src/community/features-templating/features-templating-ows/pom.xml @@ -71,7 +71,6 @@ org.geotools gt-app-schema - ${gt.version} test @@ -91,33 +90,28 @@ org.geotools gt-app-schema - ${gt.version} tests test org.geotools gt-sample-data - ${gt.version} test org.geotools gt-jdbc - ${gt.version} tests test org.geotools gt-jdbc - ${gt.version} test org.geotools.jdbc gt-jdbc-postgis - ${gt.version} test diff --git a/src/community/features-templating/features-templating-rest/pom.xml b/src/community/features-templating/features-templating-rest/pom.xml index 78dc44d4360..0a5fb99931a 100644 --- a/src/community/features-templating/features-templating-rest/pom.xml +++ b/src/community/features-templating/features-templating-rest/pom.xml @@ -37,7 +37,6 @@ org.geotools gt-http - ${gt.version} org.geoserver diff --git a/src/community/features-templating/features-templating-web/pom.xml b/src/community/features-templating/features-templating-web/pom.xml index fc062f9a3ba..6bff437ac36 100644 --- a/src/community/features-templating/features-templating-web/pom.xml +++ b/src/community/features-templating/features-templating-web/pom.xml @@ -32,7 +32,6 @@ org.geotools gt-http - ${gt.version} org.geoserver diff --git a/src/community/flatgeobuf/pom.xml b/src/community/flatgeobuf/pom.xml index 9b28f2e11a3..7304f95541b 100644 --- a/src/community/flatgeobuf/pom.xml +++ b/src/community/flatgeobuf/pom.xml @@ -26,7 +26,6 @@ org.geotools gt-flatgeobuf - ${gt.version} diff --git a/src/community/geopkg/pom.xml b/src/community/geopkg/pom.xml index b4217808393..216cc7e3b7d 100644 --- a/src/community/geopkg/pom.xml +++ b/src/community/geopkg/pom.xml @@ -50,17 +50,14 @@ org.geotools gt-process - ${gt.version} org.geotools gt-geopkg - ${gt.version} org.geotools gt-render - ${gt.version} org.geoserver.extension @@ -96,7 +93,6 @@ org.geotools gt-sample-data - ${gt.version} test diff --git a/src/community/graticule/pom.xml b/src/community/graticule/pom.xml index 96ca91559d9..309a42debfa 100644 --- a/src/community/graticule/pom.xml +++ b/src/community/graticule/pom.xml @@ -47,7 +47,6 @@ org.geotools gt-graticule - ${gt.version} org.apache.wicket diff --git a/src/community/gsr/pom.xml b/src/community/gsr/pom.xml index 1a743f046c4..460383398ff 100644 --- a/src/community/gsr/pom.xml +++ b/src/community/gsr/pom.xml @@ -43,7 +43,6 @@ org.geotools gt-main - ${gt.version} net.sf.json-lib @@ -91,7 +90,6 @@ org.geotools gt-main - ${gt.version} tests test diff --git a/src/community/importer-jdbc/pom.xml b/src/community/importer-jdbc/pom.xml index 605d2b5923b..71ae7e521b4 100644 --- a/src/community/importer-jdbc/pom.xml +++ b/src/community/importer-jdbc/pom.xml @@ -20,7 +20,6 @@ org.geotools gt-transform - ${gt.version} org.geoserver.importer @@ -65,7 +64,6 @@ org.geotools gt-sample-data - ${gt.version} test diff --git a/src/community/mbtiles-store/pom.xml b/src/community/mbtiles-store/pom.xml index b5186b11ecb..86eb88627a6 100644 --- a/src/community/mbtiles-store/pom.xml +++ b/src/community/mbtiles-store/pom.xml @@ -20,7 +20,6 @@ org.geotools gt-mbtiles - ${gt.version} diff --git a/src/community/mbtiles/pom.xml b/src/community/mbtiles/pom.xml index 89a9bd5fef6..2b261e4fdbe 100644 --- a/src/community/mbtiles/pom.xml +++ b/src/community/mbtiles/pom.xml @@ -40,12 +40,10 @@ org.geotools gt-mbtiles - ${gt.version} org.geotools gt-render - ${gt.version} org.geoserver.extension @@ -81,7 +79,6 @@ org.geotools gt-sample-data - ${gt.version} test diff --git a/src/community/ncwms/pom.xml b/src/community/ncwms/pom.xml index 72f32cb2d42..609dfac311c 100644 --- a/src/community/ncwms/pom.xml +++ b/src/community/ncwms/pom.xml @@ -22,7 +22,6 @@ org.geotools gt-brewer - ${gt.version} org.geoserver.community @@ -72,7 +71,6 @@ org.geotools gt-iau-wkt - ${gt.version} test diff --git a/src/community/netcdf-ghrsst/pom.xml b/src/community/netcdf-ghrsst/pom.xml index 3e1faf9fd38..802fe0e8db1 100644 --- a/src/community/netcdf-ghrsst/pom.xml +++ b/src/community/netcdf-ghrsst/pom.xml @@ -30,7 +30,7 @@ org.apache.logging.log4j - log4j-slf4j-impl + log4j-slf4j2-impl @@ -42,7 +42,6 @@ org.geotools gt-netcdf - ${gt.version} slf4j-api diff --git a/src/community/ogcapi/dggs/dggs-clickhouse/pom.xml b/src/community/ogcapi/dggs/dggs-clickhouse/pom.xml index d87a4d2c25d..83abbfe6e13 100644 --- a/src/community/ogcapi/dggs/dggs-clickhouse/pom.xml +++ b/src/community/ogcapi/dggs/dggs-clickhouse/pom.xml @@ -31,7 +31,6 @@ org.geotools gt-jdbc - ${gt.version} com.clickhouse @@ -46,20 +45,17 @@ org.geotools gt-jdbc - ${gt.version} tests test org.geotools gt-sample-data - ${gt.version} test org.geotools gt-epsg-hsql - ${gt.version} test diff --git a/src/community/ogcapi/dggs/dggs-clickhouse/src/main/java/org/geotools/dggs/clickhouse/ClickHouseDGGSDataStore.java b/src/community/ogcapi/dggs/dggs-clickhouse/src/main/java/org/geotools/dggs/clickhouse/ClickHouseDGGSDataStore.java index eed2458c18c..0092273f22c 100644 --- a/src/community/ogcapi/dggs/dggs-clickhouse/src/main/java/org/geotools/dggs/clickhouse/ClickHouseDGGSDataStore.java +++ b/src/community/ogcapi/dggs/dggs-clickhouse/src/main/java/org/geotools/dggs/clickhouse/ClickHouseDGGSDataStore.java @@ -196,7 +196,7 @@ public FeatureReader getFeatureReader( DGGSFeatureSource source = getFeatureSource(query.getTypeName()); @SuppressWarnings("PMD.CloseResource") // wrapped and returned SimpleFeatureIterator features = source.getFeatures(query).features(); - return new FeatureReader() { + return new FeatureReader<>() { @Override public SimpleFeatureType getFeatureType() { return source.getSchema(); diff --git a/src/community/ogcapi/dggs/dggs-clickhouse/src/main/java/org/geotools/dggs/clickhouse/ClickhouseAggregatorCollection.java b/src/community/ogcapi/dggs/dggs-clickhouse/src/main/java/org/geotools/dggs/clickhouse/ClickhouseAggregatorCollection.java index 374202dd4f8..121ab93ac80 100644 --- a/src/community/ogcapi/dggs/dggs-clickhouse/src/main/java/org/geotools/dggs/clickhouse/ClickhouseAggregatorCollection.java +++ b/src/community/ogcapi/dggs/dggs-clickhouse/src/main/java/org/geotools/dggs/clickhouse/ClickhouseAggregatorCollection.java @@ -58,9 +58,8 @@ public void accepts(FeatureVisitor visitor, ProgressListener progress) throws IO if (visit((MatrixAggregate) visitor)) return; } else if (visitor instanceof GroupedMatrixAggregate) { if (visit((GroupedMatrixAggregate) visitor)) return; - } else { - delegate.accepts(visitor, progress); } + delegate.accepts(visitor, progress); } private boolean visit(MatrixAggregate visitor) throws IOException { diff --git a/src/community/ogcapi/dggs/dggs-core/pom.xml b/src/community/ogcapi/dggs/dggs-core/pom.xml index b955f77602f..ee47db7ec6a 100644 --- a/src/community/ogcapi/dggs/dggs-core/pom.xml +++ b/src/community/ogcapi/dggs/dggs-core/pom.xml @@ -30,12 +30,10 @@ org.geotools gt-main - ${gt.version} org.geotools gt-render - ${gt.version} @@ -52,13 +50,11 @@ org.geotools gt-epsg-hsql - ${gt.version} test org.geotools gt-shapefile - ${gt.version} test diff --git a/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/ZoneWrapper.java b/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/ZoneWrapper.java index 0ff89cd46d5..cfe1c62ecd2 100644 --- a/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/ZoneWrapper.java +++ b/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/ZoneWrapper.java @@ -41,7 +41,7 @@ public enum DatelineLocation { West, /** Crossing the dateline, majority of points in the east empisphere */ East - }; + } /** * Wraps a dateline crossing polygon so that its longitudes are all packed on one side. Will not diff --git a/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/h3/H3DGGSInstance.java b/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/h3/H3DGGSInstance.java index da5a4ff842b..e55c6e0d63b 100644 --- a/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/h3/H3DGGSInstance.java +++ b/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/h3/H3DGGSInstance.java @@ -101,6 +101,7 @@ public H3Zone getZone(double lat, double lon, int resolution) { } @Override + @SuppressWarnings("PMD.UnnecessaryCast") public Iterator zonesFromEnvelope( Envelope envelope, int targetResolution, boolean compact) { Envelope intersection = envelope.intersection(WORLD); @@ -287,6 +288,7 @@ public List getExtraProperties() { } @Override + @SuppressWarnings("PMD.UnnecessaryCast") public Iterator neighbors(String id, int radius) { // Using H3 facilities. Upside fast and accurate (considering dateline and pole neighbors // too), downside, will quickly go OOM, radius should be limited @@ -324,6 +326,7 @@ public Zone point(Point point, int resolution) { } @Override + @SuppressWarnings("PMD.UnnecessaryCast") public Iterator polygon(Polygon polygon, int resolution, boolean compact) { List shell = getGeoCoords(polygon.getExteriorRing()); List> holes = diff --git a/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/rhealpix/RHealPixDGGSFactory.java b/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/rhealpix/RHealPixDGGSFactory.java index 7dfd794904d..bd40935febc 100644 --- a/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/rhealpix/RHealPixDGGSFactory.java +++ b/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/rhealpix/RHealPixDGGSFactory.java @@ -53,15 +53,19 @@ public DGGSInstance createInstance(Map params) throws IOException { @Override public boolean isAvailable() { JEPWebRuntime runtime = new JEPWebRuntime(INITIALIZER); + boolean interpreterFound = false; try { runtime.getInterpreter(); + interpreterFound = true; return true; - } catch (Exception | UnsatisfiedLinkError e) { + // JEP throws an UnsatisfiedLinkError if the native library is not found the first time, + // but from the second time over, it throws a generic Error instead + } catch (Exception | Error e) { LOGGER.log(Level.FINE, "Could not instantiate a rHEALPix DGGS", e); return false; } finally { try { - JEPWebRuntime.closeThreadIntepreter(); + if (interpreterFound) JEPWebRuntime.closeThreadIntepreter(); } catch (JepException e) { LOGGER.log(Level.FINE, "Could not clean up the JEP runtime", e); } diff --git a/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/rhealpix/RHealPixDGGSInstance.java b/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/rhealpix/RHealPixDGGSInstance.java index 48993c6d801..1c9dd75224d 100644 --- a/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/rhealpix/RHealPixDGGSInstance.java +++ b/src/community/ogcapi/dggs/dggs-core/src/main/java/org/geotools/dggs/rhealpix/RHealPixDGGSInstance.java @@ -140,6 +140,7 @@ private String toZoneId(List idList) { } @Override + @SuppressWarnings("PMD.UnnecessaryCast") public Iterator zonesFromEnvelope( Envelope envelope, int targetResolution, boolean compact) { // WAY USING DIRECT LIBRARY CALLS. Faster, but memory bound. @@ -374,6 +375,7 @@ public List getExtraProperties() { } @Override + @SuppressWarnings("PMD.UnnecessaryCast") public Iterator neighbors(String id, int radius) { Set result = new HashSet<>(); // temporary add to work as an exclusion mask too @@ -417,6 +419,7 @@ public Iterator neighbors(String id, int radius) { } @Override + @SuppressWarnings("PMD.UnnecessaryCast") public Iterator children(String zoneId, int resolution) { Zone parent = getZone(zoneId); if (parent.getResolution() >= resolution) return new EmptyIterator<>(); @@ -480,7 +483,7 @@ public Iterator polygon(Polygon polygon, int resolution, boolean compact) && testContains(prepared, zone.getCenter())) || testContains(prepared, zone.getBoundary()); }, - zone -> (Zone) zone); + zone -> zone); // if compact iteration, we are done if (compact) return compactIterator; // otherwise expand the cells that are at a lower resolution using the fast children diff --git a/src/community/ogcapi/dggs/dggs-core/src/test/java/org/geotools/dggs/rhealpix/RHealPixDGGSFactoryTest.java b/src/community/ogcapi/dggs/dggs-core/src/test/java/org/geotools/dggs/rhealpix/RHealPixDGGSFactoryTest.java new file mode 100644 index 00000000000..0e9771221d8 --- /dev/null +++ b/src/community/ogcapi/dggs/dggs-core/src/test/java/org/geotools/dggs/rhealpix/RHealPixDGGSFactoryTest.java @@ -0,0 +1,22 @@ +/* (c) 2024 Open Source Geospatial Foundation - all rights reserved + * This code is licensed under the GPL 2.0 license, available at the root + * application directory. + */ +package org.geotools.dggs.rhealpix; + +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +public class RHealPixDGGSFactoryTest { + + @Test + public void testIsAvailable() throws Exception { + RHealPixDGGSFactory rHealPixDGGSFactory = new RHealPixDGGSFactory(); + // if JEP is available, nothing bad will happen + if (!rHealPixDGGSFactory.isAvailable()) { + // but if not available, this second call used to throw an uncaught Error + assertFalse(rHealPixDGGSFactory.isAvailable()); + } + } +} diff --git a/src/community/ogcapi/dggs/ogcapi-dggs/src/main/java/org/geoserver/ogcapi/v1/dggs/CollectionsDocument.java b/src/community/ogcapi/dggs/ogcapi-dggs/src/main/java/org/geoserver/ogcapi/v1/dggs/CollectionsDocument.java index b0c086d9acc..3415b02dc1d 100644 --- a/src/community/ogcapi/dggs/ogcapi-dggs/src/main/java/org/geoserver/ogcapi/v1/dggs/CollectionsDocument.java +++ b/src/community/ogcapi/dggs/ogcapi-dggs/src/main/java/org/geoserver/ogcapi/v1/dggs/CollectionsDocument.java @@ -40,11 +40,11 @@ public List getLinks() { } @JacksonXmlProperty(localName = "Collection") - @SuppressWarnings({"PMD.CloseResource", "PMD.EmptyWhileStmt"}) + @SuppressWarnings({"PMD.CloseResource", "PMD.EmptyControlStatement"}) public Iterator getCollections() { CloseableIterator featureTypes = geoServer.getCatalog().list(FeatureTypeInfo.class, Filter.INCLUDE); - return new Iterator() { + return new Iterator<>() { CollectionDocument next; diff --git a/src/community/ogcapi/dggs/ogcapi-dggs/src/main/java/org/geoserver/ogcapi/v1/dggs/DGGSDAPAExtension.java b/src/community/ogcapi/dggs/ogcapi-dggs/src/main/java/org/geoserver/ogcapi/v1/dggs/DGGSDAPAExtension.java index cdf13f9067e..331f1f82ee5 100644 --- a/src/community/ogcapi/dggs/ogcapi-dggs/src/main/java/org/geoserver/ogcapi/v1/dggs/DGGSDAPAExtension.java +++ b/src/community/ogcapi/dggs/ogcapi-dggs/src/main/java/org/geoserver/ogcapi/v1/dggs/DGGSDAPAExtension.java @@ -196,9 +196,7 @@ public SimpleFeatureCollection areaSpaceAggregation( q.getHints().put(VIRTUAL_TABLE_PARAMETERS, singletonMap(VP_RESOLUTION, resolution)); SimpleFeatureSource fs = (SimpleFeatureSource) ft.getFeatureSource(null, null); List expressions = - Arrays.stream(variables) - .map(v -> (Expression) FF.property(v)) - .collect(Collectors.toList()); + Arrays.stream(variables).map(v -> FF.property(v)).collect(Collectors.toList()); // run a full aggregate and build the feature List timeGroupExpressions = getTimeGroup(ft); GroupedMatrixAggregate aggregate = @@ -283,9 +281,7 @@ public SimpleFeatureCollection areaTimeAggregation( q.getHints().put(VIRTUAL_TABLE_PARAMETERS, singletonMap(VP_RESOLUTION, resolution)); SimpleFeatureSource fs = (SimpleFeatureSource) ft.getFeatureSource(null, null); List expressions = - Arrays.stream(variables) - .map(v -> (Expression) FF.property(v)) - .collect(Collectors.toList()); + Arrays.stream(variables).map(v -> FF.property(v)).collect(Collectors.toList()); // run a full aggregate and build the feature GroupedMatrixAggregate aggregate = new GroupedMatrixAggregate( @@ -360,9 +356,7 @@ public SimpleFeatureCollection areaSpaceTimeAggregation( q.getHints().put(VIRTUAL_TABLE_PARAMETERS, singletonMap(VP_RESOLUTION, resolution)); SimpleFeatureSource fs = (SimpleFeatureSource) ft.getFeatureSource(null, null); List expressions = - Arrays.stream(variables) - .map(v -> (Expression) FF.property(v)) - .collect(Collectors.toList()); + Arrays.stream(variables).map(v -> FF.property(v)).collect(Collectors.toList()); // run a full aggregate and build the feature MatrixAggregate aggregate = new MatrixAggregate(expressions, Arrays.asList(functions)); fs.getFeatures(q).accepts(aggregate, null); @@ -476,9 +470,7 @@ public SimpleFeatureCollection positionTimeAggregate( q.getHints().put(VIRTUAL_TABLE_PARAMETERS, singletonMap(VP_RESOLUTION, resolution)); SimpleFeatureSource fs = (SimpleFeatureSource) ft.getFeatureSource(null, null); List expressions = - Arrays.stream(variables) - .map(v -> (Expression) FF.property(v)) - .collect(Collectors.toList()); + Arrays.stream(variables).map(v -> FF.property(v)).collect(Collectors.toList()); // run a full aggregate and build the feature GroupedMatrixAggregate aggregate = new GroupedMatrixAggregate( diff --git a/src/community/ogcapi/dggs/ogcapi-dggs/src/main/java/org/geoserver/ogcapi/v1/dggs/GroupMatrixFeatureCollection.java b/src/community/ogcapi/dggs/ogcapi-dggs/src/main/java/org/geoserver/ogcapi/v1/dggs/GroupMatrixFeatureCollection.java index a35b11bd1e2..30ca97dbbd2 100644 --- a/src/community/ogcapi/dggs/ogcapi-dggs/src/main/java/org/geoserver/ogcapi/v1/dggs/GroupMatrixFeatureCollection.java +++ b/src/community/ogcapi/dggs/ogcapi-dggs/src/main/java/org/geoserver/ogcapi/v1/dggs/GroupMatrixFeatureCollection.java @@ -116,7 +116,7 @@ public boolean containsAll(Collection o) { @Override public boolean isEmpty() { try (CloseableIterator it = result.getIterator()) { - return features().hasNext(); + return it.hasNext(); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/src/community/ogcapi/dggs/ogcapi-dggs/src/test/java/org/geoserver/ogcapi/v1/dggs/ConformanceTest.java b/src/community/ogcapi/dggs/ogcapi-dggs/src/test/java/org/geoserver/ogcapi/v1/dggs/ConformanceTest.java index 70083dd9170..822aa2a00d6 100644 --- a/src/community/ogcapi/dggs/ogcapi-dggs/src/test/java/org/geoserver/ogcapi/v1/dggs/ConformanceTest.java +++ b/src/community/ogcapi/dggs/ogcapi-dggs/src/test/java/org/geoserver/ogcapi/v1/dggs/ConformanceTest.java @@ -31,7 +31,7 @@ public void testConformanceJson() throws Exception { @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/dggs/v1/conformance?f=application/x-yaml"); + String yaml = getAsString("ogc/dggs/v1/conformance?f=application/yaml"); checkConformance(convertYamlToJsonPath(yaml)); } diff --git a/src/community/ogcapi/dggs/ogcapi-dggs/src/test/java/org/geoserver/ogcapi/v1/dggs/LandingPageTest.java b/src/community/ogcapi/dggs/ogcapi-dggs/src/test/java/org/geoserver/ogcapi/v1/dggs/LandingPageTest.java index 25ba31bfba6..32a0283b404 100644 --- a/src/community/ogcapi/dggs/ogcapi-dggs/src/test/java/org/geoserver/ogcapi/v1/dggs/LandingPageTest.java +++ b/src/community/ogcapi/dggs/ogcapi-dggs/src/test/java/org/geoserver/ogcapi/v1/dggs/LandingPageTest.java @@ -91,15 +91,15 @@ public void testLandingPageXML() throws Exception { @Test public void testLandingPageYaml() throws Exception { - String yaml = getAsString("ogc/dggs/v1?f=application/x-yaml"); + String yaml = getAsString("ogc/dggs/v1?f=application/yaml"); DocumentContext json = convertYamlToJsonPath(yaml); assertJSONList( json, - "links[?(@.type == 'application/x-yaml' && @.href =~ /.*ogc\\/dggs\\/v1\\/\\?.*/)].rel", + "links[?(@.type == 'application/yaml' && @.href =~ /.*ogc\\/dggs\\/v1\\/\\?.*/)].rel", "self"); assertJSONList( json, - "links[?(@.type != 'application/x-yaml' && @.href =~ /.*ogc\\/dggs\\/v1\\/\\?.*/)].rel", + "links[?(@.type != 'application/yaml' && @.href =~ /.*ogc\\/dggs\\/v1\\/\\?.*/)].rel", "alternate", "alternate"); checkJSONLandingPageShared(json); diff --git a/src/community/ogcapi/ogcapi-changeset/pom.xml b/src/community/ogcapi/ogcapi-changeset/pom.xml index 2d0283f34ef..6e1b0d67f6e 100644 --- a/src/community/ogcapi/ogcapi-changeset/pom.xml +++ b/src/community/ogcapi/ogcapi-changeset/pom.xml @@ -36,7 +36,6 @@ org.geotools.jdbc gt-jdbc-h2 - ${gt.version} org.geoserver diff --git a/src/community/ogcapi/ogcapi-changeset/src/main/java/org/geoserver/ogcapi/v1/changeset/ChangeSet.java b/src/community/ogcapi/ogcapi-changeset/src/main/java/org/geoserver/ogcapi/v1/changeset/ChangeSet.java index 57a14b8abc3..9b4b2e6980f 100644 --- a/src/community/ogcapi/ogcapi-changeset/src/main/java/org/geoserver/ogcapi/v1/changeset/ChangeSet.java +++ b/src/community/ogcapi/ogcapi-changeset/src/main/java/org/geoserver/ogcapi/v1/changeset/ChangeSet.java @@ -20,7 +20,7 @@ enum Priority { high, medium, low - }; + } public static class ChangedItem { Priority priority; diff --git a/src/community/ogcapi/ogcapi-core/pom.xml b/src/community/ogcapi/ogcapi-core/pom.xml index 2edee21560d..d57df177b4f 100644 --- a/src/community/ogcapi/ogcapi-core/pom.xml +++ b/src/community/ogcapi/ogcapi-core/pom.xml @@ -86,7 +86,6 @@ org.geotools gt-geojson-core - ${gt.version} org.geoserver @@ -129,7 +128,6 @@ org.geotools gt-jdbc - ${gt.version} test-jar test @@ -148,13 +146,11 @@ org.geotools gt-app-schema - ${gt.version} test org.geotools gt-app-schema - ${gt.version} tests test diff --git a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/APIBBoxParser.java b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/APIBBoxParser.java index a835b85fcda..581b582224d 100644 --- a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/APIBBoxParser.java +++ b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/APIBBoxParser.java @@ -105,7 +105,7 @@ private static Filter toFilter(ReferencedEnvelope[] bboxes) { return FF.bbox(FF.property(""), bboxes[0]); } else if (bboxes instanceof ReferencedEnvelope[]) { List filters = - Stream.of((ReferencedEnvelope[]) bboxes) + Stream.of(bboxes) .map(e -> FF.bbox(FF.property(""), e)) .collect(Collectors.toList()); return FF.or(filters); diff --git a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/APIDispatcher.java b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/APIDispatcher.java index 81e2f008891..1a7a6f0d3b2 100644 --- a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/APIDispatcher.java +++ b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/APIDispatcher.java @@ -352,7 +352,7 @@ private void dispatchService(Request dr, HandlerMethod handler) { public static APIService getApiServiceAnnotation(Class clazz) { APIService annotation = null; while (annotation == null && clazz != null) { - annotation = (APIService) clazz.getAnnotation(APIService.class); + annotation = clazz.getAnnotation(APIService.class); if (annotation == null) { clazz = clazz.getSuperclass(); } diff --git a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/ConformanceClass.java b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/ConformanceClass.java index cccb8e85961..138cb1976d9 100644 --- a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/ConformanceClass.java +++ b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/ConformanceClass.java @@ -20,11 +20,14 @@ public class ConformanceClass { * CQL filtering conformance classes, shared here to allow STAC using them, without depending on * ogc-api-features directly */ - public static final String FEATURES_FILTER = - "http://www.opengis.net/spec/ogcapi-features-3/1.0/req/features-filter"; + public static final String QUERYABLES = + "http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables"; public static final String FILTER = - "http://www.opengis.net/spec/ogcapi-features-3/1.0/req/filter"; + "http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/filter"; + + public static final String FEATURES_FILTER = + "http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/features-filter"; /** Sorting conformance class from OGC API - Records. */ public static final String SORTBY = diff --git a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/FunctionsDocument.java b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/FunctionsDocument.java index ff7371eff88..9dbc23477fb 100644 --- a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/FunctionsDocument.java +++ b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/FunctionsDocument.java @@ -5,6 +5,7 @@ package org.geoserver.ogcapi; import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Optional; @@ -16,7 +17,7 @@ /** A document enumerating the available functions */ @JsonInclude(JsonInclude.Include.NON_NULL) -public class FunctionsDocument { +public class FunctionsDocument extends AbstractDocument { public static final String REL = "http://www.opengis.net/def/rel/ogc/1.0/functions"; @@ -49,12 +50,14 @@ public AttributeType[] getType() { public static class Function { String name; String description; - Argument returns; + List returns; List arguments; Function(FunctionName fn) { this.name = fn.getName(); - this.returns = toParameter(fn.getReturn()); + this.returns = + Arrays.stream(toParameter(fn.getReturn()).getType()) + .collect(Collectors.toList()); this.description = null; // no support for descriptions in GeoTools functions this.arguments = fn.getArguments().stream() @@ -66,7 +69,7 @@ public String getName() { return name; } - public Argument getReturns() { + public List getReturns() { return returns; } @@ -92,6 +95,8 @@ public FunctionsDocument() { .map(Function::new) .distinct() .collect(Collectors.toList()); + + addSelfLinks("ogc/features/v1/functions"); } private static boolean isSimpleFunction(FunctionName functionName) { diff --git a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/MappingJackson2YAMLMessageConverter.java b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/MappingJackson2YAMLMessageConverter.java index da6aee70c37..af9df0834e3 100644 --- a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/MappingJackson2YAMLMessageConverter.java +++ b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/MappingJackson2YAMLMessageConverter.java @@ -6,15 +6,19 @@ import com.fasterxml.jackson.annotation.JsonIgnoreType; import io.swagger.v3.core.util.Yaml; +import java.io.IOException; import java.lang.reflect.Type; import org.geoserver.rest.wrapper.RestWrapper; +import org.springframework.http.ContentDisposition; +import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter; /** Message converter encoding a Java bean into YAML using Jackson */ public class MappingJackson2YAMLMessageConverter extends AbstractJackson2HttpMessageConverter { - public static final String APPLICATION_YAML_VALUE = "application/x-yaml"; + public static final String APPLICATION_YAML_VALUE = "application/yaml"; public static final MediaType APPLICATION_YAML = MediaType.parseMediaType(APPLICATION_YAML_VALUE); @@ -53,4 +57,16 @@ static boolean canJacksonHandle(Class clazz) { return clazz.getAnnotation(JsonIgnoreType.class) == null && !RestWrapper.class.isAssignableFrom(clazz); } + + @Override + protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage) + throws IOException, HttpMessageNotWritableException { + ContentDisposition disposition = + ContentDisposition.builder("inline") + .filename(object.getClass().getSimpleName() + ".yaml") + .build(); + outputMessage.getHeaders().setContentDisposition(disposition); + + super.writeInternal(object, type, outputMessage); + } } diff --git a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/Queryables.java b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/Queryables.java index dd68590d18a..930f7ca5614 100644 --- a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/Queryables.java +++ b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/Queryables.java @@ -19,8 +19,10 @@ public class Queryables extends Schema { public static final String REL = "http://www.opengis.net/def/rel/ogc/1.0/queryables"; + public static final String JSON_SCHEMA_DRAFT_2020_12 = + "https://json-schema.org/draft/2020-12/schema"; - private final String schema = "https://json-schema.org/draft/2019-09/schema"; + private final String schema = JSON_SCHEMA_DRAFT_2020_12; private String id; diff --git a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/QueryablesBuilder.java b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/QueryablesBuilder.java index d6377467f74..318c65efc49 100644 --- a/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/QueryablesBuilder.java +++ b/src/community/ogcapi/ogcapi-core/src/main/java/org/geoserver/ogcapi/QueryablesBuilder.java @@ -8,13 +8,16 @@ import io.swagger.v3.oas.models.media.Schema; import java.io.IOException; +import java.net.URL; import java.util.LinkedHashMap; import java.util.Map; import java.util.Optional; +import java.util.UUID; import java.util.stream.Collectors; import org.geoserver.catalog.FeatureTypeInfo; import org.geotools.api.feature.type.FeatureType; -import org.geotools.api.feature.type.PropertyType; +import org.geotools.api.feature.type.PropertyDescriptor; +import org.geotools.feature.FeatureTypes; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; import org.locationtech.jts.geom.MultiLineString; @@ -25,23 +28,13 @@ public class QueryablesBuilder { - public static final String POINT_SCHEMA_REF = "https://geojson.org/schema/Point.json"; - public static final String MULTIPOINT_SCHEMA_REF = "https://geojson.org/schema/MultiPoint.json"; - public static final String LINESTRING_SCHEMA_REF = "https://geojson.org/schema/LineString.json"; - public static final String MULTILINESTRING_SCHEMA_REF = - "https://geojson.org/schema/MultiLineString.json"; - public static final String POLYGON_SCHEMA_REF = "https://geojson.org/schema/Polygon.json"; - public static final String MULTIPOLYGON_SCHEMA_REF = - "https://geojson.org/schema/MultiPolygon.json"; - public static final String GEOMETRY_SCHEMA_REF = "https://geojson.org/schema/Geometry.json"; - public static final String POINT = "Point"; public static final String MULTIPOINT = "MultiPoint"; public static final String LINESTRING = "LineString"; public static final String MULTILINESTRING = "MultiLineString"; public static final String POLYGON = "Polygon"; public static final String MULTIPOLYGON = "MultiPolygon"; - public static final String GENERIC_GEOMETRY = "Generic geometry"; + public static final String GENERIC_GEOMETRY = "Any geometry"; public static final String DATE = "Date"; public static final String DATE_TIME = "DateTime"; public static final String TIME = "Time"; @@ -68,7 +61,7 @@ public QueryablesBuilder forType(FeatureType ft) { .collect( Collectors.toMap( ad -> ad.getName().getLocalPart(), - ad -> getSchema(ad.getType()), + ad -> getSchema(ad), (u, v) -> { throw new IllegalStateException( String.format("Duplicate key %s", u)); @@ -78,9 +71,14 @@ public QueryablesBuilder forType(FeatureType ft) { return this; } - private Schema getSchema(PropertyType type) { - Class binding = type.getBinding(); - return getSchema(binding); + private Schema getSchema(PropertyDescriptor descriptor) { + Class binding = descriptor.getType().getBinding(); + Schema schema = getSchema(binding); + int fieldLength = FeatureTypes.getFieldLength(descriptor); + if (fieldLength != FeatureTypes.ANY_LENGTH) { + schema.setMaxLength(fieldLength); + } + return schema; } /** Returns the schema for a given data type */ @@ -90,34 +88,31 @@ public static Schema getSchema(Class binding) { } private static Schema getGeometrySchema(Class binding) { - Schema schema = new Schema(); - String ref; - String description; + Schema schema = new Schema<>(); + String title; if (Point.class.isAssignableFrom(binding)) { - ref = POINT_SCHEMA_REF; - description = POINT; + title = POINT; } else if (MultiPoint.class.isAssignableFrom(binding)) { - ref = MULTIPOINT_SCHEMA_REF; - description = MULTIPOINT; + title = MULTIPOINT; } else if (LineString.class.isAssignableFrom(binding)) { - ref = LINESTRING_SCHEMA_REF; - description = LINESTRING; + title = LINESTRING; } else if (MultiLineString.class.isAssignableFrom(binding)) { - ref = MULTILINESTRING_SCHEMA_REF; - description = MULTILINESTRING; + title = MULTILINESTRING; } else if (Polygon.class.isAssignableFrom(binding)) { - ref = POLYGON_SCHEMA_REF; - description = POLYGON; + title = POLYGON; } else if (MultiPolygon.class.isAssignableFrom(binding)) { - ref = MULTIPOLYGON_SCHEMA_REF; - description = MULTIPOLYGON; + title = MULTIPOLYGON; + } else { + title = GENERIC_GEOMETRY; + } + + schema.setTitle(title); + if (title.equals(GENERIC_GEOMETRY)) { + schema.setFormat("geometry-any"); } else { - ref = GEOMETRY_SCHEMA_REF; - description = GENERIC_GEOMETRY; + schema.setFormat("geometry-" + title.toLowerCase()); } - schema.set$ref(ref); - schema.setDescription(description); return schema; } @@ -131,16 +126,20 @@ public static Schema getAlphanumericSchema(Class binding) { Schema schema = new Schema<>(); schema.setType(org.geoserver.ogcapi.AttributeType.fromClass(binding).getType()); - schema.setDescription(schema.getType()); + schema.setTitle(schema.getType()); if (java.sql.Date.class.isAssignableFrom(binding)) { schema.setFormat("date"); - schema.setDescription(DATE); + schema.setTitle(DATE); } else if (java.sql.Time.class.isAssignableFrom(binding)) { schema.setFormat("time"); - schema.setDescription(TIME); + schema.setTitle(TIME); } else if (java.util.Date.class.isAssignableFrom(binding)) { schema.setFormat("date-time"); - schema.setDescription(DATE_TIME); + schema.setTitle(DATE_TIME); + } else if (UUID.class.isAssignableFrom(binding)) { + schema.setFormat("uuid"); + } else if (URL.class.isAssignableFrom(binding)) { + schema.setTitle("uri"); } return schema; } diff --git a/src/community/ogcapi/ogcapi-core/src/main/resources/org/geoserver/ogcapi/queryables.ftl b/src/community/ogcapi/ogcapi-core/src/main/resources/org/geoserver/ogcapi/queryables.ftl index 280c2b4ff6a..305e9372e46 100644 --- a/src/community/ogcapi/ogcapi-core/src/main/resources/org/geoserver/ogcapi/queryables.ftl +++ b/src/community/ogcapi/ogcapi-core/src/main/resources/org/geoserver/ogcapi/queryables.ftl @@ -13,7 +13,7 @@ <#if model.getProperties()??>
    <#list model.getProperties() as name, definition> -
  • ${name}: ${definition.getDescription()}
  • +
  • ${name}: ${definition.getTitle()}
<#else> diff --git a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/APIBBoxParserTest.java b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/APIBBoxParserTest.java new file mode 100644 index 00000000000..a391bb51953 --- /dev/null +++ b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/APIBBoxParserTest.java @@ -0,0 +1,179 @@ +/* (c) 2024 Open Source Geospatial Foundation - all rights reserved + * This code is licensed under the GPL 2 license, available at the root + * application directory. + */ +package org.geoserver.ogcapi; + +import static org.geotools.referencing.crs.DefaultGeographicCRS.WGS84_3D; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.geotools.api.filter.Filter; +import org.geotools.api.filter.Or; +import org.geotools.api.filter.expression.PropertyName; +import org.geotools.api.filter.spatial.BBOX; +import org.geotools.api.geometry.BoundingBox; +import org.geotools.api.referencing.FactoryException; +import org.geotools.factory.CommonFactoryFinder; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.geotools.geometry.jts.ReferencedEnvelope3D; +import org.geotools.referencing.CRS; +import org.geotools.referencing.crs.DefaultGeographicCRS; +import org.junit.Test; +import org.locationtech.jts.geom.Envelope; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.MultiPolygon; +import org.locationtech.jts.geom.Polygon; + +public class APIBBoxParserTest { + + private static final double EPS = 0001; + public static final String BBOX_3D_SPEC = "10,20,5,30,40,15"; + public static final String BBOX_2D_SPEC = "10,20,30,40"; + private static PropertyName DEFAULT_GEOMETRY = + CommonFactoryFinder.getFilterFactory().property(""); + + @Test + public void testParse2DBBox() throws FactoryException { + ReferencedEnvelope[] result = APIBBoxParser.parse(BBOX_2D_SPEC); + + assertNotNull(result); + assertEquals(1, result.length); + ReferencedEnvelope envelope = result[0]; + assertEnvelope(envelope, 10, 20, 30, 40); + assertEquals(DefaultGeographicCRS.WGS84, envelope.getCoordinateReferenceSystem()); + } + + @Test + public void testToFilter2DBBox() throws FactoryException { + Filter boxFilter = APIBBoxParser.toFilter(BBOX_2D_SPEC); + + assertNotNull(boxFilter); + assertThat(boxFilter, instanceOf(BBOX.class)); + BBOX bboxFilter = (BBOX) boxFilter; + assertEnvelope(bboxFilter.getBounds(), 10, 20, 30, 40); + assertEquals( + DefaultGeographicCRS.WGS84, bboxFilter.getBounds().getCoordinateReferenceSystem()); + assertEquals(DEFAULT_GEOMETRY, bboxFilter.getExpression1()); + } + + @Test + public void testParse3DBBox() throws FactoryException { + ReferencedEnvelope[] result = APIBBoxParser.parse(BBOX_3D_SPEC); + + assertNotNull(result); + assertEquals(1, result.length); + ReferencedEnvelope envelope = result[0]; + assertEnvelope(envelope, 10, 20, 5, 30, 40, 15); + assertEquals(WGS84_3D, envelope.getCoordinateReferenceSystem()); + } + + @Test + public void testToFilter3DBBox() throws FactoryException { + Filter boxFilter = APIBBoxParser.toFilter(BBOX_3D_SPEC); + + assertNotNull(boxFilter); + assertThat(boxFilter, instanceOf(BBOX.class)); + BBOX bboxFilter = (BBOX) boxFilter; + assertEnvelope(bboxFilter.getBounds(), 10, 20, 5, 30, 40, 15); + assertEquals(WGS84_3D, bboxFilter.getBounds().getCoordinateReferenceSystem()); + assertEquals(DEFAULT_GEOMETRY, bboxFilter.getExpression1()); + } + + @Test + public void testParse2DBBoxWithCRS() throws FactoryException { + String bbox = BBOX_2D_SPEC; + String crs = "EPSG:4326"; + ReferencedEnvelope[] result = APIBBoxParser.parse(bbox, crs); + + assertNotNull(result); + assertEquals(1, result.length); + ReferencedEnvelope envelope = result[0]; + assertEnvelope(envelope, 10, 20, 30, 40); + assertNotNull(envelope.getCoordinateReferenceSystem()); + assertEquals(crs, CRS.lookupIdentifier(envelope.getCoordinateReferenceSystem(), false)); + } + + @Test + public void testParseDatelineSpan() throws FactoryException { + ReferencedEnvelope[] result = APIBBoxParser.parse("160, 20, -160, 40"); + + assertNotNull(result); + assertEquals(2, result.length); + assertEnvelope(result[0], 160, 20, 180, 40); + assertEquals(DefaultGeographicCRS.WGS84, result[0].getCoordinateReferenceSystem()); + assertEnvelope(result[1], -180, 20, -160, 40); + assertEquals(DefaultGeographicCRS.WGS84, result[1].getCoordinateReferenceSystem()); + } + + @Test + public void testFilterDatelineSpan() throws FactoryException { + Filter filter = APIBBoxParser.toFilter("160, 20, -160, 40"); + + assertThat(filter, instanceOf(Or.class)); + Or or = (Or) filter; + assertThat(or.getChildren().get(0), instanceOf(BBOX.class)); + assertThat(or.getChildren().get(1), instanceOf(BBOX.class)); + + BBOX bbox1 = (BBOX) or.getChildren().get(0); + assertEnvelope(bbox1.getBounds(), 160, 20, 180, 40); + assertEquals(DefaultGeographicCRS.WGS84, bbox1.getBounds().getCoordinateReferenceSystem()); + assertEquals(DEFAULT_GEOMETRY, bbox1.getExpression1()); + + BBOX bbox2 = (BBOX) or.getChildren().get(1); + assertEnvelope(bbox2.getBounds(), -180, 20, -160, 40); + assertEquals(DefaultGeographicCRS.WGS84, bbox2.getBounds().getCoordinateReferenceSystem()); + assertEquals(DEFAULT_GEOMETRY, bbox2.getExpression1()); + } + + @Test + public void testToGeometryDatelineSpan() throws FactoryException { + Geometry geometry = APIBBoxParser.toGeometry("160, 20, -160, 40"); + + assertThat(geometry, instanceOf(MultiPolygon.class)); + Polygon p1 = (Polygon) geometry.getGeometryN(0); + assertTrue(p1.isRectangle()); + assertEquals(new Envelope(160, 180, 20, 40), p1.getEnvelopeInternal()); + Polygon p2 = (Polygon) geometry.getGeometryN(1); + assertTrue(p2.isRectangle()); + assertEquals(new Envelope(-180, -160, 20, 40), p2.getEnvelopeInternal()); + } + + @Test + public void testParse3DBBoxWithCRS() throws FactoryException { + String bbox = BBOX_3D_SPEC; + String crs = "EPSG:4326"; + ReferencedEnvelope[] result = APIBBoxParser.parse(bbox, crs); + + assertNotNull(result); + assertEquals(1, result.length); + ReferencedEnvelope envelope = result[0]; + assertEnvelope(envelope, 10, 20, 5, 30, 40, 15); + assertNotNull(envelope.getCoordinateReferenceSystem()); + assertEquals(crs, CRS.lookupIdentifier(envelope.getCoordinateReferenceSystem(), false)); + } + + private void assertEnvelope(BoundingBox bounds, double... expected) { + assertEnvelope(ReferencedEnvelope.reference(bounds), expected); + } + + private static void assertEnvelope(ReferencedEnvelope envelope, double... expected) { + if (expected.length == 6) { + ReferencedEnvelope3D envelope3D = (ReferencedEnvelope3D) envelope; + assertEquals(expected[0], envelope3D.getMinX(), EPS); + assertEquals(expected[1], envelope3D.getMinY(), EPS); + assertEquals(expected[2], envelope3D.getMinZ(), EPS); + assertEquals(expected[3], envelope3D.getMaxX(), EPS); + assertEquals(expected[4], envelope3D.getMaxY(), EPS); + assertEquals(expected[5], envelope3D.getMaxZ(), EPS); + } else { + assertEquals(expected[0], envelope.getMinX(), EPS); + assertEquals(expected[1], envelope.getMinY(), EPS); + assertEquals(expected[2], envelope.getMaxX(), EPS); + assertEquals(expected[3], envelope.getMaxY(), EPS); + } + } +} diff --git a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/APIRequestInfoTest.java b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/APIRequestInfoTest.java new file mode 100644 index 00000000000..044249ddc33 --- /dev/null +++ b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/APIRequestInfoTest.java @@ -0,0 +1,149 @@ +/* (c) 2024 Open Source Geospatial Foundation - all rights reserved + * This code is licensed under the GPL 2.0 license, available at the root + * application directory. + */ +package org.geoserver.ogcapi; + +import static org.geoserver.ogcapi.MappingJackson2YAMLMessageConverter.APPLICATION_YAML; +import static org.geoserver.ogcapi.MappingJackson2YAMLMessageConverter.APPLICATION_YAML_VALUE; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.springframework.http.MediaType.APPLICATION_JSON; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; +import net.sf.json.JSONObject; +import org.geoserver.ows.Request; +import org.geoserver.ows.TestDispatcherCallback; +import org.geoserver.platform.Operation; +import org.geoserver.platform.Service; +import org.geoserver.test.GeoServerSystemTestSupport; +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Test; +import org.springframework.http.MediaType; + +/** + * Test class for APIRequestInfo, uses custom callbacks to test the APIRequestInfo object (as it's + * available during the request processing) + */ +public class APIRequestInfoTest extends GeoServerSystemTestSupport { + + @Before + public void cleanupCallbacks() throws Exception { + APIDispatcher dispatcher = getAPIDispatcher(); + dispatcher.callbacks.removeIf(c -> c instanceof TestDispatcherCallback); + } + + @Test + public void testProducibleMediaTypes() throws Exception { + testDuringOperationExecuted( + ri -> { + Collection mediaTypes = + ri.getProducibleMediaTypes(Message.class, true); + assertThat(mediaTypes, Matchers.hasItems(APPLICATION_JSON, APPLICATION_YAML)); + }); + } + + @Test + public void testLandingPage() throws Exception { + testDuringOperationExecuted(ri -> assertEquals("ogc/hello/v1", ri.getServiceLandingPage())); + } + + @Test + public void testService() throws Exception { + testDuringOperationExecuted( + ri -> { + Service service = ri.getService(); + assertEquals("Hello", service.getId()); + assertThat(service.getService(), Matchers.instanceOf(HelloService.class)); + }); + } + + @Test + public void testIsFormatRequested() throws Exception { + testDuringOperationExecuted( + ri -> { + assertTrue(ri.isFormatRequested(APPLICATION_JSON, APPLICATION_JSON)); + }); + } + + @Test + public void testQueryMap() throws Exception { + APIDispatcher dispatcher = getAPIDispatcher(); + dispatcher.callbacks.add( + new TestDispatcherCallback() { + @Override + public Object operationExecuted( + Request request, Operation operation, Object result) { + APIRequestInfo ri = APIRequestInfo.get(); + assertThat(ri.getSimpleQueryMap(), Matchers.hasEntry("k1", "v1")); + assertThat(ri.getSimpleQueryMap(), Matchers.hasEntry("k2", "v2")); + + return null; + } + }); + // check no exceptions have been thrown + JSONObject json = (JSONObject) getAsJSON("ogc/hello/v1?k1=v1&k2=v2"); + assertEquals("Landing page", json.get("message")); + } + + @Test + public void getLinks() throws Exception { + testDuringOperationExecuted( + ri -> { + List links = + ri.getLinksFor( + "ogc/hello/v1/echo", + Message.class, + "Message as ", + "alternate", + true, + "test", + null); + assertEquals(4, links.size()); + + // check the links are correctly built + Set mimeTypes = new HashSet<>(); + for (Link link : links) { + assertEquals("alternate", link.getRel()); + assertEquals("test", link.getClassification()); + assertEquals("Message as " + link.getType(), link.getTitle()); + mimeTypes.add(link.getType()); + } + assertThat( + mimeTypes, + Matchers.hasItems( + MediaType.APPLICATION_JSON_VALUE, + MediaType.TEXT_HTML_VALUE, + MediaType.TEXT_PLAIN_VALUE, + APPLICATION_YAML_VALUE)); + }); + } + + private APIDispatcher getAPIDispatcher() { + return applicationContext.getBean(APIDispatcher.class); + } + + private void testDuringOperationExecuted(Consumer consumer) throws Exception { + APIDispatcher dispatcher = getAPIDispatcher(); + dispatcher.callbacks.add( + new TestDispatcherCallback() { + @Override + public Object operationExecuted( + Request request, Operation operation, Object result) { + APIRequestInfo ri = APIRequestInfo.get(); + consumer.accept(ri); + + return null; + } + }); + // check no exceptions have been thrown + JSONObject json = (JSONObject) getAsJSON("ogc/hello/v1/"); + assertEquals("Landing page", json.get("message")); + } +} diff --git a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/ApiConfigurationSupportTest.java b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/ApiConfigurationSupportTest.java index c6e75c7ae24..96d8574cd52 100644 --- a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/ApiConfigurationSupportTest.java +++ b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/ApiConfigurationSupportTest.java @@ -115,7 +115,7 @@ public void testReadWithControllerContext() { return ((GenericHttpMessageConverter) c) .canRead( Message.class, - HelloController.class, + HelloService.class, MediaType.APPLICATION_JSON); else return c.canRead(Message.class, MediaType.APPLICATION_JSON); }); diff --git a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/DateTimeConverterTest.java b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/DateTimeConverterTest.java new file mode 100644 index 00000000000..a2c89b37779 --- /dev/null +++ b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/DateTimeConverterTest.java @@ -0,0 +1,102 @@ +/* (c) 2024 Open Source Geospatial Foundation - all rights reserved + * This code is licensed under the GPL 2.0 license, available at the root + * application directory. + */ +package org.geoserver.ogcapi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; +import org.geotools.util.DateRange; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +public class DateTimeConverterTest { + + private DateTimeConverter dateTimeConverter; + private SimpleDateFormat dateFormat; + + @Before + public void setUp() { + // Ensure tests are not timezone dependent + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + dateTimeConverter = new DateTimeConverter(); + dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + @Test + public void testSingleDate() throws ParseException { + String input = "2023-10-01T12:00:00.000Z"; + Date expected = dateFormat.parse("2023-10-01T12:00:00.000Z"); + DateTimeList result = dateTimeConverter.convert(input); + assertEquals(1, result.size()); + assertTrue(result.get(0) instanceof Date); + assertEquals(expected, result.get(0)); + } + + @Test + public void testIntervalClosed() throws ParseException { + String input = "2023-10-01T12:00:00.000Z/2023-10-01T14:00:00.000Z"; + Date start = dateFormat.parse("2023-10-01T12:00:00.000Z"); + Date end = dateFormat.parse("2023-10-01T14:00:00.000Z"); + DateTimeList result = dateTimeConverter.convert(input); + assertEquals(1, result.size()); + assertTrue(result.get(0) instanceof DateRange); + DateRange range = (DateRange) result.get(0); + assertEquals(start, range.getMinValue()); + assertEquals(end, range.getMaxValue()); + } + + @Test + @Ignore // see TODO in DateTimeConverter + public void testIntervalOpenStart() throws ParseException { + String input = "../2023-10-01T14:00:00.000Z"; + Date end = dateFormat.parse("2023-10-01T14:00:00.000Z"); + DateTimeList result = dateTimeConverter.convert(input); + assertEquals(1, result.size()); + assertTrue(result.get(0) instanceof DateRange); + DateRange range = (DateRange) result.get(0); + assertNull(range.getMinValue()); + assertEquals(end, range.getMaxValue()); + } + + @Test + @Ignore // see TODO in DateTimeConverter + public void testIntervalOpenEnd() throws ParseException { + String input = "2023-10-01T12:00:00.000Z/.."; + Date start = dateFormat.parse("2023-10-01T12:00:00.000Z"); + DateTimeList result = dateTimeConverter.convert(input); + assertEquals(1, result.size()); + assertTrue(result.get(0) instanceof DateRange); + DateRange range = (DateRange) result.get(0); + assertEquals(start, range.getMinValue().toInstant()); + assertNull(range.getMaxValue()); + } + + @Test + public void testSequenceWithSingleTimesAndIntervals() throws ParseException { + String input = + "2023-10-01T11:00:00.000Z,2023-10-01T12:00:00.000Z/2023-10-01T14:00:00.000Z,2023-10-01T15:00:00.000Z"; + Date date1 = dateFormat.parse("2023-10-01T11:00:00.000Z"); + Date date2 = dateFormat.parse("2023-10-01T12:00:00.000Z"); + Date date3 = dateFormat.parse("2023-10-01T14:00:00.000Z"); + Date date4 = dateFormat.parse("2023-10-01T15:00:00.000Z"); + DateTimeList result = dateTimeConverter.convert(input); + assertEquals(3, result.size()); + assertTrue(result.get(0) instanceof Date); + assertEquals(date1, result.get(0)); + assertTrue(result.get(1) instanceof DateRange); + DateRange range = (DateRange) result.get(1); + assertEquals(date2, range.getMinValue()); + assertEquals(date3, range.getMaxValue()); + assertTrue(result.get(2) instanceof Date); + assertEquals(date4, result.get(2)); + } +} diff --git a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloDocument.java b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloDocument.java new file mode 100644 index 00000000000..22e2aec54f9 --- /dev/null +++ b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloDocument.java @@ -0,0 +1,17 @@ +/* (c) 2024 Open Source Geospatial Foundation - all rights reserved + * This code is licensed under the GPL 2.0 license, available at the root + * application directory. + */ +package org.geoserver.ogcapi; + +public class HelloDocument extends AbstractDocument { + String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloResponseMessageConverter.java b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloResponseMessageConverter.java new file mode 100644 index 00000000000..76951a6023a --- /dev/null +++ b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloResponseMessageConverter.java @@ -0,0 +1,16 @@ +/* (c) 2024 Open Source Geospatial Foundation - all rights reserved + * This code is licensed under the GPL 2.0 license, available at the root + * application directory. + */ +package org.geoserver.ogcapi; + +import org.springframework.stereotype.Component; + +/** Helps testing the bridge between OWS responses and OGC APIs */ +@Component +public class HelloResponseMessageConverter extends MessageConverterResponseAdapter { + + public HelloResponseMessageConverter() { + super(Message.class, Message.class); + } +} diff --git a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloController.java b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloService.java similarity index 67% rename from src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloController.java rename to src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloService.java index c6fdba23817..c9fe5896492 100644 --- a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloController.java +++ b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloService.java @@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletResponse; import org.geoserver.config.ServiceInfo; +import org.geoserver.config.impl.ServiceInfoImpl; import org.geoserver.ows.HttpErrorCodeException; import org.geoserver.platform.ServiceException; import org.springframework.http.HttpHeaders; @@ -26,13 +27,25 @@ service = "Hello", version = "1.0.1", landingPage = "ogc/hello/v1", - serviceClass = HelloController.HelloServiceInfo.class) + serviceClass = HelloService.HelloServiceInfo.class) @RequestMapping(path = APIDispatcher.ROOT_PATH + "/hello/v1") -public class HelloController { +public class HelloService { - static interface HelloServiceInfo extends ServiceInfo {}; + public static final String DEFAULT_GREETING = "hello"; + private final HelloServiceInfoImpl serviceInfo; - String defaultValue = "hello"; + static interface HelloServiceInfo extends ServiceInfo {} + + static class HelloServiceInfoImpl extends ServiceInfoImpl implements HelloServiceInfo {} + + String defaultValue = DEFAULT_GREETING; + + public HelloService() { + this.serviceInfo = new HelloServiceInfoImpl(); + this.serviceInfo.setName("Hello"); + this.serviceInfo.setTitle("Hello Service"); + this.serviceInfo.setEnabled(true); + } @GetMapping(name = "landingPage") @ResponseBody @@ -40,7 +53,7 @@ public Message landingPage() { return new Message("Landing page"); } - @GetMapping(path = "hello", name = "sayHello") + @GetMapping(path = DEFAULT_GREETING, name = "sayHello") @ResponseBody public Message hello(@RequestParam(name = "message", required = false) String message) { return new Message(message != null ? message : defaultValue); @@ -51,13 +64,13 @@ public Message hello(@RequestParam(name = "message", required = false) String me public ResponseEntity echo(@RequestBody Message message) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.TEXT_PLAIN); - return new ResponseEntity(message.getMessage(), headers, HttpStatus.CREATED); + return new ResponseEntity<>(message.getMessage(), headers, HttpStatus.CREATED); } @DeleteMapping(path = "delete") @ResponseBody public ResponseEntity delete() { - return new ResponseEntity(HttpStatus.NO_CONTENT); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); } @PutMapping(path = "default") @@ -89,4 +102,19 @@ public void httpErrorCodeExceptionWithContentType() { throw new HttpErrorCodeException(HttpServletResponse.SC_OK, "{\"hello\":\"world\"}") .setContentType("application/json"); } + + @GetMapping(path = "document", name = "document") + @ResponseBody + @HTMLResponseBody(templateName = "message.ftl", fileName = "message.html") + public HelloDocument document() { + HelloDocument doc = new HelloDocument(); + doc.setMessage(defaultValue); + doc.addSelfLinks("ogc/hello/v1/document"); + return doc; + } + + /** Used by the {@link org.geoserver.ows.DisabledServiceCheck} */ + public HelloServiceInfo getServiceInfo() { + return serviceInfo; + } } diff --git a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/APIDispatcherTest.java b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloServiceTest.java similarity index 71% rename from src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/APIDispatcherTest.java rename to src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloServiceTest.java index d903e471e7a..2fbd980995e 100644 --- a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/APIDispatcherTest.java +++ b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/HelloServiceTest.java @@ -6,11 +6,12 @@ package org.geoserver.ogcapi; +import static org.geoserver.ogcapi.MappingJackson2YAMLMessageConverter.APPLICATION_YAML_VALUE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.UnsupportedEncodingException; -import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.LinkedHashMap; import java.util.Map; @@ -18,17 +19,17 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import javax.servlet.http.HttpServletResponse; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; import org.geoserver.ows.Request; import org.geoserver.ows.Response; import org.geoserver.ows.TestDispatcherCallback; import org.geoserver.platform.Operation; import org.geoserver.platform.Service; import org.geoserver.test.CodeExpectingHttpServletResponse; -import org.junit.After; +import org.geoserver.test.GeoServerSystemTestSupport; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; -import org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletRequest; @@ -36,25 +37,23 @@ import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.servlet.handler.DispatcherServletWebRequest; -@Ignore -public class APIDispatcherTest { - - private FileSystemXmlApplicationContext applicationContext; +public class HelloServiceTest extends GeoServerSystemTestSupport { @Before - public void setup() { - URL url = getClass().getResource("applicationContext.xml"); - this.applicationContext = new FileSystemXmlApplicationContext(url.toString()); + public void cleanupCallbacks() throws Exception { + APIDispatcher dispatcher = getAPIDispatcher(); + dispatcher.callbacks.removeIf(c -> c instanceof TestDispatcherCallback); } - @After - public void teardown() { - this.applicationContext.close(); + @Before + public void cleanupDefaultValue() throws Exception { + HelloService controller = applicationContext.getBean(HelloService.class); + controller.defaultValue = HelloService.DEFAULT_GREETING; } @Test public void testDefaultFormat() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); MockHttpServletRequest request = setupHelloRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); @@ -67,7 +66,7 @@ public void testDefaultFormat() throws Exception { @Test public void testQueryParameters() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); MockHttpServletRequest request = setupHelloRequest("message", "yo", "f", "json"); MockHttpServletResponse response = new MockHttpServletResponse(); @@ -79,37 +78,38 @@ public void testQueryParameters() throws Exception { } @Test - @Ignore // restore when XML is back as supported format - public void testXMLFormatQueryParameter() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + public void testYAMLFormatQueryParameter() throws Exception { + APIDispatcher dispatcher = getAPIDispatcher(); - MockHttpServletRequest request = setupHelloRequest("f", "xml"); + MockHttpServletRequest request = setupHelloRequest("f", "yaml"); MockHttpServletResponse response = new MockHttpServletResponse(); dispatcher.handleRequest(request, response); assertEquals(200, response.getStatus()); - assertEquals(MediaType.APPLICATION_XML_VALUE, response.getContentType()); - assertEquals("hello", response.getContentAsString()); + assertEquals(APPLICATION_YAML_VALUE, response.getContentType()); + assertEquals( + "inline; filename=\"Message.yaml\"", + response.getHeader(HttpHeaders.CONTENT_DISPOSITION)); + assertEquals("message: hello\n", response.getContentAsString()); } @Test - @Ignore // restore when XML is back as supported format - public void testXMLFormatAcceptHeader() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + public void testYAMLFormatAcceptHeader() throws Exception { + APIDispatcher dispatcher = getAPIDispatcher(); MockHttpServletRequest request = setupHelloRequest(); - request.addHeader(HttpHeaders.ACCEPT, "application/xml"); + request.addHeader(HttpHeaders.ACCEPT, APPLICATION_YAML_VALUE); MockHttpServletResponse response = new MockHttpServletResponse(); dispatcher.handleRequest(request, response); assertEquals(200, response.getStatus()); - assertEquals(MediaType.APPLICATION_XML_VALUE, response.getContentType()); - assertEquals("hello", response.getContentAsString()); + assertEquals(APPLICATION_YAML_VALUE, response.getContentType()); + assertEquals("message: hello\n", response.getContentAsString()); } @Test public void testPostRequest() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); String message = "{\"message\":\"Is there anyone here?\"}"; MockHttpServletRequest request = setupEchoRequest(message, "f", "json"); @@ -124,7 +124,7 @@ public void testPostRequest() throws Exception { @Test public void testDeleteRequest() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); MockHttpServletRequest request = setupDeleteRequest(); request.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); @@ -136,24 +136,23 @@ public void testDeleteRequest() throws Exception { @Test public void testPutRequest() throws Exception { - try (FileSystemXmlApplicationContext context = this.applicationContext) { - APIDispatcher dispatcher = context.getBean(APIDispatcher.class); - HelloController controller = context.getBean(HelloController.class); - - String newDefault = "ciao"; - MockHttpServletRequest request = setupPutRequest(newDefault); - request.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN); - MockHttpServletResponse response = new MockHttpServletResponse(); - dispatcher.handleRequest(request, response); - - assertEquals(200, response.getStatus()); - assertEquals(newDefault, controller.defaultValue); - } + + APIDispatcher dispatcher = applicationContext.getBean(APIDispatcher.class); + HelloService controller = applicationContext.getBean(HelloService.class); + + String newDefault = "ciao"; + MockHttpServletRequest request = setupPutRequest(newDefault); + request.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN); + MockHttpServletResponse response = new MockHttpServletResponse(); + dispatcher.handleRequest(request, response); + + assertEquals(200, response.getStatus()); + assertEquals(newDefault, controller.defaultValue); } @Test public void testDispatcherCallback() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); TestDispatcherCallback callback = new TestDispatcherCallback(); MockHttpServletRequest request = setupHelloRequest(); @@ -168,7 +167,7 @@ public void testDispatcherCallback() throws Exception { @Test public void testDispatcherCallbackOperationName() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); AtomicReference requestReference = new AtomicReference<>(); TestDispatcherCallback callback = new TestDispatcherCallback() { @@ -186,13 +185,13 @@ public Operation operationDispatched(Request request, Operation operation) { dispatcher.handleRequest(request, response); assertEquals(200, response.getStatus()); assertEquals("Hello", requestReference.get().getService()); - assertEquals("1.0", requestReference.get().getVersion()); + assertEquals("1.0.1", requestReference.get().getVersion()); assertEquals("sayHello", requestReference.get().getRequest()); } @Test public void testDispatcherCallbackFailInit() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); final TestDispatcherCallback callback1 = new TestDispatcherCallback(); final TestDispatcherCallback callback2 = new TestDispatcherCallback(); @@ -224,7 +223,7 @@ public Request init(Request request) { @Test public void testDispatcherCallbackFailServiceDispatched() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); final TestDispatcherCallback callback1 = new TestDispatcherCallback(); final TestDispatcherCallback callback2 = new TestDispatcherCallback(); TestDispatcherCallback callbackFail = @@ -254,7 +253,7 @@ public Service serviceDispatched(Request request, Service service) { @Test public void testDispatcherCallbackFailOperationDispatched() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); final TestDispatcherCallback callback1 = new TestDispatcherCallback(); final TestDispatcherCallback callback2 = new TestDispatcherCallback(); TestDispatcherCallback callbackFail = @@ -283,7 +282,7 @@ public Operation operationDispatched(Request request, Operation operation) { @Test public void testDispatcherCallbackFailOperationExecuted() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); final TestDispatcherCallback callback1 = new TestDispatcherCallback(); final TestDispatcherCallback callback2 = new TestDispatcherCallback(); TestDispatcherCallback callbackFail = @@ -314,7 +313,7 @@ public Object operationExecuted( @Test public void testDispatcherCallbackFailResponseDispatched() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); final TestDispatcherCallback callback1 = new TestDispatcherCallback(); final TestDispatcherCallback callback2 = new TestDispatcherCallback(); TestDispatcherCallback callbackFail = @@ -348,7 +347,7 @@ public Response responseDispatched( @Test public void testDispatcherCallbackFailFinished() throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); final AtomicBoolean firedCallback = new AtomicBoolean(false); TestDispatcherCallback callback1 = new TestDispatcherCallback(); TestDispatcherCallback callback2 = @@ -407,14 +406,90 @@ public void testHttpErrorCodeExceptionWithContentType() throws Exception { assertEquals("application/json", rsp.getContentType()); } + @Test + public void testDocumentDefaultMime() throws Exception { + MockHttpServletResponse response = getAsServletResponse("ogc/hello/v1/document"); + assertEquals(MediaType.APPLICATION_JSON_VALUE, response.getContentType()); + JSONObject json = (JSONObject) json(response); + // links to self and alternate representations + assertEquals("hello", json.get("message")); + JSONArray links = json.getJSONArray("links"); + assertEquals(3, links.size()); + for (int i = 0; i < links.size(); i++) { + JSONObject link = links.getJSONObject(i); + if ("self".equals(link.getString("rel"))) { + assertEquals("This document", link.getString("title")); + assertEquals("application/json", link.getString("type")); + assertEquals( + "http://localhost:8080/geoserver/ogc/hello/v1/document?f=application%2Fjson", + link.getString("href")); + } else if ("alternate".equals(link.getString("rel")) + && "application/yaml".equals(link.getString("type"))) { + assertEquals("This document as application/yaml", link.getString("title")); + assertEquals( + "http://localhost:8080/geoserver/ogc/hello/v1/document?f=application%2Fyaml", + link.getString("href")); + } else if ("alternate".equals(link.getString("rel"))) { + assertEquals("This document as text/html", link.getString("title")); + assertEquals("text/html", link.getString("type")); + assertEquals( + "http://localhost:8080/geoserver/ogc/hello/v1/document?f=text%2Fhtml", + link.getString("href")); + } else { + fail("Unexpected link: " + link); + } + } + } + + @Test + public void testDocumentHTML() throws Exception { + MockHttpServletResponse response = getAsServletResponse("ogc/hello/v1/document?f=html"); + assertEquals(MediaType.TEXT_HTML_VALUE, response.getContentType()); + // Testing: + // - the message is in the body + // - service link generation + // - resource link generation + String expected = + "\n" + + "\n" + + " \n" + + "\n" + + "\n" + + "

The message: hello

\n" + + "

Capabilities URL

\n" + + "\n" + + ""; + assertEquals(expected, response.getContentAsString()); + } + + @Test + public void testHelloPlainText() throws Exception { + MockHttpServletResponse response = getAsServletResponse("ogc/hello/v1/hello?f=text/plain"); + assertEquals(MediaType.TEXT_PLAIN_VALUE, response.getContentType()); + assertEquals("hello", response.getContentAsString()); + } + + @Test + public void testeServiceDisabled() throws Exception { + HelloService hs = applicationContext.getBean(HelloService.class); + try { + hs.getServiceInfo().setEnabled(false); + MockHttpServletResponse response = getAsServletResponse("ogc/hello/v1"); + assertEquals(404, response.getStatus()); + assertEquals("Service Hello is disabled", response.getErrorMessage()); + } finally { + hs.getServiceInfo().setEnabled(true); + } + } + private CodeExpectingHttpServletResponse assertHttpErrorCode(String path, int expectedCode) throws Exception { - APIDispatcher dispatcher = getDispatcher(); + APIDispatcher dispatcher = getAPIDispatcher(); MockHttpServletRequest request = setupRequestBase(); request.setMethod("GET"); - request.setPathInfo("/geoserver/ogc/" + path); - request.setRequestURI("/geoserver/ogc/" + path); + request.setPathInfo("/geoserver/ogc/hello/v1/" + path); + request.setRequestURI("/geoserver/ogc/hello/v1/" + path); CodeExpectingHttpServletResponse response = new CodeExpectingHttpServletResponse(new MockHttpServletResponse()); @@ -426,14 +501,14 @@ private CodeExpectingHttpServletResponse assertHttpErrorCode(String path, int ex return response; } - private APIDispatcher getDispatcher() { + private APIDispatcher getAPIDispatcher() { return applicationContext.getBean(APIDispatcher.class); } private MockHttpServletRequest setupDeleteRequest() { MockHttpServletRequest request = setupRequestBase(); - request.setPathInfo("/geoserver/ogc/delete"); - request.setRequestURI("/geoserver/ogc/delete"); + request.setPathInfo("/geoserver/ogc/hello/v1/delete"); + request.setRequestURI("/geoserver/ogc/hello/v1/delete"); request.setMethod("DELETE"); return request; @@ -441,10 +516,10 @@ private MockHttpServletRequest setupDeleteRequest() { private MockHttpServletRequest setupPutRequest(String message, String... params) { MockHttpServletRequest request = setupRequestBase(params); - request.setPathInfo("/geoserver/ogc/default"); + request.setPathInfo("/geoserver/ogc/hello/v1/default"); request.setMethod("PUT"); - request.setRequestURI("/geoserver/ogc/default"); + request.setRequestURI("/geoserver/ogc/hello/v1/default"); request.setContent(message.getBytes(StandardCharsets.UTF_8)); return request; @@ -452,10 +527,10 @@ private MockHttpServletRequest setupPutRequest(String message, String... params) private MockHttpServletRequest setupEchoRequest(String message, String... params) { MockHttpServletRequest request = setupRequestBase(params); - request.setPathInfo("/geoserver/ogc/hello"); + request.setPathInfo("/geoserver/ogc/hello/v1/hello"); request.setMethod("POST"); - request.setRequestURI("/geoserver/ogc/echo"); + request.setRequestURI("/geoserver/ogc/hello/v1/echo"); request.setContent(message.getBytes(StandardCharsets.UTF_8)); return request; @@ -463,9 +538,9 @@ private MockHttpServletRequest setupEchoRequest(String message, String... params private MockHttpServletRequest setupHelloRequest(String... params) { MockHttpServletRequest request = setupRequestBase(params); - request.setPathInfo("/geoserver/ogc/hello"); + request.setPathInfo("/geoserver/ogc/hello/v1/hello"); request.setMethod("GET"); - request.setRequestURI("/geoserver/ogc/hello"); + request.setRequestURI("/geoserver/ogc/hello/v1/hello"); return request; } diff --git a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/MessageResponse.java b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/MessageResponse.java new file mode 100644 index 00000000000..70be5d13cd3 --- /dev/null +++ b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/MessageResponse.java @@ -0,0 +1,35 @@ +/* (c) 2024 Open Source Geospatial Foundation - all rights reserved + * This code is licensed under the GPL 2.0 license, available at the root + * application directory. + */ +package org.geoserver.ogcapi; + +import java.io.IOException; +import java.io.OutputStream; +import org.geoserver.ows.Response; +import org.geoserver.platform.Operation; +import org.springframework.stereotype.Component; + +/** + * A response that writes a message to the output stream, used to test the bridge between OWS + * responses and OGC APIs + */ +@Component +public class MessageResponse extends Response { + public MessageResponse() { + super(Message.class, "text/plain"); + } + + @Override + public String getMimeType(Object value, Operation operation) { + return "text/plain"; + } + + @Override + public void write(Object value, OutputStream output, Operation operation) throws IOException { + Message message = (Message) value; + output.write(message.message.getBytes()); + } + + public void abort(Object value, OutputStream output, Operation operation) throws IOException {} +} diff --git a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/PaginationLinksBuilderTest.java b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/PaginationLinksBuilderTest.java new file mode 100644 index 00000000000..410a05c8f92 --- /dev/null +++ b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/PaginationLinksBuilderTest.java @@ -0,0 +1,61 @@ +/* (c) 2024 Open Source Geospatial Foundation - all rights reserved + * This code is licensed under the GPL 2.0 license, available at the root + * application directory. + */ +package org.geoserver.ogcapi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.easymock.EasyMock; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; + +public class PaginationLinksBuilderTest { + + public static final String PATH = "service/v1/resource"; + public static final String URL_BASE = "http://localhost/service/v1/resource"; + + @BeforeClass + public static void setupRequestInfo() { + RequestAttributes attributes = EasyMock.niceMock(RequestAttributes.class); + RequestContextHolder.setRequestAttributes(attributes); + APIRequestInfo requestInfo = + new APIRequestInfo( + new MockHttpServletRequest(), + new MockHttpServletResponse(), + EasyMock.mock(APIDispatcher.class)); + APIRequestInfo.set(requestInfo); + EasyMock.expect( + attributes.getAttribute( + APIRequestInfo.KEY, RequestAttributes.SCOPE_REQUEST)) + .andReturn(requestInfo) + .anyTimes(); + EasyMock.replay(attributes); + } + + @Test + public void testFirst() { + PaginationLinksBuilder builder = new PaginationLinksBuilder(PATH, 0, 5, 5, 250); + assertNull(builder.getPrevious()); + assertEquals(URL_BASE + "?startIndex=5&limit=5", builder.getNext()); + } + + @Test + public void testMid() { + PaginationLinksBuilder builder = new PaginationLinksBuilder(PATH, 5, 5, 5, 250); + assertEquals(URL_BASE + "?startIndex=0&limit=5", builder.getPrevious()); + assertEquals(URL_BASE + "?startIndex=10&limit=5", builder.getNext()); + } + + @Test + public void testLast() { + PaginationLinksBuilder builder = new PaginationLinksBuilder(PATH, 245, 5, 5, 250); + assertEquals(URL_BASE + "?startIndex=240&limit=5", builder.getPrevious()); + assertNull(builder.getNext()); + } +} diff --git a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/QueryablesBuilderTest.java b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/QueryablesBuilderTest.java index 2eba737d079..95beb377d6c 100644 --- a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/QueryablesBuilderTest.java +++ b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/QueryablesBuilderTest.java @@ -22,69 +22,69 @@ public class QueryablesBuilderTest { public void testGetSchema() throws Exception { Schema stringSchema = QueryablesBuilder.getSchema(String.class); assertEquals("string", stringSchema.getType()); - assertEquals("string", stringSchema.getDescription()); + assertEquals("string", stringSchema.getTitle()); Schema integerSchema = QueryablesBuilder.getSchema(Integer.class); assertEquals("integer", integerSchema.getType()); - assertEquals("integer", integerSchema.getDescription()); + assertEquals("integer", integerSchema.getTitle()); Schema longSchema = QueryablesBuilder.getSchema(Long.class); assertEquals("integer", longSchema.getType()); - assertEquals("integer", longSchema.getDescription()); + assertEquals("integer", longSchema.getTitle()); Schema doubleSchema = QueryablesBuilder.getSchema(Double.class); assertEquals("number", doubleSchema.getType()); - assertEquals("number", doubleSchema.getDescription()); + assertEquals("number", doubleSchema.getTitle()); Schema floatSchema = QueryablesBuilder.getSchema(Float.class); assertEquals("number", floatSchema.getType()); - assertEquals("number", floatSchema.getDescription()); + assertEquals("number", floatSchema.getTitle()); Schema booleanSchema = QueryablesBuilder.getSchema(Boolean.class); assertEquals("boolean", booleanSchema.getType()); - assertEquals("boolean", booleanSchema.getDescription()); + assertEquals("boolean", booleanSchema.getTitle()); Schema timeSchema = QueryablesBuilder.getSchema(java.sql.Time.class); assertEquals("string", timeSchema.getType()); assertEquals("time", timeSchema.getFormat()); - assertEquals("Time", timeSchema.getDescription()); + assertEquals("Time", timeSchema.getTitle()); Schema dateSChema = QueryablesBuilder.getSchema(java.sql.Date.class); assertEquals("string", dateSChema.getType()); assertEquals("date", dateSChema.getFormat()); - assertEquals("Date", dateSChema.getDescription()); + assertEquals("Date", dateSChema.getTitle()); Schema dateTimeSchema = QueryablesBuilder.getSchema(java.util.Date.class); assertEquals("string", dateTimeSchema.getType()); assertEquals("date-time", dateTimeSchema.getFormat()); - assertEquals("DateTime", dateTimeSchema.getDescription()); + assertEquals("DateTime", dateTimeSchema.getTitle()); Schema pointSchema = QueryablesBuilder.getSchema(Point.class); - assertEquals(QueryablesBuilder.POINT_SCHEMA_REF, pointSchema.get$ref()); - assertEquals("Point", pointSchema.getDescription()); + assertEquals("geometry-point", pointSchema.getFormat()); + assertEquals("Point", pointSchema.getTitle()); Schema multiPointSchema = QueryablesBuilder.getSchema(MultiPoint.class); - assertEquals(QueryablesBuilder.MULTIPOINT_SCHEMA_REF, multiPointSchema.get$ref()); - assertEquals("MultiPoint", multiPointSchema.getDescription()); + assertEquals("geometry-multipoint", multiPointSchema.getFormat()); + assertEquals("MultiPoint", multiPointSchema.getTitle()); Schema lineStringSchema = QueryablesBuilder.getSchema(LineString.class); - assertEquals(QueryablesBuilder.LINESTRING_SCHEMA_REF, lineStringSchema.get$ref()); - assertEquals("LineString", lineStringSchema.getDescription()); + assertEquals("geometry-linestring", lineStringSchema.getFormat()); + assertEquals("LineString", lineStringSchema.getTitle()); Schema multiLineStringSchema = QueryablesBuilder.getSchema(MultiLineString.class); - assertEquals(QueryablesBuilder.MULTILINESTRING_SCHEMA_REF, multiLineStringSchema.get$ref()); - assertEquals("MultiLineString", multiLineStringSchema.getDescription()); + assertEquals("geometry-multilinestring", multiLineStringSchema.getFormat()); + assertEquals("MultiLineString", multiLineStringSchema.getTitle()); Schema polygonSchema = QueryablesBuilder.getSchema(Polygon.class); - assertEquals(QueryablesBuilder.POLYGON_SCHEMA_REF, polygonSchema.get$ref()); - assertEquals("Polygon", polygonSchema.getDescription()); + assertEquals("geometry-polygon", polygonSchema.getFormat()); + assertEquals("Polygon", polygonSchema.getTitle()); Schema multiPolygonSchema = QueryablesBuilder.getSchema(MultiPolygon.class); - assertEquals(QueryablesBuilder.MULTIPOLYGON_SCHEMA_REF, multiPolygonSchema.get$ref()); - assertEquals("MultiPolygon", multiPolygonSchema.getDescription()); + assertEquals("geometry-multipolygon", multiPolygonSchema.getFormat()); + assertEquals("MultiPolygon", multiPolygonSchema.getTitle()); Schema geometrySchema = QueryablesBuilder.getSchema(Geometry.class); - assertEquals(QueryablesBuilder.GEOMETRY_SCHEMA_REF, geometrySchema.get$ref()); - assertEquals("Generic geometry", geometrySchema.getDescription()); + assertEquals("geometry-any", geometrySchema.getFormat()); + assertEquals("Any geometry", geometrySchema.getTitle()); } } diff --git a/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/impl/LinkInfoImplTest.java b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/impl/LinkInfoImplTest.java new file mode 100644 index 00000000000..86baf07f72d --- /dev/null +++ b/src/community/ogcapi/ogcapi-core/src/test/java/org/geoserver/ogcapi/impl/LinkInfoImplTest.java @@ -0,0 +1,100 @@ +/* (c) 2024 Open Source Geospatial Foundation - all rights reserved + * This code is licensed under the GPL 2.0 license, available at the root + * application directory. + */ +package org.geoserver.ogcapi.impl; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +public class LinkInfoImplTest { + + private LinkInfoImpl linkInfo; + + @Before + public void setUp() { + linkInfo = new LinkInfoImpl(); + } + + @Test + public void testRel() { + linkInfo.setRel("self"); + assertEquals("self", linkInfo.getRel()); + } + + @Test + public void testType() { + linkInfo.setType("application/json"); + assertEquals("application/json", linkInfo.getType()); + } + + @Test + public void testTitle() { + linkInfo.setTitle("Example Title"); + assertEquals("Example Title", linkInfo.getTitle()); + } + + @Test + public void testHref() { + linkInfo.setHref("http://example.com"); + assertEquals("http://example.com", linkInfo.getHref()); + } + + @Test + public void testService() { + linkInfo.setService("Example Service"); + assertEquals("Example Service", linkInfo.getService()); + } + + @Test + public void testEquals() { + LinkInfoImpl anotherLinkInfo = new LinkInfoImpl(); + anotherLinkInfo.setRel("self"); + anotherLinkInfo.setType("application/json"); + anotherLinkInfo.setTitle("Example Title"); + anotherLinkInfo.setHref("http://example.com"); + anotherLinkInfo.setService("Example Service"); + + linkInfo.setRel("self"); + linkInfo.setType("application/json"); + linkInfo.setTitle("Example Title"); + linkInfo.setHref("http://example.com"); + linkInfo.setService("Example Service"); + + assertEquals(linkInfo, anotherLinkInfo); + } + + @Test + public void testHashCode() { + LinkInfoImpl anotherLinkInfo = new LinkInfoImpl(); + anotherLinkInfo.setRel("self"); + anotherLinkInfo.setType("application/json"); + anotherLinkInfo.setTitle("Example Title"); + anotherLinkInfo.setHref("http://example.com"); + anotherLinkInfo.setService("Example Service"); + + linkInfo.setRel("self"); + linkInfo.setType("application/json"); + linkInfo.setTitle("Example Title"); + linkInfo.setHref("http://example.com"); + linkInfo.setService("Example Service"); + + assertEquals(linkInfo.hashCode(), anotherLinkInfo.hashCode()); + } + + @Test + public void testClone() throws CloneNotSupportedException { + linkInfo.setRel("self"); + linkInfo.setType("application/json"); + linkInfo.setTitle("Example Title"); + linkInfo.setHref("http://example.com"); + linkInfo.setService("Example Service"); + + LinkInfoImpl clonedLinkInfo = (LinkInfoImpl) linkInfo.clone(); + + assertEquals(linkInfo, clonedLinkInfo); + assertEquals(linkInfo.hashCode(), clonedLinkInfo.hashCode()); + } +} diff --git a/src/community/ogcapi/ogcapi-core/src/test/resources/org/geoserver/ogcapi/applicationContext.xml b/src/community/ogcapi/ogcapi-core/src/test/resources/org/geoserver/ogcapi/applicationContext.xml deleted file mode 100644 index 0a9884e65cd..00000000000 --- a/src/community/ogcapi/ogcapi-core/src/test/resources/org/geoserver/ogcapi/applicationContext.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/community/ogcapi/ogcapi-core/src/test/resources/org/geoserver/ogcapi/message.ftl b/src/community/ogcapi/ogcapi-core/src/test/resources/org/geoserver/ogcapi/message.ftl new file mode 100644 index 00000000000..8105c7baa6f --- /dev/null +++ b/src/community/ogcapi/ogcapi-core/src/test/resources/org/geoserver/ogcapi/message.ftl @@ -0,0 +1,9 @@ + + + + + +

The message: ${model.message}

+

Capabilities URL

+ + \ No newline at end of file diff --git a/src/community/ogcapi/ogcapi-coverages/pom.xml b/src/community/ogcapi/ogcapi-coverages/pom.xml index 8125c78c4f4..ae2ade03fcd 100644 --- a/src/community/ogcapi/ogcapi-coverages/pom.xml +++ b/src/community/ogcapi/ogcapi-coverages/pom.xml @@ -56,7 +56,6 @@ org.geotools gt-jdbc - ${gt.version} test-jar test diff --git a/src/community/ogcapi/ogcapi-coverages/src/main/java/org/geoserver/ogcapi/v1/coverages/CollectionsDocument.java b/src/community/ogcapi/ogcapi-coverages/src/main/java/org/geoserver/ogcapi/v1/coverages/CollectionsDocument.java index 781f1a70395..6055cdfc69c 100644 --- a/src/community/ogcapi/ogcapi-coverages/src/main/java/org/geoserver/ogcapi/v1/coverages/CollectionsDocument.java +++ b/src/community/ogcapi/ogcapi-coverages/src/main/java/org/geoserver/ogcapi/v1/coverages/CollectionsDocument.java @@ -51,7 +51,7 @@ public List getLinks() { public Iterator getCollections() { CloseableIterator coverages = geoServer.getCatalog().list(CoverageInfo.class, Filter.INCLUDE); - return new Iterator() { + return new Iterator<>() { CollectionDocument next; diff --git a/src/community/ogcapi/ogcapi-coverages/src/main/resources/org/geoserver/ogcapi/v1/coverages/openapi.yaml b/src/community/ogcapi/ogcapi-coverages/src/main/resources/org/geoserver/ogcapi/v1/coverages/openapi.yaml index bfbe16a2b7e..398c8a1fa32 100644 --- a/src/community/ogcapi/ogcapi-coverages/src/main/resources/org/geoserver/ogcapi/v1/coverages/openapi.yaml +++ b/src/community/ogcapi/ogcapi-coverages/src/main/resources/org/geoserver/ogcapi/v1/coverages/openapi.yaml @@ -65,7 +65,7 @@ paths: default: application/vnd.oai.openapi+json;version=3.0 enum: - application/vnd.oai.openapi+json;version=3.0 - - application/x-yaml + - application/yaml - text/html responses: diff --git a/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/ApiTest.java b/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/ApiTest.java index fbac0bfe392..15cb7368b57 100644 --- a/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/ApiTest.java +++ b/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/ApiTest.java @@ -91,7 +91,7 @@ public void testApiHTML() throws Exception { @Test public void testApiYaml() throws Exception { - String yaml = getAsString("ogc/coverages/v1/openapi?f=application/x-yaml"); + String yaml = getAsString("ogc/coverages/v1/openapi?f=application/yaml"); GeoServerBaseTestSupport.LOGGER.log(Level.INFO, yaml); ObjectMapper mapper = Yaml.mapper(); @@ -104,10 +104,10 @@ public void testYamlAsAcceptsHeader() throws Exception { MockHttpServletRequest request = createRequest("ogc/coverages/v1/openapi"); request.setMethod("GET"); request.setContent(new byte[] {}); - request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/x-yaml, text/html"); + request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/yaml, text/html"); MockHttpServletResponse response = dispatch(request); assertEquals(200, response.getStatus()); - assertThat(response.getContentType(), CoreMatchers.startsWith("application/x-yaml")); + assertThat(response.getContentType(), CoreMatchers.startsWith("application/yaml")); String yaml = string(new ByteArrayInputStream(response.getContentAsString().getBytes())); ObjectMapper mapper = Yaml.mapper(); @@ -186,10 +186,10 @@ public void testWorkspaceQualifiedAPI() throws Exception { MockHttpServletRequest request = createRequest("cdf/ogc/coverages/v1/openapi"); request.setMethod("GET"); request.setContent(new byte[] {}); - request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/x-yaml, text/html"); + request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/yaml, text/html"); MockHttpServletResponse response = dispatch(request); assertEquals(200, response.getStatus()); - assertEquals("application/x-yaml", response.getContentType()); + assertEquals("application/yaml", response.getContentType()); String yaml = string(new ByteArrayInputStream(response.getContentAsString().getBytes())); // System.out.println(yaml); diff --git a/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/CollectionTest.java b/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/CollectionTest.java index bd897f754c6..7ea7793cc0b 100644 --- a/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/CollectionTest.java +++ b/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/CollectionTest.java @@ -85,7 +85,7 @@ public void testCollectionVirtualWorkspace() throws Exception { @Test public void testCollectionYaml() throws Exception { - String yaml = getAsString("ogc/coverages/v1/collections/rs:DEM?f=application/x-yaml"); + String yaml = getAsString("ogc/coverages/v1/collections/rs:DEM?f=application/yaml"); checkDEMCoverage(convertYamlToJsonPath(yaml), "rs:DEM"); } diff --git a/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/CollectionsTest.java b/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/CollectionsTest.java index 43683175c2e..c5d536a0c42 100644 --- a/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/CollectionsTest.java +++ b/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/CollectionsTest.java @@ -127,7 +127,7 @@ public void testCollectionsWorkspaceSpecificJson() throws Exception { @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/coverages/v1/collections/?f=application/x-yaml"); + String yaml = getAsString("ogc/coverages/v1/collections/?f=application/yaml"); DocumentContext json = convertYamlToJsonPath(yaml); testCollectionsJson(json); } diff --git a/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/ConformanceTest.java b/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/ConformanceTest.java index 2c3a8c38307..e81528527ef 100644 --- a/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/ConformanceTest.java +++ b/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/ConformanceTest.java @@ -43,7 +43,7 @@ private String[] getExpectedConformanceClasses() { @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/coverages/v1/conformance/?f=application/x-yaml"); + String yaml = getAsString("ogc/coverages/v1/conformance/?f=application/yaml"); checkConformance(convertYamlToJsonPath(yaml)); } diff --git a/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/LandingPageTest.java b/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/LandingPageTest.java index d7a2b43c771..76ca94cb433 100644 --- a/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/LandingPageTest.java +++ b/src/community/ogcapi/ogcapi-coverages/src/test/java/org/geoserver/ogcapi/v1/coverages/LandingPageTest.java @@ -67,16 +67,16 @@ public void testLandingPageWorkspaceSpecific() throws Exception { @Test public void testLandingPageYaml() throws Exception { - String yaml = getAsString("ogc/coverages/v1?f=application/x-yaml"); + String yaml = getAsString("ogc/coverages/v1?f=application/yaml"); // System.out.println(yaml); DocumentContext json = convertYamlToJsonPath(yaml); assertJSONList( json, - "links[?(@.type == 'application/x-yaml' && @.href =~ /.*ogc\\/coverages\\/v1\\/\\?.*/)].rel", + "links[?(@.type == 'application/yaml' && @.href =~ /.*ogc\\/coverages\\/v1\\/\\?.*/)].rel", "self"); assertJSONList( json, - "links[?(@.type != 'application/x-yaml' && @.href =~ /.*ogc\\/coverages\\/v1\\/\\?.*/)].rel", + "links[?(@.type != 'application/yaml' && @.href =~ /.*ogc\\/coverages\\/v1\\/\\?.*/)].rel", "alternate", "alternate"); checkJSONLandingPageShared(json); diff --git a/src/community/ogcapi/ogcapi-features/pom.xml b/src/community/ogcapi/ogcapi-features/pom.xml index 9500d9c75c6..4c3326b4a98 100644 --- a/src/community/ogcapi/ogcapi-features/pom.xml +++ b/src/community/ogcapi/ogcapi-features/pom.xml @@ -61,7 +61,6 @@ org.geotools gt-jdbc - ${gt.version} test-jar test @@ -75,13 +74,11 @@ org.geotools gt-app-schema - ${gt.version} test org.geotools gt-app-schema - ${gt.version} tests test @@ -92,5 +89,11 @@ tests test + + com.github.erosb + json-sKema + test + + diff --git a/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/CollectionDocument.java b/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/CollectionDocument.java index 7fa48e9297a..455d8d862dd 100644 --- a/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/CollectionDocument.java +++ b/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/CollectionDocument.java @@ -8,6 +8,9 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import java.io.IOException; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -47,19 +50,45 @@ public class CollectionDocument extends AbstractCollectionDocument crs) throws IOException { + this(geoServer, featureType, crs, null); + } + + public CollectionDocument( + GeoServer geoServer, + FeatureTypeInfo featureType, + List crs, + List serviceCRS) + throws IOException { super(featureType); // basic info String collectionId = featureType.prefixedName(); this.id = collectionId; this.title = featureType.getTitle(); this.description = featureType.getAbstract(); - ReferencedEnvelope bbox = featureType.getLatLonBoundingBox(); DateRange timeExtent = TimeExtentCalculator.getTimeExtent(featureType); - setExtent(new CollectionExtents(bbox, timeExtent)); + + // Prepare a lat/lon bounding box adhering to the GeoServer configured number of decimal + // places for text output + ReferencedEnvelope bbox = featureType.getLatLonBoundingBox(); + int numDecimals = geoServer.getSettings().getNumDecimals(); + ReferencedEnvelope roundedOutBounds = roundLonLatBbox(bbox, numDecimals); + + setExtent(new CollectionExtents(roundedOutBounds, timeExtent)); + this.featureType = featureType; - this.crs = crs; this.storageCrs = lookupStorageCrs(); + // the crs list must contain the storage crs, make sure it is there + if (crs == null) { + this.crs = List.of(storageCrs); + } else if (!crsListContains(storageCrs, crs, serviceCRS)) { + // provided list may be immutable + this.crs = new ArrayList<>(crs); + this.crs.add(0, storageCrs); + } else { + this.crs = crs; + } + // links Collection formats = APIRequestInfo.get().getProducibleMediaTypes(FeaturesResponse.class, true); @@ -114,6 +143,46 @@ public CollectionDocument(GeoServer geoServer, FeatureTypeInfo featureType, List } } + /** + * @param bbox a FeatureType's WGS84 bounds with east-north axis order + * @param numDecimals precision to round coordinates to + * @return an envelope rounded to the specified number of decimaps and expanded as necessary to + * the west-east and south-north directions. Zero width and height are preserved. + */ + private ReferencedEnvelope roundLonLatBbox(ReferencedEnvelope bbox, int numDecimals) { + // if(true)return bbox; + double minX = Math.max(-180d, round(bbox.getMinX(), numDecimals, RoundingMode.FLOOR)); + double minY = Math.max(-90d, round(bbox.getMinY(), numDecimals, RoundingMode.FLOOR)); + double maxX = Math.min(180d, round(bbox.getMaxX(), numDecimals, RoundingMode.CEILING)); + double maxY = Math.min(90d, round(bbox.getMaxY(), numDecimals, RoundingMode.CEILING)); + + if (bbox.getWidth() == 0d) { + maxX = minX; + } + if (bbox.getHeight() == 0d) { + maxY = minY; + } + + return new ReferencedEnvelope(minX, maxX, minY, maxY, bbox.getCoordinateReferenceSystem()); + } + + /** Round a value to the specified number of decimal places with a provided rounding strategy */ + double round(double value, int places, RoundingMode mode) { + if (places < 0) throw new IllegalArgumentException("Decimal places must be non-negative"); + BigDecimal bd = BigDecimal.valueOf(value); + bd = bd.setScale(places, mode); + return bd.doubleValue(); + } + + private boolean crsListContains( + String storageCrs, List collectionCRSs, List serviceCRSs) { + // is it referring to the whole server CRS list? + if (collectionCRSs.contains("#/crs")) { + if (serviceCRSs != null && serviceCRSs.contains(storageCrs)) return true; + } + return collectionCRSs.contains(storageCrs); + } + private static boolean isOWSAvailable(GeoServer geoServer, String serviceId) { return geoServer.getServices().stream() .anyMatch(s -> serviceId.equalsIgnoreCase(s.getName()) && s.isEnabled()); diff --git a/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/CollectionsDocument.java b/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/CollectionsDocument.java index cdf458db8fd..9c54bd0bb36 100644 --- a/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/CollectionsDocument.java +++ b/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/CollectionsDocument.java @@ -53,7 +53,7 @@ public List getLinks() { public Iterator getCollections() { CloseableIterator featureTypes = geoServer.getCatalog().list(FeatureTypeInfo.class, Filter.INCLUDE); - return new Iterator() { + return new Iterator<>() { CollectionDocument next; @@ -74,7 +74,8 @@ public boolean hasNext() { FeatureService.getFeatureTypeCRS( featureType, Collections.singletonList("#/crs")); CollectionDocument collection = - new CollectionDocument(geoServer, featureType, crs); + new CollectionDocument( + geoServer, featureType, crs, CollectionsDocument.this.crs); for (Consumer collectionDecorator : collectionDecorators) { collectionDecorator.accept(collection); diff --git a/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/FeatureService.java b/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/FeatureService.java index 8214764f6df..bf9ea45cac3 100644 --- a/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/FeatureService.java +++ b/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/FeatureService.java @@ -17,6 +17,7 @@ import static org.geoserver.ogcapi.ConformanceClass.FEATURES_FILTER; import static org.geoserver.ogcapi.ConformanceClass.FILTER; import static org.geoserver.ogcapi.ConformanceClass.IDS; +import static org.geoserver.ogcapi.ConformanceClass.QUERYABLES; import static org.geoserver.ogcapi.ConformanceClass.SEARCH; import static org.geoserver.ogcapi.ConformanceClass.SORTBY; import static org.geoserver.ogcapi.MappingJackson2YAMLMessageConverter.APPLICATION_YAML_VALUE; @@ -318,8 +319,9 @@ public ConformanceDocument conformance() { GEOJSON, /* GMLSF0, GS does not use the gmlsf namespace */ CRS_BY_REFERENCE, - FEATURES_FILTER, FILTER, + QUERYABLES, + FEATURES_FILTER, SEARCH, ECQL, ECQL_TEXT, diff --git a/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/FeaturesAPIBuilder.java b/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/FeaturesAPIBuilder.java index 91f3d3a49e3..4da220bb649 100644 --- a/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/FeaturesAPIBuilder.java +++ b/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/FeaturesAPIBuilder.java @@ -61,13 +61,14 @@ public OpenAPI build(WFSInfo wfs) throws IOException { Catalog catalog = wfs.getGeoServer().getCatalog(); List validCollectionIds = catalog.getFeatureTypes().stream() + .filter(ft -> ft.isEnabled() && ft.isAdvertised()) .map(ft -> ft.prefixedName()) .collect(Collectors.toList()); collectionId.getSchema().setEnum(validCollectionIds); // list of valid filter-lang values Parameter filterLang = parameters.get("filter-lang"); - filterLang.getSchema().setEnum(new ArrayList(APIFilterParser.SUPPORTED_ENCODINGS)); + filterLang.getSchema().setEnum(new ArrayList<>(APIFilterParser.SUPPORTED_ENCODINGS)); // provide actual values for limit Parameter limit = parameters.get("limit"); diff --git a/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/RFCGeoJSONFeaturesResponse.java b/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/RFCGeoJSONFeaturesResponse.java index df6378c9e20..1ce0cebc02c 100644 --- a/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/RFCGeoJSONFeaturesResponse.java +++ b/src/community/ogcapi/ogcapi-features/src/main/java/org/geoserver/ogcapi/v1/features/RFCGeoJSONFeaturesResponse.java @@ -212,10 +212,10 @@ protected void addLinks( protected FeatureTypeInfo getFeatureType(GetFeatureRequest request) { // OGC API Features always have a collection reference, so one query return Optional.ofNullable(request.getQueries()) - .filter(qs -> qs.size() > 0) + .filter(qs -> !qs.isEmpty()) .map(qs -> qs.get(0)) .map(q -> q.getTypeNames()) - .filter(tns -> tns.size() > 0) + .filter(tns -> !tns.isEmpty()) .map(tns -> tns.get(0)) .map(tn -> new NameImpl(tn.getNamespaceURI(), tn.getLocalPart())) .map(tn -> gs.getCatalog().getFeatureTypeByName(tn)) diff --git a/src/community/ogcapi/ogcapi-features/src/main/resources/org/geoserver/ogcapi/v1/features/functions.ftl b/src/community/ogcapi/ogcapi-features/src/main/resources/org/geoserver/ogcapi/v1/features/functions.ftl index b405d98b7c4..b02fbeb247d 100644 --- a/src/community/ogcapi/ogcapi-features/src/main/resources/org/geoserver/ogcapi/v1/features/functions.ftl +++ b/src/community/ogcapi/ogcapi-features/src/main/resources/org/geoserver/ogcapi/v1/features/functions.ftl @@ -7,12 +7,12 @@ <#list model.functions as f>

${f.name}

    -
  • Returns: <#list f.returns.type as t>${t}
  • +
  • Returns: <#list f.returns as t>${t}
  • Arguments: - + <#list f.arguments as arg> - +
    NameDescriptionType
    NameTitleType
    ${arg.title}${arg.description!""}<#list f.returns.type as t>${t}
    ${arg.title}${arg.title!""}<#list arg.type as t>${t}
  • diff --git a/src/community/ogcapi/ogcapi-features/src/main/resources/org/geoserver/ogcapi/v1/features/landingPage.ftl b/src/community/ogcapi/ogcapi-features/src/main/resources/org/geoserver/ogcapi/v1/features/landingPage.ftl index 50baa1a2a71..9d4ae67bbef 100644 --- a/src/community/ogcapi/ogcapi-features/src/main/resources/org/geoserver/ogcapi/v1/features/landingPage.ftl +++ b/src/community/ogcapi/ogcapi-features/src/main/resources/org/geoserver/ogcapi/v1/features/landingPage.ftl @@ -28,6 +28,16 @@ + +
    +
    +
    +

    Functions

    +

    The collection page provides a list of all the collections available in this service. +
    +

    +
    +
    ${htmlExtensions('landing')?no_esc} diff --git a/src/community/ogcapi/ogcapi-features/src/main/resources/org/geoserver/ogcapi/v1/features/openapi.yaml b/src/community/ogcapi/ogcapi-features/src/main/resources/org/geoserver/ogcapi/v1/features/openapi.yaml index d69d7f84e74..5647d970f1b 100644 --- a/src/community/ogcapi/ogcapi-features/src/main/resources/org/geoserver/ogcapi/v1/features/openapi.yaml +++ b/src/community/ogcapi/ogcapi-features/src/main/resources/org/geoserver/ogcapi/v1/features/openapi.yaml @@ -329,28 +329,30 @@ components: filter: name: filter in: query + required: false description: Defines a filter that will be applied on items, only items matching the filter will be returned schema: type: string + explode: false filter-lang: name: filter-lang in: query + required: false description: Filter encoding used in the filter parameter schema: type: string enum: - cql-text - cql2-text - default: cql-text + default: cql2-text filter-crs: name: filter-crs in: query - description: Filter CRS which is being used to encode geometries in the filter parameter required: false + description: Filter CRS which is being used to encode geometries in the filter parameter schema: type: string format: uri-reference - style: form explode: false sortby: name: sortby diff --git a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/ApiTest.java b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/ApiTest.java index f4c4e868fa9..350a61aba2f 100644 --- a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/ApiTest.java +++ b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/ApiTest.java @@ -12,6 +12,7 @@ import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -38,6 +39,7 @@ import org.geoserver.wfs.WFSInfo; import org.hamcrest.CoreMatchers; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.mock.web.MockHttpServletRequest; @@ -124,13 +126,13 @@ public void testApiHTML() throws Exception { @Test public void testApiYaml() throws Exception { - String yaml = getAsString("ogc/features/v1/openapi?f=application/x-yaml"); + String yaml = getAsString("ogc/features/v1/openapi?f=application/yaml"); validateYAMLApi(yaml); } @Test public void testApiYamlExtension() throws Exception { - String yaml = getAsString("ogc/features/v1/openapi?f=application/x-yaml"); + String yaml = getAsString("ogc/features/v1/openapi?f=application/yaml"); validateYAMLApi(yaml); } @@ -147,10 +149,10 @@ public void testYamlAsAcceptsHeader() throws Exception { MockHttpServletRequest request = createRequest("ogc/features/v1/openapi"); request.setMethod("GET"); request.setContent(new byte[] {}); - request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/x-yaml, text/html"); + request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/yaml, text/html"); MockHttpServletResponse response = dispatch(request); assertEquals(200, response.getStatus()); - assertThat(response.getContentType(), CoreMatchers.startsWith("application/x-yaml")); + assertThat(response.getContentType(), CoreMatchers.startsWith("application/yaml")); String yaml = string(new ByteArrayInputStream(response.getContentAsString().getBytes())); ObjectMapper mapper = Yaml.mapper(); @@ -251,10 +253,10 @@ public void testWorkspaceQualifiedAPI() throws Exception { MockHttpServletRequest request = createRequest("cdf/ogc/features/v1/openapi"); request.setMethod("GET"); request.setContent(new byte[] {}); - request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/x-yaml, text/html"); + request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/yaml, text/html"); MockHttpServletResponse response = dispatch(request); assertEquals(200, response.getStatus()); - assertEquals("application/x-yaml", response.getContentType()); + assertEquals("application/yaml", response.getContentType()); String yaml = string(new ByteArrayInputStream(response.getContentAsString().getBytes())); // System.out.println(yaml); @@ -272,4 +274,14 @@ public void testWorkspaceQualifiedAPI() throws Exception { .collect(Collectors.toList()); assertThat(collectionIdValues, equalTo(expectedCollectionIds)); } + + @Test + @Ignore + public void testFilterCRS() throws Exception { + fail( + "We should to enumerate all supported filter-crs values, but they are likely too many, " + + "and we'd have to inspect all the collections to find an exhaustive list for the" + + "test. The ATS does not seem to check it either, so taking a not but not " + + "implementing for the time being."); + } } diff --git a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/CollectionDocumentBoundsTest.java b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/CollectionDocumentBoundsTest.java new file mode 100644 index 00000000000..ddb0e5891e6 --- /dev/null +++ b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/CollectionDocumentBoundsTest.java @@ -0,0 +1,260 @@ +/* (c) 2024 Open Source Geospatial Foundation - all rights reserved + * This code is licensed under the GPL 2.0 license, available at the root + * application directory. + */ +package org.geoserver.ogcapi.v1.features; + +import static com.google.common.collect.Iterators.toArray; +import static java.lang.String.format; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.jayway.jsonpath.DocumentContext; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.math.BigDecimal; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import javax.xml.namespace.QName; +import org.geoserver.catalog.Catalog; +import org.geoserver.catalog.CatalogBuilder; +import org.geoserver.catalog.FeatureTypeInfo; +import org.geoserver.config.GeoServer; +import org.geoserver.config.GeoServerInfo; +import org.geoserver.data.test.CiteTestData; +import org.geoserver.data.test.SystemTestData; +import org.geotools.api.feature.simple.SimpleFeature; +import org.geotools.api.geometry.BoundingBox; +import org.geotools.data.geojson.GeoJSONReader; +import org.geotools.data.simple.SimpleFeatureCollection; +import org.geotools.data.store.FeatureIteratorIterator; +import org.geotools.geometry.jts.JTS; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.geotools.referencing.crs.DefaultGeographicCRS; +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.Polygon; + +/** + * Checks the WGS84 spatial extent in collections from {@code /collections} and {@code + * /collections/} documents adhere to the configured number of decimal places, and + * {@code /collection//items} are fully covered by the spatial extent declared in the + * collection document. + */ +@RunWith(Parameterized.class) +public class CollectionDocumentBoundsTest extends FeaturesTestSupport { + + /** Test dataset with high precision ordinates */ + static QName TIGER_POI = new QName("http://www.census.gov", "poi", "tiger"); + /** Single-point feature dataset with high precision ordinates */ + static QName TIGER_SINGLE_POI = new QName("http://www.census.gov", "single_poi", "tiger"); + + static final List layersFixture = + List.of(TIGER_POI, TIGER_SINGLE_POI, CiteTestData.BUILDINGS); + + private String collectionId; + private int numDecimals; + + /** The actual, accurate lat-lon bbox for the feature type under test */ + private ReferencedEnvelope latLonBbox; + + // Constructor to inject parameters for each test case + public CollectionDocumentBoundsTest(String collectionId, int numDecimals) { + this.collectionId = collectionId; + this.numDecimals = numDecimals; + } + + // Provide test data [[collectionId, numDecimals],...] + @Parameters(name = "{0}: numDecimals: {1}") + public static Collection data() { + return layersFixture.stream() + .map(qn -> format("%s:%s", qn.getPrefix(), qn.getLocalPart())) + .map(CollectionDocumentBoundsTest::testParams) + .flatMap(List::stream) + .collect(Collectors.toList()); + } + + private static List testParams(String name) { + + return IntStream.rangeClosed(3, 15) + .boxed() + .sorted(Comparator.naturalOrder().reversed()) + .map(numDecimals -> new Object[] {name, numDecimals}) + .collect(Collectors.toList()); + } + + /** + * One-time set up, creates the additional layers in the catalog and sets up precise lat-lon + * bounds for each {@link #layersFixture collection to be tested} + */ + @Override + protected void onSetUp(SystemTestData testData) throws Exception { + super.onSetUp(testData); + Catalog catalog = getCatalog(); + addFeatureTypes(testData, catalog); + layersFixture.stream().map(super::getLayerId).forEach(this::adjustFeatureType); + } + + /** + * Obtain the actual collection bounds and store it in {@link #latLonBbox}, configure number of + * decimal places to use for encoding from the {@link #numDecimals} test parameter + */ + @Before + public void beforeEach() throws Exception { + GeoServer geoServer = getGeoServer(); + GeoServerInfo global = geoServer.getGlobal(); + global.getSettings().setNumDecimals(this.numDecimals); + geoServer.save(global); + + FeatureTypeInfo featureType = getCatalog().getFeatureTypeByName(collectionId); + this.latLonBbox = featureType.getLatLonBoundingBox(); + } + + @Test + public void testCollectionBoundsCoversActualBounds() throws Exception { + assertEquals(this.numDecimals, getGeoServer().getGlobal().getSettings().getNumDecimals()); + + String collectionQuery = format("ogc/features/v1/collections/%s", collectionId); + DocumentContext json = getAsJSONPath(collectionQuery, 200); + + ReferencedEnvelope actualBounds = this.latLonBbox; + ReferencedEnvelope encodedBounds = parseSpatialExtent(json); + + assertMaxDecimals(encodedBounds, this.numDecimals); + assertEncodedCollectionBoundsCoversActualBounds(actualBounds, encodedBounds); + } + + @Test + public void testCollectionBoundsCoversItems() throws Exception { + assertEquals(this.numDecimals, getGeoServer().getGlobal().getSettings().getNumDecimals()); + + String collectionQuery = format("ogc/features/v1/collections/%s", collectionId); + DocumentContext json = getAsJSONPath(collectionQuery, 200); + final ReferencedEnvelope collectionBounds = parseSpatialExtent(json); + + String itemsQuery = format("ogc/features/v1/collections/%s/items", collectionId); + String fc = super.getAsString(itemsQuery); + SimpleFeatureCollection parsedFc = GeoJSONReader.parseFeatureCollection(fc); + + SimpleFeature[] features = + toArray(new FeatureIteratorIterator<>(parsedFc.features()), SimpleFeature.class); + for (SimpleFeature feature : features) { + assertMaxDecimals(feature, this.numDecimals); + assertEncodedCollectionBoundsCoversFeature(feature, collectionBounds); + } + } + + private void assertMaxDecimals(SimpleFeature feature, int numDecimals) { + Geometry geom = (Geometry) feature.getDefaultGeometry(); + if (geom == null) { + assertTrue(true); + } else { + String strgeom = geom.toText(); + Coordinate[] coordinates = geom.getCoordinates(); + for (Coordinate c : coordinates) { + assertMaxDecimals(c.getX(), numDecimals, strgeom); + assertMaxDecimals(c.getY(), numDecimals, strgeom); + } + } + } + + private void assertMaxDecimals(ReferencedEnvelope bounds, int numDecimals) { + String strbounds = bounds.toString(); + assertMaxDecimals(bounds.getMinX(), numDecimals, strbounds); + assertMaxDecimals(bounds.getMaxX(), numDecimals, strbounds); + assertMaxDecimals(bounds.getMinY(), numDecimals, strbounds); + assertMaxDecimals(bounds.getMaxY(), numDecimals, strbounds); + } + + private void assertMaxDecimals(double ordinate, int numDecimals, String message) { + int numberOfDecimals = getNumberOfDecimals(ordinate); + assertThat(message, numberOfDecimals, Matchers.lessThanOrEqualTo(numDecimals)); + } + + private void assertEncodedCollectionBoundsCoversActualBounds( + ReferencedEnvelope original, ReferencedEnvelope encoded) { + String msg = + format( + "Expected encoded collection bounds %s to fully contain %s%n" + + "encoded extent:\t\t%s %noriginal extent:\t%s", + encoded, original, poly(encoded), poly(original)); + + assertTrue(msg, encoded.contains(original)); + } + + private void assertEncodedCollectionBoundsCoversFeature( + SimpleFeature feature, ReferencedEnvelope encodedCollectionBounds) { + + ReferencedEnvelope actualCollectionBounds = this.latLonBbox; + String fid = feature.getID(); + BoundingBox featureBounds = feature.getBounds(); + String msg = + format( + "Feature %s bounds not covered by collection bounds%n" + + "feature bounds:\t\t%s %ncollection bounds:\t%s%n" + + "real collection bounds:\t%s", + fid, + poly(featureBounds), + poly(encodedCollectionBounds), + poly(actualCollectionBounds)); + + assertTrue(msg, encodedCollectionBounds.contains(featureBounds)); + } + + private static Polygon poly(BoundingBox bounds) { + return JTS.toGeometry(bounds); + } + + private void addFeatureTypes(SystemTestData testData, Catalog catalog) throws IOException { + testData.addWorkspace(TIGER_POI.getPrefix(), TIGER_POI.getNamespaceURI(), catalog); + testData.addVectorLayer(TIGER_POI, null, "tiger_poi.properties", getClass(), catalog); + testData.addVectorLayer( + TIGER_SINGLE_POI, null, "tiger_single_poi.properties", getClass(), catalog); + } + + private void adjustFeatureType(String featureTypeName) { + Catalog catalog = getCatalog(); + FeatureTypeInfo featureType = catalog.getFeatureTypeByName(featureTypeName); + assertNotNull(featureType); + // revert default values set by SystemTestData.addVectorLayer() + // sets numDecimals=8 at the featuretype level, revert to zero for the encoder + // to use the global settings + featureType.setNumDecimals(0); + // compute latlon bbox, SystemTestData sets the full WGS84 bounds + try { + new CatalogBuilder(catalog).setupBounds(featureType); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + ReferencedEnvelope actualLatLonBounds = featureType.getLatLonBoundingBox(); + featureType.setLatLonBoundingBox(actualLatLonBounds); + catalog.save(featureType); + } + + public static int getNumberOfDecimals(double value) { + // Convert the double to BigDecimal with proper precision handling + BigDecimal bd = BigDecimal.valueOf(value).stripTrailingZeros(); + // Get the scale (number of decimal places) + return Math.max(0, bd.scale()); + } + + private ReferencedEnvelope parseSpatialExtent(DocumentContext json) { + double minx = json.read("$.extent.spatial.bbox[0][0]", Double.class); + double miny = json.read("$.extent.spatial.bbox[0][1]", Double.class); + double maxx = json.read("$.extent.spatial.bbox[0][2]", Double.class); + double maxy = json.read("$.extent.spatial.bbox[0][3]", Double.class); + + return new ReferencedEnvelope(minx, maxx, miny, maxy, DefaultGeographicCRS.WGS84); + } +} diff --git a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/CollectionTest.java b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/CollectionTest.java index 089ad782803..73e55e79ef5 100644 --- a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/CollectionTest.java +++ b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/CollectionTest.java @@ -25,7 +25,6 @@ import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.custommonkey.xmlunit.XMLAssert; import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.config.GeoServer; import org.geoserver.data.test.MockData; @@ -38,10 +37,8 @@ import org.geoserver.wfs.WFSInfo; import org.hamcrest.Matchers; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.springframework.http.MediaType; -import org.w3c.dom.Document; public class CollectionTest extends FeaturesTestSupport { @@ -63,14 +60,11 @@ public void cleanupRoads() throws IOException { } @Before - public void enableWFS() throws Exception { - setWFSEnabled(true); - } - - private void setWFSEnabled(boolean enabled) { + public void resetWFS() throws Exception { GeoServer gs = getGeoServer(); WFSInfo wfs = gs.getService(WFSInfo.class); - wfs.setEnabled(enabled); + wfs.getSRS().clear(); + wfs.setEnabled(true); gs.save(wfs); } @@ -157,6 +151,31 @@ public void testCollectionJsonCustomCRSList() throws Exception { "http://www.opengis.net/def/crs/EPSG/0/32632")); } + @Test + public void testCustomizeGlobalCRSList() throws Exception { + GeoServer gs = getGeoServer(); + WFSInfo wfs = gs.getService(WFSInfo.class); + wfs.getSRS().addAll(Arrays.asList("EPSG:4326", "EPSG:3857")); + gs.save(wfs); + + String polygons = getLayerId(MockData.POLYGONS); + DocumentContext json = getAsJSONPath("ogc/features/v1/collections/" + polygons, 200); + + assertEquals("cgf:Polygons", json.read("$.id", String.class)); + String storageCrs = json.read("storageCrs"); + assertEquals("http://www.opengis.net/def/crs/EPSG/0/32615", storageCrs); + // make sure the storage CRS is in the crs list, even if it was not declared globally + List crs = json.read("crs"); + assertEquals(4, crs.size()); + assertThat( + crs, + hasItems( + "http://www.opengis.net/def/crs/OGC/1.3/CRS84", + "http://www.opengis.net/def/crs/EPSG/0/4326", + "http://www.opengis.net/def/crs/EPSG/0/3857", + "http://www.opengis.net/def/crs/EPSG/0/32615")); + } + private List getFeaturesResponseFormats() { return GeoServerExtensions.bean(APIDispatcher.class, applicationContext) .getProducibleMediaTypes(FeaturesResponse.class, true); @@ -187,32 +206,10 @@ public void testCollectionVirtualWorkspace() throws Exception { readSingle(json, "$.links[?(@.type=='application/gml+xml;version=3.2')]"); } - @Test - @Ignore // ignoring XML output for the moment, we need to migrated it to use JAXB2 to be of any - // usefulness - public void testCollectionXML() throws Exception { - Document dom = - getAsDOM( - "ogc/features/v1/collections/" - + getLayerId(ROAD_SEGMENTS) - + "?f=application/xml"); - print(dom); - String expected = - "http://localhost:8080/geoserver/ogc/features/v1/collections/cite%3ARoadSegments" - + "/items?f=application%2Fjson"; - XMLAssert.assertXpathEvaluatesTo( - expected, - "//wfs:Collection[wfs:id='cite:RoadSegments']/atom:link[@atom:type='application" - + "/json']/@atom:href", - dom); - } - @Test public void testCollectionYaml() throws Exception { getAsString( - "ogc/features/v1/collections/" - + getLayerId(ROAD_SEGMENTS) - + "?f=application/x-yaml"); + "ogc/features/v1/collections/" + getLayerId(ROAD_SEGMENTS) + "?f=application/yaml"); // System.out.println(yaml); } @@ -240,28 +237,6 @@ public void testCollectionHTMLRemovedInlineJS() throws Exception { assertThat(html, not(containsString("onchange"))); } - @Test - public void testQueryables() throws Exception { - String roadSegments = ROAD_SEGMENTS.getLocalPart(); - DocumentContext json = - getAsJSONPath( - "cite/ogc/features/v1/collections/" + roadSegments + "/queryables", 200); - assertThat( - json.read("properties.the_geom.$ref"), - equalTo("https://geojson.org/schema/MultiLineString.json")); - assertThat(json.read("properties.FID.type"), equalTo("string")); - assertThat(json.read("properties.NAME.type"), equalTo("string")); - } - - @Test - public void testQueryablesHTML() throws Exception { - String roadSegments = ROAD_SEGMENTS.getLocalPart(); - org.jsoup.nodes.Document document = - getAsJSoup( - "cite/ogc/features/v1/collections/" + roadSegments + "/queryables?f=html"); - assertEquals("the_geom: MultiLineString", document.select("#queryables li:eq(0)").text()); - } - @Test public void testCustomLinks() throws Exception { FeatureTypeInfo roads = getCatalog().getFeatureTypeByName(getLayerId(ROAD_SEGMENTS)); diff --git a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/CollectionsTest.java b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/CollectionsTest.java index 246f72f7014..3b080d326c6 100644 --- a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/CollectionsTest.java +++ b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/CollectionsTest.java @@ -37,12 +37,10 @@ import org.geoserver.wfs.WFSInfo; import org.hamcrest.Matchers; import org.jsoup.Jsoup; -import org.junit.Ignore; import org.junit.Test; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import org.w3c.dom.Document; public class CollectionsTest extends FeaturesTestSupport { @@ -142,17 +140,9 @@ public void testCollectionsWorkspaceSpecificJson() throws Exception { ((JSONArray) json.read(deleteHrefPath)).get(0)); } - @Test - @Ignore - public void testCollectionsXML() throws Exception { - Document dom = getAsDOM("ogc/features/v1/collections?f=application/xml"); - print(dom); - // TODO: add actual tests - } - @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/features/v1/collections/?f=application/x-yaml"); + String yaml = getAsString("ogc/features/v1/collections/?f=application/yaml"); DocumentContext json = convertYamlToJsonPath(yaml); testCollectionsJson(json); } diff --git a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/ConformanceTest.java b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/ConformanceTest.java index 9c1de2a3925..fea6d12f131 100644 --- a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/ConformanceTest.java +++ b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/ConformanceTest.java @@ -17,8 +17,14 @@ import static org.geoserver.ogcapi.ConformanceClass.FEATURES_FILTER; import static org.geoserver.ogcapi.ConformanceClass.FILTER; import static org.geoserver.ogcapi.ConformanceClass.IDS; +import static org.geoserver.ogcapi.ConformanceClass.QUERYABLES; import static org.geoserver.ogcapi.ConformanceClass.SEARCH; import static org.geoserver.ogcapi.ConformanceClass.SORTBY; +import static org.geoserver.ogcapi.v1.features.FeatureService.CORE; +import static org.geoserver.ogcapi.v1.features.FeatureService.CRS_BY_REFERENCE; +import static org.geoserver.ogcapi.v1.features.FeatureService.GEOJSON; +import static org.geoserver.ogcapi.v1.features.FeatureService.HTML; +import static org.geoserver.ogcapi.v1.features.FeatureService.OAS30; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.Assert.assertEquals; @@ -26,9 +32,7 @@ import com.jayway.jsonpath.DocumentContext; import java.util.List; import java.util.stream.Collectors; -import org.junit.Ignore; import org.junit.Test; -import org.w3c.dom.Document; public class ConformanceTest extends FeaturesTestSupport { @@ -45,13 +49,14 @@ private void checkConformance(DocumentContext json) { private String[] getExpectedConformanceClasses() { return new String[] { - FeatureService.CORE, - FeatureService.OAS30, - FeatureService.HTML, - FeatureService.GEOJSON, - FeatureService.CRS_BY_REFERENCE, - FEATURES_FILTER, + CORE, + OAS30, + HTML, + GEOJSON, + CRS_BY_REFERENCE, FILTER, + QUERYABLES, + FEATURES_FILTER, SEARCH, ECQL, ECQL_TEXT, @@ -68,16 +73,9 @@ private String[] getExpectedConformanceClasses() { }; } - @Test - @Ignore - public void testConformanceXML() throws Exception { - Document dom = getAsDOM("ogc/features/v1?f=application/xml"); - print(dom); - } - @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/features/v1/conformance/?f=application/x-yaml"); + String yaml = getAsString("ogc/features/v1/conformance/?f=application/yaml"); checkConformance(convertYamlToJsonPath(yaml)); } diff --git a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/FeatureTest.java b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/FeatureTest.java index 0cc73e85f40..0845a648362 100644 --- a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/FeatureTest.java +++ b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/FeatureTest.java @@ -154,10 +154,10 @@ public void testWorkspaceQualified() throws Exception { @Test public void testBBoxFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( - "ogc/features/v1/collections/" + roadSegments + "/items?bbox=35,0,60,3", + "ogc/features/v1/collections/" + collectionName + "/items?bbox=35,0,60,3", 200); assertEquals("FeatureCollection", json.read("type", String.class)); // should return only f002 and f003 @@ -170,13 +170,13 @@ public void testBBoxFilter() throws Exception { @Test public void testBBoxCRSFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); ReferencedEnvelope bbox = new ReferencedEnvelope(35, 60, 0, 3, DefaultGeographicCRS.WGS84); ReferencedEnvelope wmBox = bbox.transform(CRS.decode("EPSG:3857", true), true); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?" + bboxCrsQueryParameters(wmBox), 200); @@ -209,11 +209,11 @@ private String crsQueryParameter(ReferencedEnvelope re) throws FactoryException @Test public void testBBOXOGCAuthority() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?" + "bbox=35,0,60,3" + "&bbox-crs=http://www.opengis.net/def/crs/OGC/1.3/CRS84", @@ -229,11 +229,11 @@ public void testBBOXOGCAuthority() throws Exception { @Test public void testInvalidBBOXCRS() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?" + "bbox=35,0,60,3" + "&bbox-crs=http://www.opengis.net/def/crs/OGC/1.3/INVALID", @@ -246,10 +246,10 @@ public void testInvalidBBOXCRS() throws Exception { @Test public void testBBoxDatelineCrossingFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( - "ogc/features/v1/collections/" + roadSegments + "/items?bbox=170,0,60,3", + "ogc/features/v1/collections/" + collectionName + "/items?bbox=170,0,60,3", 200); assertEquals("FeatureCollection", json.read("type", String.class)); // should return only f002 and f003 @@ -262,11 +262,11 @@ public void testBBoxDatelineCrossingFilter() throws Exception { @Test public void testCqlFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?filter=name='name-f001'", 200); assertEquals("FeatureCollection", json.read("type", String.class)); @@ -278,11 +278,11 @@ public void testCqlFilter() throws Exception { @Test public void testCql2JsonFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?filter=%7B%22op%22%3A%22%3D%22%2C%22args%22%3A%5B%7B%22property%22%3A%22name%22%7D%2C%22name-f001%22%5D%7D" // {"op":"=","args":[{"property":"name"},"name-f001"]} + "&filter-lang=cql2-json", 200); @@ -295,11 +295,11 @@ public void testCql2JsonFilter() throws Exception { @Test public void testCqlSpatialFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?filter=BBOX(pointProperty,38,1,40,3)&filter-lang=cql-text", 200); assertEquals("FeatureCollection", json.read("type", String.class)); @@ -311,11 +311,11 @@ public void testCqlSpatialFilter() throws Exception { @Test public void testCql2JsonSpatialFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?filter=%7B%22op%22%3A%22s_intersects%22%2C%22args%22%3A%5B%7B%22property%22%3A%22pointProperty%22%7D%2C%7B%22bbox%22%3A%5B38%2C1%2C40%2C3%5D%7D%5D%7D" // + "&filter-lang=cql2-json", 200); @@ -328,14 +328,14 @@ public void testCql2JsonSpatialFilter() throws Exception { @Test public void testCqlSpatialFilterWithFilterCrs() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); ReferencedEnvelope bbox = new ReferencedEnvelope(38, 40, 1, 3, DefaultGeographicCRS.WGS84); ReferencedEnvelope wmBox = bbox.transform(CRS.decode("EPSG:3857", true), true); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?" + filterCrsQueryParameters(wmBox), 200); @@ -352,14 +352,30 @@ private String filterCrsQueryParameters(ReferencedEnvelope re) throws FactoryExc return "filter=" + boxValue + "&filter-crs=" + crsValue + "&filter-lang=cql-text"; } + @Test + public void testCqlFilterInvalidFilter() throws Exception { + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); + + DocumentContext json = + getAsJSONPath( + "ogc/features/v1/collections/" + + collectionName + + "/items?filter=THIS IS NOT A FILTER", + 400); + assertEquals("InvalidParameterValue", json.read("code", String.class)); + assertThat( + json.read("description", String.class), + Matchers.containsString("THIS IS NOT A FILTER")); + } + @Test public void testCqlFilterInvalidCrs() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?filter=BBOX(pointProperty,38,1,40,3)&" + "filter-crs=" + FeatureService.CRS_PREFIX @@ -371,11 +387,11 @@ public void testCqlFilterInvalidCrs() throws Exception { @Test public void testCqlFilterInvalidLanguage() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?filter=name='name-f001'&filter-lang=foo-bar", 400); assertEquals("InvalidParameterValue", json.read("code", String.class)); @@ -384,11 +400,11 @@ public void testCqlFilterInvalidLanguage() throws Exception { @Test public void testTimeFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?datetime=2006-10-25", 200); assertEquals("FeatureCollection", json.read("type", String.class)); @@ -400,11 +416,11 @@ public void testTimeFilter() throws Exception { @Test public void testTimeRangeFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?datetime=2006-09-01/2006-10-23", 200); assertEquals("FeatureCollection", json.read("type", String.class)); @@ -417,11 +433,11 @@ public void testTimeRangeFilter() throws Exception { @Test public void testTimeDurationFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?datetime=2006-09-01/P1M23DT12H31M12S", 200); assertEquals("FeatureCollection", json.read("type", String.class)); @@ -434,11 +450,11 @@ public void testTimeDurationFilter() throws Exception { @Test public void testCombinedSpaceTimeFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?datetime=2006-09-01/2006-10-23&bbox=35,0,60,3", 200); assertEquals("FeatureCollection", json.read("type", String.class)); @@ -449,11 +465,11 @@ public void testCombinedSpaceTimeFilter() throws Exception { @Test public void testSortByWithDefaultSortOrder() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?sortby=name&limit=2", 200); assertEquals("FeatureCollection", json.read("type", String.class)); @@ -464,11 +480,11 @@ public void testSortByWithDefaultSortOrder() throws Exception { @Test public void testSortByWithAscendingSortOrder() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?sortby=%2Bname&limit=2", 200); assertEquals("FeatureCollection", json.read("type", String.class)); @@ -479,11 +495,11 @@ public void testSortByWithAscendingSortOrder() throws Exception { @Test public void testSortByWithDescendingSortOrder() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?sortby=-name&limit=2", 200); assertEquals("FeatureCollection", json.read("type", String.class)); @@ -494,11 +510,11 @@ public void testSortByWithDescendingSortOrder() throws Exception { @Test public void testSortByMultipleProperties() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); DocumentContext json = getAsJSONPath( "ogc/features/v1/collections/" - + roadSegments + + collectionName + "/items?sortby=booleanProperty,-intProperty", 200); assertEquals("FeatureCollection", json.read("type", String.class)); @@ -527,7 +543,7 @@ public void testIdsFilter() throws Exception { @Test public void testSearchCql2JsonFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); String request = "{\n" + " \"filter\": {\"op\":\"=\",\"args\":[{\"property\":\"name\"},\"name-f001\"]}," @@ -535,7 +551,7 @@ public void testSearchCql2JsonFilter() throws Exception { + "}"; DocumentContext json = postAsJSONPath( - "ogc/features/v1/collections/" + roadSegments + "/search", request, 200); + "ogc/features/v1/collections/" + collectionName + "/search", request, 200); assertEquals("FeatureCollection", json.read("type", String.class)); // should return only f001 assertEquals(1, (int) json.read("features.length()", Integer.class)); @@ -545,7 +561,7 @@ public void testSearchCql2JsonFilter() throws Exception { @Test public void testSearchCql2TextFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); String request = "{\n" + " \"filter\": \"BBOX(pointProperty,38,1,40,3)\",\n" @@ -553,7 +569,7 @@ public void testSearchCql2TextFilter() throws Exception { + "}"; DocumentContext json = postAsJSONPath( - "ogc/features/v1/collections/" + roadSegments + "/search", request, 200); + "ogc/features/v1/collections/" + collectionName + "/search", request, 200); assertEquals("FeatureCollection", json.read("type", String.class)); // should return only f001 assertEquals(1, (int) json.read("features.length()", Integer.class)); @@ -563,7 +579,7 @@ public void testSearchCql2TextFilter() throws Exception { @Test public void testSearchCql2TextFilterWithFilterCrs() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); ReferencedEnvelope bbox = new ReferencedEnvelope(38, 40, 1, 3, DefaultGeographicCRS.WGS84); ReferencedEnvelope wmBox = bbox.transform(CRS.decode("EPSG:3857", true), true); String crsValue = crsQueryParameter(wmBox); @@ -579,7 +595,7 @@ public void testSearchCql2TextFilterWithFilterCrs() throws Exception { + "\"\n}"; DocumentContext json = postAsJSONPath( - "ogc/features/v1/collections/" + roadSegments + "/search", request, 200); + "ogc/features/v1/collections/" + collectionName + "/search", request, 200); assertEquals("FeatureCollection", json.read("type", String.class)); // should return only f001 assertEquals(1, (int) json.read("features.length()", Integer.class)); @@ -589,11 +605,11 @@ public void testSearchCql2TextFilterWithFilterCrs() throws Exception { @Test public void testSearchBBoxJsonFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); String request = "{\"bbox\":[35, 0, 60, 3]}"; DocumentContext json = postAsJSONPath( - "ogc/features/v1/collections/" + roadSegments + "/search", request, 200); + "ogc/features/v1/collections/" + collectionName + "/search", request, 200); assertEquals("FeatureCollection", json.read("type", String.class)); // should return only f002 and f003 assertEquals(2, (int) json.read("features.length()", Integer.class)); @@ -605,11 +621,11 @@ public void testSearchBBoxJsonFilter() throws Exception { @Test public void testSearchBBoxTextFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); String request = "{\"bbox\":\"35,0,60,3\"}"; DocumentContext json = postAsJSONPath( - "ogc/features/v1/collections/" + roadSegments + "/search", request, 200); + "ogc/features/v1/collections/" + collectionName + "/search", request, 200); assertEquals("FeatureCollection", json.read("type", String.class)); // should return only f002 and f003 assertEquals(2, (int) json.read("features.length()", Integer.class)); @@ -621,7 +637,7 @@ public void testSearchBBoxTextFilter() throws Exception { @Test public void testSearchBBoxCRSFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); ReferencedEnvelope bbox = new ReferencedEnvelope(35, 60, 0, 3, DefaultGeographicCRS.WGS84); ReferencedEnvelope wmBox = bbox.transform(CRS.decode("EPSG:3857", true), true); String boxValue = bboxQueryParameter(wmBox); @@ -629,7 +645,7 @@ public void testSearchBBoxCRSFilter() throws Exception { String request = "{\"bbox\":\"" + boxValue + "\",\"bbox-crs\":\"" + bboxCrsValue + "\"}"; DocumentContext json = postAsJSONPath( - "ogc/features/v1/collections/" + roadSegments + "/search", request, 200); + "ogc/features/v1/collections/" + collectionName + "/search", request, 200); assertEquals("FeatureCollection", json.read("type", String.class)); // should return only f002 and f003 assertEquals(2, (int) json.read("features.length()", Integer.class)); @@ -694,11 +710,11 @@ public void testSearchIdsTextFilter() throws Exception { @Test public void testSearchDatetimeFilter() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); String request = "{\"datetime\":\"2006-10-25\"}"; DocumentContext json = postAsJSONPath( - "ogc/features/v1/collections/" + roadSegments + "/search", request, 200); + "ogc/features/v1/collections/" + collectionName + "/search", request, 200); assertEquals("FeatureCollection", json.read("type", String.class)); // should return only f001 assertEquals(1, (int) json.read("features.length()", Integer.class)); @@ -708,11 +724,11 @@ public void testSearchDatetimeFilter() throws Exception { @Test public void testSearchSortByJson() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); String request = "{\"sortby\":[\"name\"],\"limit\":2}"; DocumentContext json = postAsJSONPath( - "ogc/features/v1/collections/" + roadSegments + "/search", request, 200); + "ogc/features/v1/collections/" + collectionName + "/search", request, 200); assertEquals("FeatureCollection", json.read("type", String.class)); assertEquals(2, (int) json.read("features.length()", Integer.class)); assertEquals(null, json.read("features[0].properties.name", String.class)); @@ -721,11 +737,11 @@ public void testSearchSortByJson() throws Exception { @Test public void testSearchSortByText() throws Exception { - String roadSegments = getLayerId(MockData.PRIMITIVEGEOFEATURE); + String collectionName = getLayerId(MockData.PRIMITIVEGEOFEATURE); String request = "{\"sortby\":\"name\",\"limit\":2}"; DocumentContext json = postAsJSONPath( - "ogc/features/v1/collections/" + roadSegments + "/search", request, 200); + "ogc/features/v1/collections/" + collectionName + "/search", request, 200); assertEquals("FeatureCollection", json.read("type", String.class)); assertEquals(2, (int) json.read("features.length()", Integer.class)); assertEquals(null, json.read("features[0].properties.name", String.class)); diff --git a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/FunctionsTest.java b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/FunctionsTest.java index f0a07b47e7f..b3170ee5c6b 100644 --- a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/FunctionsTest.java +++ b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/FunctionsTest.java @@ -4,11 +4,23 @@ */ package org.geoserver.ogcapi.v1.features; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import com.github.erosb.jsonsKema.FormatValidationPolicy; +import com.github.erosb.jsonsKema.JsonParser; +import com.github.erosb.jsonsKema.JsonValue; +import com.github.erosb.jsonsKema.Schema; +import com.github.erosb.jsonsKema.SchemaLoader; +import com.github.erosb.jsonsKema.ValidationFailure; +import com.github.erosb.jsonsKema.Validator; +import com.github.erosb.jsonsKema.ValidatorConfig; import com.jayway.jsonpath.DocumentContext; import org.geoserver.data.test.SystemTestData; +import org.hamcrest.Matchers; import org.junit.Test; +import org.springframework.mock.web.MockHttpServletResponse; public class FunctionsTest extends FeaturesTestSupport { @@ -18,13 +30,28 @@ protected void setUpTestData(SystemTestData testData) throws Exception { } @Test - public void testCapabilities() throws Exception { + public void testSchemaValid() throws Exception { + MockHttpServletResponse response = getAsServletResponse("ogc/features/v1/functions"); + + // check the response abides to the functions schema + Schema schema = + SchemaLoader.forURL( + "classpath:/org/geoserver/ogcapi/v1/features/functions-schema.yml") + .load(); + JsonValue functionsJSON = new JsonParser(response.getContentAsString()).parse(); + Validator validator = + Validator.create(schema, new ValidatorConfig(FormatValidationPolicy.ALWAYS)); + ValidationFailure failure = validator.validate(functionsJSON); + assertNull(failure); + } + + @Test + public void testFunctions() throws Exception { DocumentContext json = getAsJSONPath("ogc/features/v1/functions", 200); // test one random function DocumentContext function = readSingleContext(json, "functions[?(@.name=='strSubstring')]"); - assertEquals("substring", function.read("returns.title")); - assertEquals("string", readSingle(function, "returns.type")); + assertEquals("string", function.read("returns[0]")); assertEquals("string", function.read("arguments[0].title")); assertEquals("string", readSingle(function, "arguments[0].type")); assertEquals("beginIndex", function.read("arguments[1].title")); @@ -32,4 +59,24 @@ public void testCapabilities() throws Exception { assertEquals("endIndex", function.read("arguments[2].title")); assertEquals("integer", readSingle(function, "arguments[2].type")); } + + @Test + public void testFunctionsHTML() throws Exception { + MockHttpServletResponse response = getAsServletResponse("ogc/features/v1/functions?f=html"); + assertEquals("text/html", response.getContentType()); + // the table is hard to look up, so let's check the representation for a given function + assertThat( + response.getContentAsString(), + Matchers.containsString( + "

    Area

    \n" + + "
      \n" + + "
    • Returns: number
    • \n" + + "
    • Arguments:\n" + + " \n" + + " \n" + + " \n" + + "
      NameTitleType
      geometrygeometrygeometry
      \n" + + "
    • \n" + + "
    ")); + } } diff --git a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/LandingPageTest.java b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/LandingPageTest.java index 65ce688fa16..e435a8d4a7c 100644 --- a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/LandingPageTest.java +++ b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/LandingPageTest.java @@ -12,6 +12,7 @@ import com.jayway.jsonpath.DocumentContext; import java.util.List; import org.geoserver.config.GeoServer; +import org.geoserver.ogcapi.FunctionsDocument; import org.geoserver.ogcapi.Link; import org.geoserver.ogcapi.OpenAPIMessageConverter; import org.geoserver.platform.Service; @@ -19,10 +20,8 @@ import org.geotools.util.Version; import org.hamcrest.CoreMatchers; import org.hamcrest.Matchers; -import org.junit.Ignore; import org.junit.Test; import org.springframework.mock.web.MockHttpServletResponse; -import org.w3c.dom.Document; public class LandingPageTest extends FeaturesTestSupport { @@ -73,26 +72,18 @@ public void testLandingPageWorkspaceSpecific() throws Exception { checkJSONLandingPage(json); } - @Test - @Ignore - public void testLandingPageXML() throws Exception { - Document dom = getAsDOM("ogc/features/v1?f=application/xml"); - print(dom); - // TODO: add actual tests in here - } - @Test public void testLandingPageYaml() throws Exception { - String yaml = getAsString("ogc/features/v1?f=application/x-yaml"); + String yaml = getAsString("ogc/features/v1?f=application/yaml"); // System.out.println(yaml); DocumentContext json = convertYamlToJsonPath(yaml); assertJSONList( json, - "links[?(@.type == 'application/x-yaml' && @.href =~ /.*ogc\\/features\\/v1\\/\\?.*/)].rel", + "links[?(@.type == 'application/yaml' && @.href =~ /.*ogc\\/features\\/v1\\/\\?.*/)].rel", "self"); assertJSONList( json, - "links[?(@.type != 'application/x-yaml' && @.href =~ /.*ogc\\/features\\/v1\\/\\?.*/)].rel", + "links[?(@.type != 'application/yaml' && @.href =~ /.*ogc\\/features\\/v1\\/\\?.*/)].rel", "alternate", "alternate"); checkJSONLandingPageShared(json); @@ -170,6 +161,15 @@ void checkJSONLandingPageShared(DocumentContext json) { Link.REL_DATA, Link.REL_DATA, Link.REL_DATA); + + // check collection links + assertJSONList( + json, + "links[?(@.href =~ /.*ogc\\/features\\/v1\\/functions.*/)].rel", + FunctionsDocument.REL, + FunctionsDocument.REL, + FunctionsDocument.REL); + // check title assertEquals("Features 1.0 server", json.read("title")); // check description @@ -183,7 +183,7 @@ public void testLandingPageHeaders() throws Exception { assertThat( link, hasItems( - "; rel=\"alternate\"; type=\"application/x-yaml\"; title=\"This document as application/x-yaml\"", + "; rel=\"alternate\"; type=\"application/yaml\"; title=\"This document as application/yaml\"", "; rel=\"self\"; type=\"application/json\"; title=\"This document\"")); } diff --git a/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/QueryablesTest.java b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/QueryablesTest.java new file mode 100644 index 00000000000..96385a2d503 --- /dev/null +++ b/src/community/ogcapi/ogcapi-features/src/test/java/org/geoserver/ogcapi/v1/features/QueryablesTest.java @@ -0,0 +1,93 @@ +/* (c) 2024 Open Source Geospatial Foundation - all rights reserved + * This code is licensed under the GPL 2.0 license, available at the root + * application directory. + */ + +package org.geoserver.ogcapi.v1.features; + +import static org.geoserver.data.test.CiteTestData.ROAD_SEGMENTS; +import static org.junit.Assert.assertEquals; + +import com.github.erosb.jsonsKema.JsonParser; +import com.github.erosb.jsonsKema.JsonValue; +import com.github.erosb.jsonsKema.SchemaLoader; +import com.jayway.jsonpath.DocumentContext; +import java.io.UnsupportedEncodingException; +import org.geoserver.data.test.MockData; +import org.geoserver.ogcapi.Queryables; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +public class QueryablesTest extends FeaturesTestSupport { + + @Test + public void testDefaultFormat() throws Exception { + MockHttpServletResponse response = + getAsMockHttpServletResponse(roadSegmentQueryables(), 200); + assertEquals("application/schema+json", response.getContentType()); + + checkRoadSegmentsQueryables(response); + } + + @Test + public void testFullFormatParameter() throws Exception { + MockHttpServletResponse response = + getAsMockHttpServletResponse( + roadSegmentQueryables() + "?f=application/schema%2Bjson", 200); + assertEquals("application/schema+json", response.getContentType()); + + checkRoadSegmentsQueryables(response); + } + + private String roadSegmentQueryables() { + return "ogc/features/v1/collections/" + getLayerId(ROAD_SEGMENTS) + "/queryables"; + } + + @Test + public void testAcceptHeader() throws Exception { + MockHttpServletRequest request = createRequest(roadSegmentQueryables()); + request.setMethod("GET"); + request.addHeader("Accept", "application/schema+json"); + + MockHttpServletResponse response = dispatch(request, null); + assertEquals(200, response.getStatus()); + checkRoadSegmentsQueryables(response); + } + + private void checkRoadSegmentsQueryables(MockHttpServletResponse response) + throws UnsupportedEncodingException { + DocumentContext json = getAsJSONPath(response); + assertEquals("geometry-multilinestring", json.read("properties.the_geom.format")); + assertEquals("string", json.read("properties.FID.type")); + assertEquals("string", json.read("properties.FID.title")); + assertEquals("string", json.read("properties.NAME.type")); + assertEquals("string", json.read("properties.NAME.title")); + assertEquals(Queryables.JSON_SCHEMA_DRAFT_2020_12, readSingle(json, ".$schema")); + assertEquals( + "http://localhost:8080/geoserver/ogc/features/v1/collections/cite%3ARoadSegments/queryables", + readSingle(json, ".$id")); + assertEquals("object", json.read("type")); + } + + @Test + public void testQueryablesHTML() throws Exception { + String roadSegments = MockData.ROAD_SEGMENTS.getLocalPart(); + org.jsoup.nodes.Document document = + getAsJSoup( + "cite/ogc/features/v1/collections/" + roadSegments + "/queryables?f=html"); + assertEquals("the_geom: MultiLineString", document.select("#queryables li:eq(0)").text()); + } + + @Test + public void queryablesSchema() throws Exception { + MockHttpServletResponse response = + getAsMockHttpServletResponse( + roadSegmentQueryables() + "?f=application/schema%2Bjson", 200); + + // check the response can be read as a valid JSON schema (will fail with an exception if + // not) + JsonValue schemaJSON = new JsonParser(response.getContentAsString()).parse(); + new SchemaLoader(schemaJSON).load(); + } +} diff --git a/src/community/ogcapi/ogcapi-features/src/test/resources/org/geoserver/ogcapi/v1/features/functions-schema.yml b/src/community/ogcapi/ogcapi-features/src/test/resources/org/geoserver/ogcapi/v1/features/functions-schema.yml new file mode 100644 index 00000000000..9c46f13b06e --- /dev/null +++ b/src/community/ogcapi/ogcapi-features/src/test/resources/org/geoserver/ogcapi/v1/features/functions-schema.yml @@ -0,0 +1,52 @@ +type: object +required: + - functions +properties: + functions: + type: array + items: + type: object + required: + - name + - returns + properties: + name: + type: string + description: + type: string + metadataUrl: + type: string + format: uri-reference + arguments: + type: array + items: + type: object + required: + - type + properties: + title: + type: string + description: + type: string + type: + type: array + items: + type: string + enum: + - string + - number + - integer + - datetime + - geometry + - boolean + returns: + type: array + items: + type: string + enum: + - string + - number + - integer + - datetime + - geometry + - boolean \ No newline at end of file diff --git a/src/community/ogcapi/ogcapi-features/src/test/resources/org/geoserver/ogcapi/v1/features/tiger_poi.properties b/src/community/ogcapi/ogcapi-features/src/test/resources/org/geoserver/ogcapi/v1/features/tiger_poi.properties new file mode 100644 index 00000000000..e9b7f9a5ad3 --- /dev/null +++ b/src/community/ogcapi/ogcapi-features/src/test/resources/org/geoserver/ogcapi/v1/features/tiger_poi.properties @@ -0,0 +1,7 @@ +_=the_geom:Point,NAME:string,THUMBNAIL:string,MAINPAGE:string +poi.1=POINT (-74.01046109936333 40.707587626256554)|museam|pics/22037827-Ti.jpg|pics/22037827-L.jpg +poi.2=POINT (-74.0108375113659 40.70754683896324)|stock|pics/22037829-Ti.jpg|pics/22037829-L.jpg +poi.3=POINT (-74.01053023879955 40.70938711687079)|art|pics/22037856-Ti.jpg|pics/22037856-L.jpg +poi.4=POINT (-74.00857344353275 40.711945649065406)|lox|pics/22037884-Ti.jpg|pics/22037884-L.jpg +poi.5=POINT (-74.0118315772888 40.708529961953786)|church|pics/22037839-Ti.jpg|pics/22037839-L.jpg +poi.6=POINT (-74.00153046439813 40.719885123828675)|fire|pics/28640984-Ti.jpg|pics/28640984-L.jpg diff --git a/src/community/ogcapi/ogcapi-features/src/test/resources/org/geoserver/ogcapi/v1/features/tiger_single_poi.properties b/src/community/ogcapi/ogcapi-features/src/test/resources/org/geoserver/ogcapi/v1/features/tiger_single_poi.properties new file mode 100644 index 00000000000..9d72f8b8886 --- /dev/null +++ b/src/community/ogcapi/ogcapi-features/src/test/resources/org/geoserver/ogcapi/v1/features/tiger_single_poi.properties @@ -0,0 +1,2 @@ +_=the_geom:Point,NAME:string,THUMBNAIL:string,MAINPAGE:string +poi.1=POINT (-74.01046109936333 40.707587626256554)|museam|pics/22037827-Ti.jpg|pics/22037827-L.jpg diff --git a/src/community/ogcapi/ogcapi-images/pom.xml b/src/community/ogcapi/ogcapi-images/pom.xml index 575b2aa8e9d..294bf6f77d6 100644 --- a/src/community/ogcapi/ogcapi-images/pom.xml +++ b/src/community/ogcapi/ogcapi-images/pom.xml @@ -42,7 +42,6 @@ org.geotools.jdbc gt-jdbc-h2 - ${gt.version} org.geoserver diff --git a/src/community/ogcapi/ogcapi-images/src/main/java/org/geoserver/ogcapi/v1/images/ImagesCollectionsDocument.java b/src/community/ogcapi/ogcapi-images/src/main/java/org/geoserver/ogcapi/v1/images/ImagesCollectionsDocument.java index 2d5c2397ddf..7a719f794f0 100644 --- a/src/community/ogcapi/ogcapi-images/src/main/java/org/geoserver/ogcapi/v1/images/ImagesCollectionsDocument.java +++ b/src/community/ogcapi/ogcapi-images/src/main/java/org/geoserver/ogcapi/v1/images/ImagesCollectionsDocument.java @@ -45,7 +45,7 @@ public Iterator getCollections() { boolean skipInvalid = gs.getGlobal().getResourceErrorHandling() == ResourceErrorHandling.SKIP_MISCONFIGURED_LAYERS; - return new Iterator() { + return new Iterator<>() { ImagesCollectionDocument next; diff --git a/src/community/ogcapi/ogcapi-images/src/main/java/org/geoserver/ogcapi/v1/images/ImagesService.java b/src/community/ogcapi/ogcapi-images/src/main/java/org/geoserver/ogcapi/v1/images/ImagesService.java index 60be0f9a899..dfb17fe5c78 100644 --- a/src/community/ogcapi/ogcapi-images/src/main/java/org/geoserver/ogcapi/v1/images/ImagesService.java +++ b/src/community/ogcapi/ogcapi-images/src/main/java/org/geoserver/ogcapi/v1/images/ImagesService.java @@ -653,7 +653,7 @@ public ResponseEntity deleteImage( imageListeners.imageRemoved(info, feature); - return new ResponseEntity(HttpStatus.OK); + return new ResponseEntity<>(HttpStatus.OK); } @Override diff --git a/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/ApiTest.java b/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/ApiTest.java index 6f2db304f66..190f74ff7cc 100644 --- a/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/ApiTest.java +++ b/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/ApiTest.java @@ -88,7 +88,7 @@ public void testApiHTML() throws Exception { @Test public void testApiYaml() throws Exception { - String yaml = getAsString("ogc/images/v1/openapi?f=application/x-yaml"); + String yaml = getAsString("ogc/images/v1/openapi?f=application/yaml"); LOGGER.log(Level.INFO, yaml); ObjectMapper mapper = Yaml.mapper(); @@ -101,10 +101,10 @@ public void testYamlAsAcceptsHeader() throws Exception { MockHttpServletRequest request = createRequest("ogc/images/v1/openapi"); request.setMethod("GET"); request.setContent(new byte[] {}); - request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/x-yaml, text/html"); + request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/yaml, text/html"); MockHttpServletResponse response = dispatch(request); assertEquals(200, response.getStatus()); - assertThat(response.getContentType(), CoreMatchers.startsWith("application/x-yaml")); + assertThat(response.getContentType(), CoreMatchers.startsWith("application/yaml")); String yaml = string(new ByteArrayInputStream(response.getContentAsString().getBytes())); ObjectMapper mapper = Yaml.mapper(); @@ -154,10 +154,10 @@ public void testWorkspaceQualifiedAPI() throws Exception { MockHttpServletRequest request = createRequest("gs/ogc/images/v1/openapi"); request.setMethod("GET"); request.setContent(new byte[] {}); - request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/x-yaml, text/html"); + request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/yaml, text/html"); MockHttpServletResponse response = dispatch(request); assertEquals(200, response.getStatus()); - assertEquals("application/x-yaml", response.getContentType()); + assertEquals("application/yaml", response.getContentType()); String yaml = string(new ByteArrayInputStream(response.getContentAsString().getBytes())); // System.out.println(yaml); diff --git a/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/CollectionTest.java b/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/CollectionTest.java index 9d3ecdcc80e..1d9799c07b2 100644 --- a/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/CollectionTest.java +++ b/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/CollectionTest.java @@ -54,8 +54,7 @@ protected void testWaterTempCollectionJson(DocumentContext json) { @Test public void testImagesCollectionYaml() throws Exception { String waterTemp = getLayerId(WATER_TEMP); - String yaml = - getAsString("ogc/images/v1/collections/" + waterTemp + "?f=application/x-yaml"); + String yaml = getAsString("ogc/images/v1/collections/" + waterTemp + "?f=application/yaml"); DocumentContext json = convertYamlToJsonPath(yaml); testWaterTempCollectionJson(json); } diff --git a/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/CollectionsTest.java b/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/CollectionsTest.java index aff7eafce28..1b1dde09b01 100644 --- a/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/CollectionsTest.java +++ b/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/CollectionsTest.java @@ -31,9 +31,9 @@ public void testCollectionsJson() throws Exception { @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/images/v1/collections/?f=application/x-yaml"); + String yaml = getAsString("ogc/images/v1/collections/?f=application/yaml"); DocumentContext json = convertYamlToJsonPath(yaml); - testCollectionsJson(json, MediaType.parseMediaType("application/x-yaml")); + testCollectionsJson(json, MediaType.parseMediaType("application/yaml")); } private void testCollectionsJson(DocumentContext json, MediaType defaultFormat) diff --git a/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/ConformanceTest.java b/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/ConformanceTest.java index cf4fa2ecbd3..296e904d43e 100644 --- a/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/ConformanceTest.java +++ b/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/ConformanceTest.java @@ -30,7 +30,7 @@ private void checkConformance(DocumentContext json) { @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/images/v1/conformance/?f=application/x-yaml"); + String yaml = getAsString("ogc/images/v1/conformance/?f=application/yaml"); checkConformance(convertYamlToJsonPath(yaml)); } diff --git a/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/LandingPageTest.java b/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/LandingPageTest.java index 9ce218ab466..3f3e981ed47 100644 --- a/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/LandingPageTest.java +++ b/src/community/ogcapi/ogcapi-images/src/test/java/org/geoserver/ogcapi/v1/images/LandingPageTest.java @@ -71,16 +71,16 @@ public void testLandingPageWorkspaceSpecific() throws Exception { @Test public void testLandingPageYaml() throws Exception { - String yaml = getAsString("ogc/images/v1?f=application/x-yaml"); + String yaml = getAsString("ogc/images/v1?f=application/yaml"); // System.out.println(yaml); DocumentContext json = convertYamlToJsonPath(yaml); assertJSONList( json, - "links[?(@.type == 'application/x-yaml' && @.href =~ /.*ogc\\/images\\/v1\\/\\?.*/)].rel", + "links[?(@.type == 'application/yaml' && @.href =~ /.*ogc\\/images\\/v1\\/\\?.*/)].rel", "self"); assertJSONList( json, - "links[?(@.type != 'application/x-yaml' && @.href =~ /.*ogc\\/images\\/v1\\/\\?.*/)].rel", + "links[?(@.type != 'application/yaml' && @.href =~ /.*ogc\\/images\\/v1\\/\\?.*/)].rel", "alternate", "alternate"); checkJSONLandingPageShared(json); diff --git a/src/community/ogcapi/ogcapi-maps/src/main/java/org/geoserver/ogcapi/v1/maps/CollectionsDocument.java b/src/community/ogcapi/ogcapi-maps/src/main/java/org/geoserver/ogcapi/v1/maps/CollectionsDocument.java index 8e5d6b938af..b1d7acfc6dd 100644 --- a/src/community/ogcapi/ogcapi-maps/src/main/java/org/geoserver/ogcapi/v1/maps/CollectionsDocument.java +++ b/src/community/ogcapi/ogcapi-maps/src/main/java/org/geoserver/ogcapi/v1/maps/CollectionsDocument.java @@ -47,7 +47,7 @@ public Iterator getCollections() { @SuppressWarnings("PMD.CloseResource") // wrapped and returned CloseableIterator publisheds = geoServer.getCatalog().list(PublishedInfo.class, Filter.INCLUDE); - return new Iterator() { + return new Iterator<>() { CollectionDocument next; diff --git a/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/CollectionsTest.java b/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/CollectionsTest.java index a4eebaa9aa0..7f259da0164 100644 --- a/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/CollectionsTest.java +++ b/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/CollectionsTest.java @@ -34,9 +34,9 @@ public void testCollectionsJson() throws Exception { @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/maps/v1/collections/?f=application/x-yaml"); + String yaml = getAsString("ogc/maps/v1/collections/?f=application/yaml"); DocumentContext json = convertYamlToJsonPath(yaml); - testCollectionsJson(json, MediaType.parseMediaType("application/x-yaml")); + testCollectionsJson(json, MediaType.parseMediaType("application/yaml")); } private void testCollectionsJson(DocumentContext json, MediaType defaultFormat) diff --git a/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/ConformanceTest.java b/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/ConformanceTest.java index 109130d86f4..1ee90e4bff1 100644 --- a/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/ConformanceTest.java +++ b/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/ConformanceTest.java @@ -32,7 +32,7 @@ private void checkConformance(DocumentContext json) { @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/maps/v1/conformance/?f=application/x-yaml"); + String yaml = getAsString("ogc/maps/v1/conformance/?f=application/yaml"); checkConformance(convertYamlToJsonPath(yaml)); } diff --git a/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/LandingPageTest.java b/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/LandingPageTest.java index 2ffbc782f13..1f00433a2cc 100644 --- a/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/LandingPageTest.java +++ b/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/LandingPageTest.java @@ -61,16 +61,16 @@ public void testLandingPageJSON() throws Exception { @Test public void testLandingPageYaml() throws Exception { - String yaml = getAsString("ogc/maps/v1?f=application/x-yaml"); + String yaml = getAsString("ogc/maps/v1?f=application/yaml"); // System.out.println(yaml); DocumentContext json = convertYamlToJsonPath(yaml); assertJSONList( json, - "links[?(@.type == 'application/x-yaml' && @.href =~ /.*ogc\\/maps\\/v1\\/\\?.*/)].rel", + "links[?(@.type == 'application/yaml' && @.href =~ /.*ogc\\/maps\\/v1\\/\\?.*/)].rel", "self"); assertJSONList( json, - "links[?(@.type != 'application/x-yaml' && @.href =~ /.*ogc\\/maps\\/v1\\/\\?.*/)].rel", + "links[?(@.type != 'application/yaml' && @.href =~ /.*ogc\\/maps\\/v1\\/\\?.*/)].rel", "alternate", "alternate"); checkJSONLandingPageShared(json); diff --git a/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/MapsTest.java b/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/MapsTest.java index 0079e6d565e..283ff06db98 100644 --- a/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/MapsTest.java +++ b/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/MapsTest.java @@ -5,13 +5,10 @@ package org.geoserver.ogcapi.v1.maps; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; import com.jayway.jsonpath.DocumentContext; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.jsoup.nodes.DataNode; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; @@ -47,8 +44,7 @@ public void testDatetimeHTMLMapsFormat() throws Exception { Document document = getAsJSoup( "ogc/maps/v1/collections/sf:TimeWithStartEnd/styles/Default/map?f=html&datetime=2012-02-12T00:00:00Z"); - boolean found = searchParameter(document, "\"datetime\": '2012-02-12T00:00:00Z'"); - assertTrue(found); + assertEquals("2012-02-12T00:00:00Z", getParameterValue(document, "datetime")); } @Test @@ -57,27 +53,15 @@ public void testHTMLNoDatetime() throws Exception { // failed here when no datetime provided, FTL processing error, null on js_string Document document = getAsJSoup("ogc/maps/v1/collections/sf:TimeWithStartEnd/styles/Default/map?f=html"); - boolean found = searchParameter(document, "\"datetime\": '2012-02-12T00:00:00Z'"); - assertFalse(found); + assertNull(getParameterValue(document, "datetime")); } - private static boolean searchParameter(Document document, String keyValue) { - Elements scriptsOnPage = document.select("script"); - Matcher matcher = null; - // check that the datetime is in the javascript parameters - String keyToFind = "datetime"; - Pattern pattern = Pattern.compile("\"" + keyToFind + "\":\\s*'(.*?)'"); - boolean found = false; - for (Element element : scriptsOnPage) { - for (DataNode node : element.dataNodes()) { - matcher = pattern.matcher(node.getWholeData()); - while (matcher.find()) { - if (matcher.group().equals(keyValue)) { - found = true; - } - } - } - } - return found; + private static String getParameterValue(Document document, String key) { + Elements parameters = document.select("input[type='hidden'][title='" + key + "']"); + if (parameters.isEmpty()) return null; + if (parameters.size() > 1) + fail("Found more than one element with key " + key + ": " + parameters); + Element parameter = parameters.first(); + return parameter.attr("value"); } } diff --git a/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/StylesTest.java b/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/StylesTest.java index 437206153e3..76a3b29c0df 100644 --- a/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/StylesTest.java +++ b/src/community/ogcapi/ogcapi-maps/src/test/java/org/geoserver/ogcapi/v1/maps/StylesTest.java @@ -43,9 +43,9 @@ public void testCollectionsJsonSlash() throws Exception { @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/maps/v1/collections/BlueMarble/styles?f=application/x-yaml"); + String yaml = getAsString("ogc/maps/v1/collections/BlueMarble/styles?f=application/yaml"); DocumentContext json = convertYamlToJsonPath(yaml); - testStylesJson(json, MediaType.parseMediaType("application/x-yaml")); + testStylesJson(json, MediaType.parseMediaType("application/yaml")); } private void testStylesJson(DocumentContext json, MediaType defaultFormat) { diff --git a/src/community/ogcapi/ogcapi-styles/pom.xml b/src/community/ogcapi/ogcapi-styles/pom.xml index e994c5e2616..1533e0610c0 100644 --- a/src/community/ogcapi/ogcapi-styles/pom.xml +++ b/src/community/ogcapi/ogcapi-styles/pom.xml @@ -61,7 +61,6 @@ org.geotools gt-jdbc - ${gt.version} test-jar test diff --git a/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StyleAttributeExtractor.java b/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StyleAttributeExtractor.java index b78fc5c99ae..73093073581 100644 --- a/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StyleAttributeExtractor.java +++ b/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StyleAttributeExtractor.java @@ -317,10 +317,7 @@ public void visit(TextSymbolizer text) { } } - if (text instanceof TextSymbolizer) { - if (((TextSymbolizer) text).getGraphic() != null) - ((TextSymbolizer) text).getGraphic().accept(this); - } + if (text.getGraphic() != null) text.getGraphic().accept(this); if (text.getFill() != null) { text.getFill().accept(this); diff --git a/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StyleLayer.java b/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StyleLayer.java index 51f01d4ac27..59e02e504ed 100644 --- a/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StyleLayer.java +++ b/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StyleLayer.java @@ -59,7 +59,7 @@ enum LayerType { polygon, geometry, raster - }; + } String id; LayerType type; diff --git a/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StylesDocument.java b/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StylesDocument.java index 03ed66f597a..8dc5fa29cd8 100644 --- a/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StylesDocument.java +++ b/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StylesDocument.java @@ -29,7 +29,7 @@ public StylesDocument(Catalog catalog) { public Iterator getStyles() { // full scan (we might add paging/filtering later) CloseableIterator styles = catalog.list(StyleInfo.class, Filter.INCLUDE); - return new Iterator() { + return new Iterator<>() { StyleDocument next; diff --git a/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StylesService.java b/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StylesService.java index eb37e7ff154..d14000181f9 100644 --- a/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StylesService.java +++ b/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/StylesService.java @@ -335,7 +335,7 @@ public ResponseEntity postStyle( // validation if (validate == only || validate == yes) { validate(mimeType, content, handler); - return new ResponseEntity(HttpStatus.NO_CONTENT); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); } else { String styleId = getStyleId(mimeType, handler, content); StyleInfo styleInfo = getStyleInfo(styleId, false); diff --git a/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/ThumbnailBuilder.java b/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/ThumbnailBuilder.java index 36130ce1b56..19e3be7e0ae 100644 --- a/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/ThumbnailBuilder.java +++ b/src/community/ogcapi/ogcapi-styles/src/main/java/org/geoserver/ogcapi/v1/styles/ThumbnailBuilder.java @@ -172,6 +172,6 @@ public boolean canGenerateThumbnail(StyleInfo styleInfo) { LOGGER.log(Level.FINER, "Could not setup thumbnail", e); } // if we have at least a layer, we can work it - return request.getLayers().size() > 0; + return !request.getLayers().isEmpty(); } } diff --git a/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/ApiTest.java b/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/ApiTest.java index b1820789ab4..2c84ad0aca2 100644 --- a/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/ApiTest.java +++ b/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/ApiTest.java @@ -91,7 +91,7 @@ public void testApiHTML() throws Exception { @Test public void testApiYaml() throws Exception { - String yaml = getAsString("ogc/styles/v1/openapi?f=application/x-yaml"); + String yaml = getAsString("ogc/styles/v1/openapi?f=application/yaml"); LOGGER.log(Level.INFO, yaml); ObjectMapper mapper = Yaml.mapper(); @@ -104,10 +104,10 @@ public void testYamlAsAcceptsHeader() throws Exception { MockHttpServletRequest request = createRequest("ogc/styles/v1/openapi"); request.setMethod("GET"); request.setContent(new byte[] {}); - request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/x-yaml, text/html"); + request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/yaml, text/html"); MockHttpServletResponse response = dispatch(request); assertEquals(200, response.getStatus()); - assertThat(response.getContentType(), CoreMatchers.startsWith("application/x-yaml")); + assertThat(response.getContentType(), CoreMatchers.startsWith("application/yaml")); String yaml = string(new ByteArrayInputStream(response.getContentAsString().getBytes())); ObjectMapper mapper = Yaml.mapper(); @@ -217,10 +217,10 @@ private OpenAPI getOpenAPI(String path) throws Exception { MockHttpServletRequest request = createRequest(path); request.setMethod("GET"); request.setContent(new byte[] {}); - request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/x-yaml, text/html"); + request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/yaml, text/html"); MockHttpServletResponse response = dispatch(request); assertEquals(200, response.getStatus()); - assertEquals("application/x-yaml", response.getContentType()); + assertEquals("application/yaml", response.getContentType()); String yaml = string(new ByteArrayInputStream(response.getContentAsString().getBytes())); ObjectMapper mapper = Yaml.mapper(); diff --git a/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/ConformanceTest.java b/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/ConformanceTest.java index 09671948c32..5434afe3507 100644 --- a/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/ConformanceTest.java +++ b/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/ConformanceTest.java @@ -31,7 +31,7 @@ private void checkConformance(DocumentContext json) { @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/styles/v1/conformance/?f=application/x-yaml"); + String yaml = getAsString("ogc/styles/v1/conformance/?f=application/yaml"); checkConformance(convertYamlToJsonPath(yaml)); } diff --git a/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/LandingPageTest.java b/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/LandingPageTest.java index f3d31d49d88..ab7fb0fa8df 100644 --- a/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/LandingPageTest.java +++ b/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/LandingPageTest.java @@ -81,16 +81,16 @@ public void testLandingPageXML() throws Exception { @Test public void testLandingPageYaml() throws Exception { - String yaml = getAsString("ogc/styles/v1?f=application/x-yaml"); + String yaml = getAsString("ogc/styles/v1?f=application/yaml"); // System.out.println(yaml); DocumentContext json = convertYamlToJsonPath(yaml); assertJSONList( json, - "links[?(@.type == 'application/x-yaml' && @.href =~ /.*ogc\\/styles\\/v1\\/\\?.*/)].rel", + "links[?(@.type == 'application/yaml' && @.href =~ /.*ogc\\/styles\\/v1\\/\\?.*/)].rel", "self"); assertJSONList( json, - "links[?(@.type != 'application/x-yaml' && @.href =~ /.*ogc\\/styles\\/v1\\/\\?.*/)].rel", + "links[?(@.type != 'application/yaml' && @.href =~ /.*ogc\\/styles\\/v1\\/\\?.*/)].rel", "alternate", "alternate"); checkJSONLandingPageShared(json); diff --git a/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/StylesTest.java b/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/StylesTest.java index eb98773fa07..b556c5e4bff 100644 --- a/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/StylesTest.java +++ b/src/community/ogcapi/ogcapi-styles/src/test/java/org/geoserver/ogcapi/v1/styles/StylesTest.java @@ -31,7 +31,7 @@ private void testStylesJson(DocumentContext json) { // check the self link assertEquals("self", readSingle(json, "links[?(@.type == 'application/json')].rel")); // and the alternates - assertEquals("alternate", readSingle(json, "links[?(@.type == 'application/x-yaml')].rel")); + assertEquals("alternate", readSingle(json, "links[?(@.type == 'application/yaml')].rel")); // check all the styles are there assertThat( diff --git a/src/community/ogcapi/ogcapi-tiled-features/pom.xml b/src/community/ogcapi/ogcapi-tiled-features/pom.xml index 3130c16acf6..9f8e2dedf44 100644 --- a/src/community/ogcapi/ogcapi-tiled-features/pom.xml +++ b/src/community/ogcapi/ogcapi-tiled-features/pom.xml @@ -55,7 +55,6 @@ org.geotools gt-jdbc - ${gt.version} test-jar test diff --git a/src/community/ogcapi/ogcapi-tiled-features/src/test/java/org/geoserver/ogcapi/v1/features/tiled/TilesetDescriptionTest.java b/src/community/ogcapi/ogcapi-tiled-features/src/test/java/org/geoserver/ogcapi/v1/features/tiled/TilesetDescriptionTest.java index 07e2ec8e6f0..09009a56f16 100644 --- a/src/community/ogcapi/ogcapi-tiled-features/src/test/java/org/geoserver/ogcapi/v1/features/tiled/TilesetDescriptionTest.java +++ b/src/community/ogcapi/ogcapi-tiled-features/src/test/java/org/geoserver/ogcapi/v1/features/tiled/TilesetDescriptionTest.java @@ -31,7 +31,7 @@ public void testGetTileMatrixSets() throws Exception { assertThat( json.read( "links[?(@.type != 'application/json' && @.href =~ /.*ogc\\/features\\/v1\\/tileMatrixSets\\?.*/ && @.rel == 'alternate')].type"), - hasItems("application/x-yaml")); + hasItems("application/yaml")); // check some of the basic tile matrix sets are there assertThat( @@ -69,7 +69,7 @@ public void testGetTileMatrixSet() throws Exception { assertThat( json.read( "links[?(@.type != 'application/json' && @.href =~ /.*ogc\\/features\\/v1\\/tileMatrixSets\\/EPSG%3A4326\\?.*/ && @.rel == 'alternate')].type"), - hasItems("application/x-yaml")); + hasItems("application/yaml")); // check basic properties assertThat(json.read("id"), equalTo("EPSG:4326")); @@ -113,7 +113,7 @@ public void getDataTilesMetadata() throws Exception { assertThat( json.read( "links[?(@.type != 'application/json' && @.href =~ /.*ogc\\/features\\/v1\\/collections\\/cite:RoadSegments\\/tiles\\/EPSG:4326\\?.*/ && @.rel == 'alternate')].type"), - hasItems("application/x-yaml")); + hasItems("application/yaml")); // test the describedBy template assertEquals( diff --git a/src/community/ogcapi/ogcapi-tiled-features/src/test/java/org/geoserver/ogcapi/v1/features/tiled/TilesetsDescriptionTest.java b/src/community/ogcapi/ogcapi-tiled-features/src/test/java/org/geoserver/ogcapi/v1/features/tiled/TilesetsDescriptionTest.java index 36aaf2e8298..4effdfabaa9 100644 --- a/src/community/ogcapi/ogcapi-tiled-features/src/test/java/org/geoserver/ogcapi/v1/features/tiled/TilesetsDescriptionTest.java +++ b/src/community/ogcapi/ogcapi-tiled-features/src/test/java/org/geoserver/ogcapi/v1/features/tiled/TilesetsDescriptionTest.java @@ -28,7 +28,7 @@ public void testGetTileMatrixSets() throws Exception { assertThat( json.read( "links[?(@.type != 'application/json' && @.href =~ /.*ogc\\/features\\/v1\\/tileMatrixSets\\?.*/ && @.rel == 'alternate')].type"), - hasItems("application/x-yaml")); + hasItems("application/yaml")); // check some of the basic tile matrix sets are there assertThat( @@ -66,7 +66,7 @@ public void testGetTileMatrixSet() throws Exception { assertThat( json.read( "links[?(@.type != 'application/json' && @.href =~ /.*ogc\\/features\\/v1\\/tileMatrixSets\\/EPSG%3A4326\\?.*/ && @.rel == 'alternate')].type"), - hasItems("application/x-yaml")); + hasItems("application/yaml")); // check basic properties assertThat(json.read("id"), equalTo("EPSG:4326")); @@ -102,7 +102,7 @@ public void getDataTilesMetadata() throws Exception { assertThat( json.read( "links[?(@.type != 'application/json' && @.href =~ /.*ogc\\/features\\/v1\\/collections\\/cite:RoadSegments\\/tiles\\?.*/ && @.rel == 'alternate')].type"), - hasItems("application/x-yaml")); + hasItems("application/yaml")); // check the tile matrices assertEquals(Integer.valueOf(2), json.read("$.tilesets.size()")); diff --git a/src/community/ogcapi/ogcapi-tiles/pom.xml b/src/community/ogcapi/ogcapi-tiles/pom.xml index 4729b4eb50d..b1b23a26817 100644 --- a/src/community/ogcapi/ogcapi-tiles/pom.xml +++ b/src/community/ogcapi/ogcapi-tiles/pom.xml @@ -73,7 +73,6 @@ org.geotools gt-jdbc - ${gt.version} test-jar test diff --git a/src/community/ogcapi/ogcapi-tiles/src/main/java/org/geoserver/ogcapi/v1/tiles/TiledCollectionsDocument.java b/src/community/ogcapi/ogcapi-tiles/src/main/java/org/geoserver/ogcapi/v1/tiles/TiledCollectionsDocument.java index c2d30fd47c3..6ff58aae583 100644 --- a/src/community/ogcapi/ogcapi-tiles/src/main/java/org/geoserver/ogcapi/v1/tiles/TiledCollectionsDocument.java +++ b/src/community/ogcapi/ogcapi-tiles/src/main/java/org/geoserver/ogcapi/v1/tiles/TiledCollectionsDocument.java @@ -53,7 +53,7 @@ public Iterator getCollections() { boolean skipInvalid = gs.getGlobal().getResourceErrorHandling() == ResourceErrorHandling.SKIP_MISCONFIGURED_LAYERS; - return new Iterator() { + return new Iterator<>() { TiledCollectionDocument next; diff --git a/src/community/ogcapi/ogcapi-tiles/src/main/java/org/geoserver/ogcapi/v1/tiles/TilesService.java b/src/community/ogcapi/ogcapi-tiles/src/main/java/org/geoserver/ogcapi/v1/tiles/TilesService.java index c9964a23115..4a4bf6c9f58 100644 --- a/src/community/ogcapi/ogcapi-tiles/src/main/java/org/geoserver/ogcapi/v1/tiles/TilesService.java +++ b/src/community/ogcapi/ogcapi-tiles/src/main/java/org/geoserver/ogcapi/v1/tiles/TilesService.java @@ -12,7 +12,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.channels.Channels; -import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.HashMap; @@ -516,7 +515,6 @@ private String getETag(byte[] tileBytes) throws NoSuchAlgorithmException { if (tileBytes == null) { return "EMPTY_TILE"; } - final byte[] hash = MessageDigest.getInstance("MD5").digest(tileBytes); return GWC.getETag(tileBytes); } diff --git a/src/community/ogcapi/ogcapi-tiles/src/main/java/org/geoserver/ogcapi/v1/tiles/VolatileGeoServerTileLayer.java b/src/community/ogcapi/ogcapi-tiles/src/main/java/org/geoserver/ogcapi/v1/tiles/VolatileGeoServerTileLayer.java index c153ac7562c..44abdfa51a1 100644 --- a/src/community/ogcapi/ogcapi-tiles/src/main/java/org/geoserver/ogcapi/v1/tiles/VolatileGeoServerTileLayer.java +++ b/src/community/ogcapi/ogcapi-tiles/src/main/java/org/geoserver/ogcapi/v1/tiles/VolatileGeoServerTileLayer.java @@ -29,11 +29,11 @@ public VolatileGeoServerTileLayer(GeoServerTileLayer layer) { } @Override - protected ConveyorTile getMetatilingReponse( + protected ConveyorTile getMetatilingResponse( ConveyorTile tile, boolean tryCache, int metaX, int metaY) throws GeoWebCacheException, IOException { // forces meta tiling factors to 1x1 and disables cache usage - return super.getMetatilingReponse(tile, false, 1, 1); + return super.getMetatilingResponse(tile, false, 1, 1); } @Override diff --git a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/ApiTest.java b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/ApiTest.java index 62bc594b5bb..5d1d508f084 100644 --- a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/ApiTest.java +++ b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/ApiTest.java @@ -91,7 +91,7 @@ public void testApiHTML() throws Exception { @Test public void testApiYaml() throws Exception { - String yaml = getAsString("ogc/tiles/v1/openapi?f=application/x-yaml"); + String yaml = getAsString("ogc/tiles/v1/openapi?f=application/yaml"); LOGGER.log(Level.INFO, yaml); ObjectMapper mapper = Yaml.mapper(); @@ -104,10 +104,10 @@ public void testYamlAsAcceptsHeader() throws Exception { MockHttpServletRequest request = createRequest("ogc/tiles/v1/openapi"); request.setMethod("GET"); request.setContent(new byte[] {}); - request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/x-yaml, text/html"); + request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/yaml, text/html"); MockHttpServletResponse response = dispatch(request); assertEquals(200, response.getStatus()); - assertThat(response.getContentType(), CoreMatchers.startsWith("application/x-yaml")); + assertThat(response.getContentType(), CoreMatchers.startsWith("application/yaml")); String yaml = string(new ByteArrayInputStream(response.getContentAsString().getBytes())); ObjectMapper mapper = Yaml.mapper(); @@ -163,10 +163,10 @@ public void testWorkspaceQualifiedAPI() throws Exception { MockHttpServletRequest request = createRequest("cdf/ogc/tiles/v1/openapi"); request.setMethod("GET"); request.setContent(new byte[] {}); - request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/x-yaml, text/html"); + request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/yaml, text/html"); MockHttpServletResponse response = dispatch(request); assertEquals(200, response.getStatus()); - assertEquals("application/x-yaml", response.getContentType()); + assertEquals("application/yaml", response.getContentType()); String yaml = string(new ByteArrayInputStream(response.getContentAsString().getBytes())); ObjectMapper mapper = Yaml.mapper(); diff --git a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/CollectionTest.java b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/CollectionTest.java index b43e86206cb..763e6a309f8 100644 --- a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/CollectionTest.java +++ b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/CollectionTest.java @@ -119,7 +119,7 @@ public void testRoadsCollectionYaml() throws Exception { getAsString( "ogc/tiles/v1/collections/" + getLayerId(MockData.ROAD_SEGMENTS) - + "?f=application/x-yaml"); + + "?f=application/yaml"); DocumentContext json = convertYamlToJsonPath(yaml); testRoadsCollectionJson(json); } diff --git a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/CollectionsTest.java b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/CollectionsTest.java index cb3a754e5c3..7493fdfe1a7 100644 --- a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/CollectionsTest.java +++ b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/CollectionsTest.java @@ -107,9 +107,9 @@ public void testCollectionsXML() throws Exception { @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/tiles/v1/collections/?f=application/x-yaml"); + String yaml = getAsString("ogc/tiles/v1/collections/?f=application/yaml"); DocumentContext json = convertYamlToJsonPath(yaml); - testCollectionsJson(json, MediaType.parseMediaType("application/x-yaml")); + testCollectionsJson(json, MediaType.parseMediaType("application/yaml")); } @Test @@ -141,7 +141,7 @@ public void testCollectionsHTML() throws Exception { @Test public void testVersionHeader() throws Exception { MockHttpServletResponse response = - getAsServletResponse("ogc/tiles/v1/collections/?f=application/x-yaml"); + getAsServletResponse("ogc/tiles/v1/collections/?f=application/yaml"); assertTrue(headerHasValue(response, "API-Version", "1.0.0")); } } diff --git a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/ConformanceTest.java b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/ConformanceTest.java index 71362fd6776..6d15c2af63f 100644 --- a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/ConformanceTest.java +++ b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/ConformanceTest.java @@ -37,7 +37,7 @@ private void checkConformance(DocumentContext json) { @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/tiles/v1/conformance/?f=application/x-yaml"); + String yaml = getAsString("ogc/tiles/v1/conformance/?f=application/yaml"); checkConformance(convertYamlToJsonPath(yaml)); } diff --git a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/LandingPageTest.java b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/LandingPageTest.java index dd06eb7e597..4a19e1a6e49 100644 --- a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/LandingPageTest.java +++ b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/LandingPageTest.java @@ -84,16 +84,16 @@ public void testLandingPageXML() throws Exception { @Test public void testLandingPageYaml() throws Exception { - String yaml = getAsString("ogc/tiles/v1?f=application/x-yaml"); + String yaml = getAsString("ogc/tiles/v1?f=application/yaml"); // System.out.println(yaml); DocumentContext json = convertYamlToJsonPath(yaml); assertJSONList( json, - "links[?(@.type == 'application/x-yaml' && @.href =~ /.*ogc\\/tiles\\/v1\\/\\?.*/)].rel", + "links[?(@.type == 'application/yaml' && @.href =~ /.*ogc\\/tiles\\/v1\\/\\?.*/)].rel", "self"); assertJSONList( json, - "links[?(@.type != 'application/x-yaml' && @.href =~ /.*ogc\\/tiles\\/v1\\/\\?.*/)].rel", + "links[?(@.type != 'application/yaml' && @.href =~ /.*ogc\\/tiles\\/v1\\/\\?.*/)].rel", "alternate", "alternate"); checkJSONLandingPageShared(json); diff --git a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/QueryablesTest.java b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/QueryablesTest.java index ab6d597e306..c86c1908fee 100644 --- a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/QueryablesTest.java +++ b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/QueryablesTest.java @@ -35,14 +35,12 @@ public void queryablesOnGroup() throws Exception { } @Test - public void queryablesOnRoadSegements() throws Exception { + public void queryablesOnRoadSegments() throws Exception { DocumentContext json = getAsJSONPath( "ogc/tiles/v1/collections/" + getLayerId(ROAD_SEGMENTS) + "/queryables", 200); - assertEquals( - "https://geojson.org/schema/MultiLineString.json", - json.read("properties.the_geom.$ref")); + assertEquals("geometry-multilinestring", json.read("properties.the_geom.format")); assertEquals("string", json.read("properties.FID.type")); assertEquals("string", json.read("properties.NAME.type")); } diff --git a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/TilesetDescriptionTest.java b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/TilesetDescriptionTest.java index a60dafe5812..4cc2694226c 100644 --- a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/TilesetDescriptionTest.java +++ b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/TilesetDescriptionTest.java @@ -48,7 +48,7 @@ public void getDataTilesMetadata() throws Exception { assertThat( json.read( "links[?(@.type != 'application/json' && @.href =~ /.*ogc\\/tiles\\/v1\\/collections\\/cite:RoadSegments\\/tiles\\/EPSG:4326\\?.*/ && @.rel == 'alternate')].type"), - hasItems("application/x-yaml")); + hasItems("application/yaml")); // test the describedBy template assertEquals( diff --git a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/TilesetsDescriptionTest.java b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/TilesetsDescriptionTest.java index d5ba0fac7c8..678205ddb7a 100644 --- a/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/TilesetsDescriptionTest.java +++ b/src/community/ogcapi/ogcapi-tiles/src/test/java/org/geoserver/ogcapi/v1/tiles/TilesetsDescriptionTest.java @@ -30,7 +30,7 @@ public void testGetTileMatrixSets() throws Exception { assertThat( json.read( "links[?(@.type != 'application/json' && @.href =~ /.*ogc\\/tiles\\/v1\\/tileMatrixSets\\?.*/ && @.rel == 'alternate')].type"), - hasItems("application/x-yaml")); + hasItems("application/yaml")); // check some of the basic tile matrix sets are there assertThat( @@ -68,7 +68,7 @@ public void testGetTileMatrixSet() throws Exception { assertThat( json.read( "links[?(@.type != 'application/json' && @.href =~ /.*ogc\\/tiles\\/v1\\/tileMatrixSets\\/EPSG%3A4326\\?.*/ && @.rel == 'alternate')].type"), - hasItems("application/x-yaml")); + hasItems("application/yaml")); // check basic properties assertThat(json.read("id"), equalTo("EPSG:4326")); @@ -113,7 +113,7 @@ public void getDataTilesMetadata() throws Exception { assertThat( json.read( "links[?(@.type != 'application/json' && @.href =~ /.*ogc\\/tiles\\/v1\\/collections\\/cite:RoadSegments\\/tiles\\?.*/ && @.rel == 'alternate')].type"), - hasItems("application/x-yaml")); + hasItems("application/yaml")); // // test the describedBy template // assertEquals( diff --git a/src/community/ogcapi/web-coverages/pom.xml b/src/community/ogcapi/web-coverages/pom.xml index bbe1903cd80..a254873fcff 100644 --- a/src/community/ogcapi/web-coverages/pom.xml +++ b/src/community/ogcapi/web-coverages/pom.xml @@ -32,6 +32,12 @@ compile + + org.junit.jupiter + junit-jupiter + test + + diff --git a/src/community/ogcapi/web-features/pom.xml b/src/community/ogcapi/web-features/pom.xml index 3bf7d642d3b..1f978cfbcb2 100644 --- a/src/community/ogcapi/web-features/pom.xml +++ b/src/community/ogcapi/web-features/pom.xml @@ -33,6 +33,12 @@ compile + + org.junit.jupiter + junit-jupiter + test + + diff --git a/src/community/ogcapi/web-images/pom.xml b/src/community/ogcapi/web-images/pom.xml index 4093ff219b0..f57169edc7b 100644 --- a/src/community/ogcapi/web-images/pom.xml +++ b/src/community/ogcapi/web-images/pom.xml @@ -33,6 +33,12 @@ compile + + org.junit.jupiter + junit-jupiter + test + + diff --git a/src/community/ogcapi/web-maps/pom.xml b/src/community/ogcapi/web-maps/pom.xml index 55dc7a38cb6..19e53084eb3 100644 --- a/src/community/ogcapi/web-maps/pom.xml +++ b/src/community/ogcapi/web-maps/pom.xml @@ -33,6 +33,12 @@ compile + + org.junit.jupiter + junit-jupiter + test + + diff --git a/src/community/ogcapi/web-ogcapi/pom.xml b/src/community/ogcapi/web-ogcapi/pom.xml index 640bd3d0539..294bf404e73 100644 --- a/src/community/ogcapi/web-ogcapi/pom.xml +++ b/src/community/ogcapi/web-ogcapi/pom.xml @@ -42,6 +42,11 @@ ${project.version} test + + org.junit.jupiter + junit-jupiter + test + diff --git a/src/community/ogcapi/web-ogcapi/src/main/java/org/geoserver/web/ogcapi/OgcApiServiceDescriptionProvider.java b/src/community/ogcapi/web-ogcapi/src/main/java/org/geoserver/web/ogcapi/OgcApiServiceDescriptionProvider.java index 8da29764048..bdb0d7b1d8a 100644 --- a/src/community/ogcapi/web-ogcapi/src/main/java/org/geoserver/web/ogcapi/OgcApiServiceDescriptionProvider.java +++ b/src/community/ogcapi/web-ogcapi/src/main/java/org/geoserver/web/ogcapi/OgcApiServiceDescriptionProvider.java @@ -88,10 +88,10 @@ public OgcApiServiceDescriptionProvider( protected SERVICEINFOTYPE info(WorkspaceInfo workspaceInfo, PublishedInfo layerInfo) { SERVICEINFOTYPE info = null; if (workspaceInfo != null) { - info = (SERVICEINFOTYPE) geoserver.getService(workspaceInfo, infoClass); + info = geoserver.getService(workspaceInfo, infoClass); } if (info == null) { - info = (SERVICEINFOTYPE) geoserver.getService(infoClass); + info = geoserver.getService(infoClass); } return info; } diff --git a/src/community/ogcapi/web-ogcapi/src/test/java/org/geoserver/web/ogcapi/provider/TestCaseInfoXStreamLoader.java b/src/community/ogcapi/web-ogcapi/src/test/java/org/geoserver/web/ogcapi/provider/TestCaseInfoXStreamLoader.java index 418746811a4..a442afd3177 100644 --- a/src/community/ogcapi/web-ogcapi/src/test/java/org/geoserver/web/ogcapi/provider/TestCaseInfoXStreamLoader.java +++ b/src/community/ogcapi/web-ogcapi/src/test/java/org/geoserver/web/ogcapi/provider/TestCaseInfoXStreamLoader.java @@ -36,7 +36,7 @@ public static void initXStreamPersister(XStreamPersister xp) { protected TestCaseInfo createServiceFromScratch(GeoServer gs) { TestCaseInfoImpl testCaseInfo = new TestCaseInfoImpl(); testCaseInfo.setName("tc"); - return (TestCaseInfo) testCaseInfo; + return testCaseInfo; } @Override diff --git a/src/community/ogcapi/web-styles/pom.xml b/src/community/ogcapi/web-styles/pom.xml index bb1c0047c99..19526ac38e4 100644 --- a/src/community/ogcapi/web-styles/pom.xml +++ b/src/community/ogcapi/web-styles/pom.xml @@ -33,6 +33,11 @@ compile + + org.junit.jupiter + junit-jupiter + test + diff --git a/src/community/ogcapi/web-tiles/pom.xml b/src/community/ogcapi/web-tiles/pom.xml index 80f5ced01e8..7ac76564bdc 100644 --- a/src/community/ogcapi/web-tiles/pom.xml +++ b/src/community/ogcapi/web-tiles/pom.xml @@ -33,6 +33,11 @@ compile + + org.junit.jupiter + junit-jupiter + test + diff --git a/src/community/oseo/oseo-core/pom.xml b/src/community/oseo/oseo-core/pom.xml index a514498ef30..983bf6da3c0 100644 --- a/src/community/oseo/oseo-core/pom.xml +++ b/src/community/oseo/oseo-core/pom.xml @@ -39,7 +39,6 @@ org.geotools gt-jdbc - ${gt.version} org.apache.commons @@ -62,7 +61,6 @@ org.geotools.jdbc gt-jdbc-h2 - ${gt.version} test diff --git a/src/community/oseo/oseo-rest/pom.xml b/src/community/oseo/oseo-rest/pom.xml index d159153569c..edd2345221c 100644 --- a/src/community/oseo/oseo-rest/pom.xml +++ b/src/community/oseo/oseo-rest/pom.xml @@ -33,12 +33,10 @@ org.geotools gt-geojson-core - ${gt.version} org.geotools gt-brewer - ${gt.version} com.fasterxml.jackson.core @@ -80,7 +78,6 @@ org.geotools.jdbc gt-jdbc-h2 - ${gt.version} test diff --git a/src/community/oseo/oseo-service/pom.xml b/src/community/oseo/oseo-service/pom.xml index 73cb3964289..702eb1f4c3b 100644 --- a/src/community/oseo/oseo-service/pom.xml +++ b/src/community/oseo/oseo-service/pom.xml @@ -81,7 +81,6 @@ org.geotools.jdbc gt-jdbc-h2 - ${gt.version} test diff --git a/src/community/oseo/oseo-stac/src/main/java/org/geoserver/ogcapi/v1/stac/STACQueryablesBuilder.java b/src/community/oseo/oseo-stac/src/main/java/org/geoserver/ogcapi/v1/stac/STACQueryablesBuilder.java index a16eb8a504a..8e02c39e6e3 100644 --- a/src/community/oseo/oseo-stac/src/main/java/org/geoserver/ogcapi/v1/stac/STACQueryablesBuilder.java +++ b/src/community/oseo/oseo-stac/src/main/java/org/geoserver/ogcapi/v1/stac/STACQueryablesBuilder.java @@ -200,10 +200,11 @@ Map getExpressionMap() { return expressions; } - private Schema getSchema(String description, String ref) { + private Schema getSchema(String title, String ref) { Schema schema = new Schema(); schema.set$ref(ref); - schema.setDescription(description); + schema.setTitle(title); + schema.setDescription(title); return schema; } diff --git a/src/community/oseo/oseo-stac/src/main/resources/org/geoserver/ogcapi/v1/stac/queryables-common.ftl b/src/community/oseo/oseo-stac/src/main/resources/org/geoserver/ogcapi/v1/stac/queryables-common.ftl index 143dd778642..0c08754fc7c 100644 --- a/src/community/oseo/oseo-stac/src/main/resources/org/geoserver/ogcapi/v1/stac/queryables-common.ftl +++ b/src/community/oseo/oseo-stac/src/main/resources/org/geoserver/ogcapi/v1/stac/queryables-common.ftl @@ -2,7 +2,7 @@ <#if model.getProperties()??>
      <#list model.getProperties() as name, definition> -
    • ${name}: ${definition.getDescription()}
    • +
    • ${name}: ${definition.getTitle()}
    <#else> diff --git a/src/community/oseo/oseo-stac/src/main/resources/org/geoserver/ogcapi/v1/stac/sortables-common.ftl b/src/community/oseo/oseo-stac/src/main/resources/org/geoserver/ogcapi/v1/stac/sortables-common.ftl index ddf2865a408..c73816e7791 100644 --- a/src/community/oseo/oseo-stac/src/main/resources/org/geoserver/ogcapi/v1/stac/sortables-common.ftl +++ b/src/community/oseo/oseo-stac/src/main/resources/org/geoserver/ogcapi/v1/stac/sortables-common.ftl @@ -2,7 +2,7 @@ <#if model.getProperties()??>
      <#list model.getProperties() as name, definition> -
    • ${name}: ${definition.getDescription()}
    • +
    • ${name}: ${definition.getTitle()}
    <#else> diff --git a/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/ApiTest.java b/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/ApiTest.java index 61bb3d77013..245f89cd15b 100644 --- a/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/ApiTest.java +++ b/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/ApiTest.java @@ -82,12 +82,12 @@ public void testApiHTML() throws Exception { assertThat( html, containsString( - "url: \"http://localhost:8080/geoserver/ogc/stac/v1/openapi?f=application%2Fvnd.oai.openapi%2Bjson%3Bversion%3D3.0")); + "value=\"http://localhost:8080/geoserver/ogc/stac/v1/openapi?f=application%2Fvnd.oai.openapi%2Bjson%3Bversion%3D3.0")); } @Test public void testApiYaml() throws Exception { - String yaml = getAsString("ogc/stac/v1/openapi?f=application/x-yaml"); + String yaml = getAsString("ogc/stac/v1/openapi?f=application/yaml"); LOGGER.log(Level.INFO, yaml); ObjectMapper mapper = Yaml.mapper(); @@ -100,10 +100,10 @@ public void testYamlAsAcceptsHeader() throws Exception { MockHttpServletRequest request = createRequest("ogc/stac/v1/openapi"); request.setMethod("GET"); request.setContent(new byte[] {}); - request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/x-yaml, text/html"); + request.addHeader(HttpHeaders.ACCEPT, "foo/bar, application/yaml, text/html"); MockHttpServletResponse response = dispatch(request); assertEquals(200, response.getStatus()); - assertThat(response.getContentType(), CoreMatchers.startsWith("application/x-yaml")); + assertThat(response.getContentType(), CoreMatchers.startsWith("application/yaml")); String yaml = string(new ByteArrayInputStream(response.getContentAsString().getBytes())); ObjectMapper mapper = Yaml.mapper(); diff --git a/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/ConformanceTest.java b/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/ConformanceTest.java index 1b839374e6d..0534aa3cd43 100644 --- a/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/ConformanceTest.java +++ b/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/ConformanceTest.java @@ -67,7 +67,7 @@ private static String[] getExpectedConformanceClasses() { @Test public void testCollectionsYaml() throws Exception { - String yaml = getAsString("ogc/stac/v1/conformance/?f=application/x-yaml"); + String yaml = getAsString("ogc/stac/v1/conformance/?f=application/yaml"); checkConformance(convertYamlToJsonPath(yaml)); } diff --git a/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/LandingPageTest.java b/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/LandingPageTest.java index 8f4f5341838..ff6a13ed33e 100644 --- a/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/LandingPageTest.java +++ b/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/LandingPageTest.java @@ -74,16 +74,16 @@ public void testLandingPageJSON() throws Exception { @Test public void testLandingPageYaml() throws Exception { - String yaml = getAsString("ogc/stac/v1?f=application/x-yaml"); + String yaml = getAsString("ogc/stac/v1?f=application/yaml"); // System.out.println(yaml); DocumentContext json = convertYamlToJsonPath(yaml); assertJSONList( json, - "links[?(@.type == 'application/x-yaml' && @.href =~ /.*ogc\\/stac\\/v1\\/\\?.*/)].rel", + "links[?(@.type == 'application/yaml' && @.href =~ /.*ogc\\/stac\\/v1\\/\\?.*/)].rel", "self"); assertJSONList( json, - "links[?(@.type != 'application/x-yaml' && @.href =~ /.*ogc\\/stac\\/v1\\/\\?.*/)].rel", + "links[?(@.type != 'application/yaml' && @.href =~ /.*ogc\\/stac\\/v1\\/\\?.*/)].rel", "alternate", "alternate"); checkJSONLandingPageShared(json); diff --git a/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/QueryablesTest.java b/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/QueryablesTest.java index 920e7ac4591..7c67cbf066a 100644 --- a/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/QueryablesTest.java +++ b/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/QueryablesTest.java @@ -56,12 +56,12 @@ public void testCollectionQueryables() throws Exception { // custom one that is there instead DocumentContext cc = readContext(properties, "eo:cloud_cover"); assertEquals("integer", cc.read("type")); - assertEquals("integer", cc.read("description")); + assertEquals("integer", cc.read("title")); // top level queryable DocumentContext kw = readContext(properties, "keywords"); assertEquals("string", kw.read("type")); - assertEquals("string", kw.read("description")); + assertEquals("string", kw.read("title")); } /** @@ -94,16 +94,16 @@ public void testCollectionQueryablesWithGlobals() throws Exception { // custom one that is there instead DocumentContext cc = readContext(properties, "eo:cloud_cover"); assertEquals("integer", cc.read("type")); - assertEquals("integer", cc.read("description")); + assertEquals("integer", cc.read("title")); // check the custom global queryables as well DocumentContext constellation = readContext(json, "properties.constellation"); assertEquals("string", constellation.read("type")); - assertEquals("string", constellation.read("description")); + assertEquals("string", constellation.read("title")); DocumentContext sun_azimuth = readContext(json, "properties.view:sun_azimuth"); assertEquals("number", sun_azimuth.read("type")); - assertEquals("number", sun_azimuth.read("description")); + assertEquals("number", sun_azimuth.read("title")); } finally { oseo.getGlobalQueryables().clear(); gs.save(oseo); @@ -142,7 +142,7 @@ public void testLandsat8Queryables() throws Exception { // check the one custom queryable added in LANDSAT8 template DocumentContext orbit = readContext(json, "properties.landsat:orbit"); assertEquals("integer", orbit.read("type")); - assertEquals("integer", orbit.read("description")); + assertEquals("integer", orbit.read("title")); } @Test @@ -159,11 +159,11 @@ public void testCustomGlobalQueryables() throws Exception { // check the custom queryables added above DocumentContext constellation = readContext(json, "properties.constellation"); assertEquals("string", constellation.read("type")); - assertEquals("string", constellation.read("description")); + assertEquals("string", constellation.read("title")); DocumentContext sun_azimuth = readContext(json, "properties.view:sun_azimuth"); assertEquals("number", sun_azimuth.read("type")); - assertEquals("number", sun_azimuth.read("description")); + assertEquals("number", sun_azimuth.read("title")); } finally { oseo.getGlobalQueryables().clear(); gs.save(oseo); @@ -184,11 +184,11 @@ public void testCustomCollectionQueryables() throws Exception { // check the custom queryables added above DocumentContext constellation = readContext(json, "properties.constellation"); assertEquals("string", constellation.read("type")); - assertEquals("string", constellation.read("description")); + assertEquals("string", constellation.read("title")); DocumentContext sun_azimuth = readContext(json, "properties.view:sun_azimuth"); assertEquals("number", sun_azimuth.read("type")); - assertEquals("number", sun_azimuth.read("description")); + assertEquals("number", sun_azimuth.read("title")); } finally { oseo.getGlobalQueryables().clear(); gs.save(oseo); diff --git a/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/SortablesTest.java b/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/SortablesTest.java index a9fa10ccee6..ac22e7c542a 100644 --- a/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/SortablesTest.java +++ b/src/community/oseo/oseo-stac/src/test/java/org/geoserver/ogcapi/v1/stac/SortablesTest.java @@ -72,7 +72,7 @@ public void testLandsat8Sortables() throws Exception { // check the one custom sortables added in LANDSAT8 template DocumentContext orbit = readContext(json, "properties.landsat:orbit"); assertEquals("integer", orbit.read("type")); - assertEquals("integer", orbit.read("description")); + assertEquals("integer", orbit.read("title")); } private void checkSortableProperties(DocumentContext json) { diff --git a/src/community/oseo/web-oseo/pom.xml b/src/community/oseo/web-oseo/pom.xml index a8a8b95d7a1..6d8c3b5641e 100644 --- a/src/community/oseo/web-oseo/pom.xml +++ b/src/community/oseo/web-oseo/pom.xml @@ -61,7 +61,6 @@ org.geotools.jdbc gt-jdbc-h2 - ${gt.version} test diff --git a/src/community/pom.xml b/src/community/pom.xml index 666768753aa..700d4424df2 100644 --- a/src/community/pom.xml +++ b/src/community/pom.xml @@ -496,6 +496,15 @@ ogcapi + + ogcapi-features + + ogcapi/ogcapi-core + ogcapi/ogcapi-features + ogcapi/web-ogcapi + ogcapi/web-features + + importer-jdbc diff --git a/src/community/s3-geotiff/pom.xml b/src/community/s3-geotiff/pom.xml index a1fb8ec7acd..8e98fd0f8d2 100644 --- a/src/community/s3-geotiff/pom.xml +++ b/src/community/s3-geotiff/pom.xml @@ -15,7 +15,6 @@ org.geotools gt-s3-geotiff - ${gt.version} org.geoserver.web diff --git a/src/community/schemaless-features/mongodb-schemaless/pom.xml b/src/community/schemaless-features/mongodb-schemaless/pom.xml index 9a753766a59..452fcf6e1a6 100644 --- a/src/community/schemaless-features/mongodb-schemaless/pom.xml +++ b/src/community/schemaless-features/mongodb-schemaless/pom.xml @@ -24,7 +24,6 @@ org.geotools gt-mongodb - ${gt.version} @@ -49,13 +48,11 @@ org.geotools gt-sample-data - ${gt.version} test org.geotools gt-referencing - ${gt.version} org.geoserver diff --git a/src/community/schemaless-features/schemaless-core/pom.xml b/src/community/schemaless-features/schemaless-core/pom.xml index 4926662fb1f..264b3a62815 100644 --- a/src/community/schemaless-features/schemaless-core/pom.xml +++ b/src/community/schemaless-features/schemaless-core/pom.xml @@ -18,7 +18,6 @@ org.geotools gt-main - ${gt.version} org.geoserver @@ -36,7 +35,6 @@ org.geotools gt-sample-data - ${gt.version} test diff --git a/src/community/smart-data-loader/pom.xml b/src/community/smart-data-loader/pom.xml index 4ae3b53e304..5d53ae96d21 100644 --- a/src/community/smart-data-loader/pom.xml +++ b/src/community/smart-data-loader/pom.xml @@ -35,7 +35,6 @@ org.geotools gt-app-schema - ${gt.version} org.geoserver.extension @@ -58,27 +57,23 @@ org.geotools gt-app-schema - ${gt.version} tests test org.geotools gt-sample-data - ${gt.version} test org.geotools gt-jdbc - ${gt.version} test-jar test org.geotools.jdbc gt-jdbc-postgis - ${gt.version} org.geoserver.web diff --git a/src/community/solr/pom.xml b/src/community/solr/pom.xml index 16416aacb3a..f8625507427 100644 --- a/src/community/solr/pom.xml +++ b/src/community/solr/pom.xml @@ -29,7 +29,6 @@ org.geotools gt-solr - ${gt.version} org.geoserver.web diff --git a/src/community/stac-datastore/pom.xml b/src/community/stac-datastore/pom.xml index f2e5ca87b5a..d1c461d4202 100644 --- a/src/community/stac-datastore/pom.xml +++ b/src/community/stac-datastore/pom.xml @@ -24,7 +24,6 @@ org.geotools gt-stac-store - ${gt.version} diff --git a/src/community/stac-datastore/src/assembly/assembly.xml b/src/community/stac-datastore/src/assembly/assembly.xml index dd26eb46461..295482db260 100644 --- a/src/community/stac-datastore/src/assembly/assembly.xml +++ b/src/community/stac-datastore/src/assembly/assembly.xml @@ -10,8 +10,7 @@ gt-stac-store*.jar - gt-cql2-text-*.jar - gt-cql-json-*.jar + gt-cql2-*.jar diff --git a/src/community/taskmanager/core/bin/pom.xml b/src/community/taskmanager/core/bin/pom.xml index 11caab4305d..a55b3f88f8a 100644 --- a/src/community/taskmanager/core/bin/pom.xml +++ b/src/community/taskmanager/core/bin/pom.xml @@ -66,13 +66,11 @@ org.apache.logging.log4j - log4j-slf4j-impl - ${log4j.version} + log4j-slf4j2-impl org.apache.logging.log4j log4j-jcl - ${log4j.version} diff --git a/src/community/taskmanager/core/pom.xml b/src/community/taskmanager/core/pom.xml index 15d10c65328..f3c6818455a 100644 --- a/src/community/taskmanager/core/pom.xml +++ b/src/community/taskmanager/core/pom.xml @@ -75,8 +75,7 @@ org.apache.logging.log4j - log4j-slf4j-impl - ${log4j.version} + log4j-slf4j2-impl org.geotools.jdbc @@ -127,7 +126,6 @@ org.geotools gt-app-schema - ${gt.version} test diff --git a/src/community/taskmanager/s3/pom.xml b/src/community/taskmanager/s3/pom.xml index 934bca9b528..f779ccefdf3 100644 --- a/src/community/taskmanager/s3/pom.xml +++ b/src/community/taskmanager/s3/pom.xml @@ -46,7 +46,6 @@ org.geotools gt-s3-geotiff - ${gt.version} test diff --git a/src/community/vector-mosaic/pom.xml b/src/community/vector-mosaic/pom.xml index 8497b0e381b..d76293a600e 100644 --- a/src/community/vector-mosaic/pom.xml +++ b/src/community/vector-mosaic/pom.xml @@ -22,7 +22,6 @@ org.geotools gt-vector-mosaic - ${gt.version} org.geoserver.web diff --git a/src/community/vsi/pom.xml b/src/community/vsi/pom.xml index 4ddee0a4b4e..7a75a84d995 100644 --- a/src/community/vsi/pom.xml +++ b/src/community/vsi/pom.xml @@ -15,7 +15,6 @@ org.geotools gt-vsi - ${gt.version} org.geoserver.web diff --git a/src/community/web-ogr/pom.xml b/src/community/web-ogr/pom.xml index 1b8fbe08250..9dac50be8fd 100644 --- a/src/community/web-ogr/pom.xml +++ b/src/community/web-ogr/pom.xml @@ -20,7 +20,6 @@ org.geotools gt-ogr-jni - ${gt.version} org.geoserver diff --git a/src/community/wps-sextante/pom.xml b/src/community/wps-sextante/pom.xml index d90bd5adc92..7e8ced3b71c 100644 --- a/src/community/wps-sextante/pom.xml +++ b/src/community/wps-sextante/pom.xml @@ -38,7 +38,6 @@ org.geotools gt-process - ${gt.version} org.geoserver diff --git a/src/extension/app-schema/app-schema-core/pom.xml b/src/extension/app-schema/app-schema-core/pom.xml index 16eb5fbc261..a16b285ab44 100644 --- a/src/extension/app-schema/app-schema-core/pom.xml +++ b/src/extension/app-schema/app-schema-core/pom.xml @@ -63,12 +63,10 @@ org.geotools gt-app-schema - ${gt.version} org.geotools gt-app-schema - ${gt.version} tests test @@ -93,26 +91,22 @@ org.geotools gt-sample-data - ${gt.version} test org.geotools gt-jdbc - ${gt.version} test-jar test org.geotools.jdbc gt-jdbc-postgis - ${gt.version} test org.geotools.jdbc gt-jdbc-oracle - ${gt.version} test diff --git a/src/extension/app-schema/app-schema-geopkg-test/pom.xml b/src/extension/app-schema/app-schema-geopkg-test/pom.xml index a0fc3b10c37..ed9c7be8df2 100644 --- a/src/extension/app-schema/app-schema-geopkg-test/pom.xml +++ b/src/extension/app-schema/app-schema-geopkg-test/pom.xml @@ -74,12 +74,10 @@ org.geotools gt-app-schema - ${gt.version} org.geotools gt-app-schema - ${gt.version} tests test @@ -109,26 +107,22 @@ org.geotools gt-sample-data - ${gt.version} test org.geotools gt-jdbc - ${gt.version} test-jar test org.geotools.jdbc gt-jdbc-postgis - ${gt.version} test org.geotools.jdbc gt-jdbc-oracle - ${gt.version} test diff --git a/src/extension/app-schema/app-schema-mongo-test/pom.xml b/src/extension/app-schema/app-schema-mongo-test/pom.xml index b071f8a7642..429f1d73be4 100644 --- a/src/extension/app-schema/app-schema-mongo-test/pom.xml +++ b/src/extension/app-schema/app-schema-mongo-test/pom.xml @@ -22,7 +22,6 @@ org.geotools gt-mongodb - ${gt.version} org.geoserver @@ -50,12 +49,10 @@ org.geotools gt-app-schema - ${gt.version} org.geotools gt-app-schema - ${gt.version} tests test diff --git a/src/extension/app-schema/app-schema-oracle-test/pom.xml b/src/extension/app-schema/app-schema-oracle-test/pom.xml index 3b2395a0f2c..034cda0ad94 100644 --- a/src/extension/app-schema/app-schema-oracle-test/pom.xml +++ b/src/extension/app-schema/app-schema-oracle-test/pom.xml @@ -74,12 +74,10 @@ org.geotools gt-app-schema - ${gt.version} org.geotools gt-app-schema - ${gt.version} tests test @@ -109,26 +107,22 @@ org.geotools gt-sample-data - ${gt.version} test org.geotools gt-jdbc - ${gt.version} test-jar test org.geotools.jdbc gt-jdbc-oracle - ${gt.version} test org.geotools.jdbc gt-jdbc-postgis - ${gt.version} test diff --git a/src/extension/app-schema/app-schema-postgis-test/pom.xml b/src/extension/app-schema/app-schema-postgis-test/pom.xml index e47e6106dff..b9693126de3 100644 --- a/src/extension/app-schema/app-schema-postgis-test/pom.xml +++ b/src/extension/app-schema/app-schema-postgis-test/pom.xml @@ -74,12 +74,10 @@ org.geotools gt-app-schema - ${gt.version} org.geotools gt-app-schema - ${gt.version} tests test @@ -109,26 +107,22 @@ org.geotools gt-sample-data - ${gt.version} test org.geotools gt-jdbc - ${gt.version} test-jar test org.geotools.jdbc gt-jdbc-postgis - ${gt.version} test org.geotools.jdbc gt-jdbc-oracle - ${gt.version} test diff --git a/src/extension/app-schema/app-schema-solr-test/pom.xml b/src/extension/app-schema/app-schema-solr-test/pom.xml index 65ec05f26a1..b489f4f31bc 100644 --- a/src/extension/app-schema/app-schema-solr-test/pom.xml +++ b/src/extension/app-schema/app-schema-solr-test/pom.xml @@ -16,12 +16,10 @@ org.geotools gt-solr - ${gt.version} org.geotools gt-solr - ${gt.version} tests test @@ -46,12 +44,10 @@ org.geotools gt-app-schema - ${gt.version} org.geotools gt-app-schema - ${gt.version} tests test diff --git a/src/extension/app-schema/app-schema-test/pom.xml b/src/extension/app-schema/app-schema-test/pom.xml index a4ce83ee3ae..be43bfe8821 100644 --- a/src/extension/app-schema/app-schema-test/pom.xml +++ b/src/extension/app-schema/app-schema-test/pom.xml @@ -74,12 +74,10 @@ org.geotools gt-app-schema - ${gt.version} org.geotools gt-app-schema - ${gt.version} tests test @@ -109,26 +107,22 @@ org.geotools gt-sample-data - ${gt.version} test org.geotools gt-jdbc - ${gt.version} test-jar test org.geotools.jdbc gt-jdbc-postgis - ${gt.version} test org.geotools.jdbc gt-jdbc-oracle - ${gt.version} test diff --git a/src/extension/app-schema/sample-data-access-test/pom.xml b/src/extension/app-schema/sample-data-access-test/pom.xml index 1ddce2f11ac..26dbe40f5d8 100644 --- a/src/extension/app-schema/sample-data-access-test/pom.xml +++ b/src/extension/app-schema/sample-data-access-test/pom.xml @@ -39,7 +39,6 @@ org.geotools gt-sample-data-access - ${gt.version} diff --git a/src/extension/css/pom.xml b/src/extension/css/pom.xml index 619a2810130..8d8dc5192ba 100644 --- a/src/extension/css/pom.xml +++ b/src/extension/css/pom.xml @@ -28,7 +28,6 @@ org.geotools gt-css - ${gt.version} diff --git a/src/extension/csw/api/pom.xml b/src/extension/csw/api/pom.xml index ee07c7e655f..f6a48bab42b 100644 --- a/src/extension/csw/api/pom.xml +++ b/src/extension/csw/api/pom.xml @@ -29,23 +29,19 @@ org.geotools.ogc net.opengis.fes - ${gt.version} org.geotools.ogc net.opengis.csw - ${gt.version} org.geotools.xsd gt-xsd-csw - ${gt.version} org.geotools gt-complex - ${gt.version} org.geotools.schemas diff --git a/src/extension/feature-pregeneralized/pom.xml b/src/extension/feature-pregeneralized/pom.xml index c1880bed152..88605242bf3 100644 --- a/src/extension/feature-pregeneralized/pom.xml +++ b/src/extension/feature-pregeneralized/pom.xml @@ -31,7 +31,6 @@ org.geotools gt-feature-pregeneralized - ${gt.version} diff --git a/src/extension/geofence/geofence-server/pom.xml b/src/extension/geofence/geofence-server/pom.xml index d8cae3bb529..ceda6fc3ee9 100644 --- a/src/extension/geofence/geofence-server/pom.xml +++ b/src/extension/geofence/geofence-server/pom.xml @@ -147,7 +147,6 @@ org.geotools.xsd gt-xsd-gml3 - ${gt.version} tests test diff --git a/src/extension/geopkg-output/pom.xml b/src/extension/geopkg-output/pom.xml index 0468ef3e15f..7be7adcf220 100644 --- a/src/extension/geopkg-output/pom.xml +++ b/src/extension/geopkg-output/pom.xml @@ -42,7 +42,6 @@ org.geotools gt-geopkg - ${gt.version} org.geoserver diff --git a/src/extension/grib/pom.xml b/src/extension/grib/pom.xml index e264f122a12..33417971669 100644 --- a/src/extension/grib/pom.xml +++ b/src/extension/grib/pom.xml @@ -19,7 +19,6 @@ org.geotools gt-grib - ${gt.version} slf4j-api @@ -35,7 +34,6 @@ org.geotools gt-sample-data - ${gt.version} test diff --git a/src/extension/importer/core/pom.xml b/src/extension/importer/core/pom.xml index 16b78d3d8e2..898c6da333b 100644 --- a/src/extension/importer/core/pom.xml +++ b/src/extension/importer/core/pom.xml @@ -34,7 +34,6 @@ org.geotools.xsd gt-xsd-kml - ${gt.version} org.geotools @@ -52,18 +51,16 @@ org.geotools gt-epsg-wkt - ${gt.version} test org.geotools gt-iau-wkt - ${gt.version} test org.apache.logging.log4j - log4j-slf4j-impl + log4j-slf4j2-impl test diff --git a/src/extension/importer/pom.xml b/src/extension/importer/pom.xml index fb4701c723f..c7bd2170f78 100644 --- a/src/extension/importer/pom.xml +++ b/src/extension/importer/pom.xml @@ -33,7 +33,6 @@ org.geotools gt-geojson-core - ${gt.version} org.geoserver diff --git a/src/extension/libjpeg-turbo/pom.xml b/src/extension/libjpeg-turbo/pom.xml index 76873f77e52..35a77bd3b36 100644 --- a/src/extension/libjpeg-turbo/pom.xml +++ b/src/extension/libjpeg-turbo/pom.xml @@ -18,7 +18,6 @@ org.geotools gt-sample-data - ${gt.version} test diff --git a/src/extension/mapml/pom.xml b/src/extension/mapml/pom.xml index 074d9d6cfb8..ef0f9480a66 100644 --- a/src/extension/mapml/pom.xml +++ b/src/extension/mapml/pom.xml @@ -93,7 +93,6 @@ org.geotools gt-iau-wkt - ${gt.version} test diff --git a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLDocumentBuilder.java b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLDocumentBuilder.java index 51c40cd7f0a..c35e4de5556 100644 --- a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLDocumentBuilder.java +++ b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLDocumentBuilder.java @@ -13,7 +13,6 @@ import static org.geoserver.mapml.MapMLConstants.MAPML_USE_FEATURES; import static org.geoserver.mapml.MapMLConstants.MAPML_USE_REMOTE; import static org.geoserver.mapml.MapMLConstants.MAPML_USE_TILES; -import static org.geoserver.mapml.MapMLHTMLOutput.PREVIEW_TCRS_MAP; import static org.geoserver.mapml.template.MapMLMapTemplate.MAPML_PREVIEW_HEAD_FTL; import static org.geoserver.mapml.template.MapMLMapTemplate.MAPML_XML_HEAD_FTL; import static org.geoserver.wms.capabilities.DimensionHelper.getDataType; @@ -65,6 +64,7 @@ import org.geoserver.gwc.GWC; import org.geoserver.gwc.layer.GeoServerTileLayer; import org.geoserver.mapml.tcrs.Bounds; +import org.geoserver.mapml.tcrs.MapMLProjection; import org.geoserver.mapml.tcrs.TiledCRS; import org.geoserver.mapml.template.MapMLMapTemplate; import org.geoserver.mapml.xml.AxisType; @@ -157,7 +157,7 @@ public class MapMLDocumentBuilder { private String imageFormat = DEFAULT_MIME_TYPE; private String baseUrl; private String baseUrlPattern; - private ProjType projType; + private MapMLProjection projType; private MetadataMap layerMeta; private int height; private int width; @@ -408,7 +408,7 @@ private MapMLLayerMetadata layersToOneMapMLLayerMetadata(List layers) mapMLLayerMetadata.setTimeEnabled(false); mapMLLayerMetadata.setElevationEnabled(false); mapMLLayerMetadata.setTransparent(transparent.orElse(false)); - ProjType projType = parseProjType(); + MapMLProjection projType = parseProjType(); mapMLLayerMetadata.setBbbox(layersToBBBox(layers, projType)); mapMLLayerMetadata.setQueryable(layersToQueryable(layers)); mapMLLayerMetadata.setLayerLabel(layersToLabel(layers)); @@ -422,9 +422,9 @@ private MapMLLayerMetadata layersToOneMapMLLayerMetadata(List layers) * Parses the projection into a ProjType, or throws a proper service exception indicating the * unsupported CRS */ - private ProjType parseProjType() { + private MapMLProjection parseProjType() { try { - return ProjType.fromValue(proj.toUpperCase()); + return new MapMLProjection(proj.toUpperCase()); } catch (IllegalArgumentException | FactoryException iae) { // figure out the parameter name (version dependent) and the actual original // string value for the srs/crs parameter @@ -488,10 +488,9 @@ private String layersToLabel(List layers) { * @param projType ProjType object * @return ReferencedEnvelope object */ - private ReferencedEnvelope layersToBBBox(List layers, ProjType projType) { - + private ReferencedEnvelope layersToBBBox(List layers, MapMLProjection projType) { ReferencedEnvelope bbbox; - bbbox = new ReferencedEnvelope(PREVIEW_TCRS_MAP.get(projType.value()).getCRS()); + bbbox = new ReferencedEnvelope(projType.getCRS()); for (int i = 0; i < layers.size(); i++) { RawLayer layer = layers.get(i); try { @@ -502,26 +501,20 @@ private ReferencedEnvelope layersToBBBox(List layers, ProjType projTyp .getResource() .boundingBox(); if (i == 0) { - bbbox = - layerBbbox.transform( - PREVIEW_TCRS_MAP.get(projType.value()).getCRS(), true); + bbbox = layerBbbox.transform(projType.getCRS(), true); } else { - bbbox.expandToInclude( - layerBbbox.transform( - PREVIEW_TCRS_MAP.get(projType.value()).getCRS(), true)); + bbbox.expandToInclude(layerBbbox.transform(projType.getCRS(), true)); } } catch (Exception e) { // get the default max/min of the pcrs from the TCRS - Bounds defaultBounds = PREVIEW_TCRS_MAP.get(projType.value()).getBounds(); + Bounds defaultBounds = projType.getTiledCRS().getBounds(); double x1, x2, y1, y2; x1 = defaultBounds.getMin().x; x2 = defaultBounds.getMax().x; y1 = defaultBounds.getMin().y; y2 = defaultBounds.getMax().y; // use the bounds of the TCRS as the default bounds for this layer - bbbox = - new ReferencedEnvelope( - x1, x2, y1, y2, PREVIEW_TCRS_MAP.get(projType.value()).getCRS()); + bbbox = new ReferencedEnvelope(x1, x2, y1, y2, projType.getCRS()); } } @@ -595,7 +588,7 @@ private MapMLLayerMetadata layerToMapMLLayerMetadata(RawLayer layer, String styl .orElse(DEFAULT_MIME_TYPE) .toString(); } - ProjType projType = parseProjType(); + MapMLProjection projType = parseProjType(); cqlFilter = cql != null ? cql : ""; tileLayerExists = gwc.hasTileLayer(isLayerGroup ? layerGroupInfo : layerInfo) @@ -843,15 +836,18 @@ private HeadContent prepareHead() throws IOException { selfStyleLink.setHref(selfStyleURL); links.add(selfStyleLink); // alternate projection links + ProjType builtInProj = projType.unwrap(); for (ProjType pt : ProjType.values()) { // skip the current proj - if (pt.equals(projType)) continue; + + if (pt.equals(builtInProj)) continue; try { Link projectionLink = new Link(); projectionLink.setRel(RelType.ALTERNATE); - projectionLink.setProjection(pt); + projectionLink.setProjection(pt.value()); // reproject the bounds - ReferencedEnvelope reprojectedBounds = reproject(projectedBox, pt); + ReferencedEnvelope reprojectedBounds = + reproject(projectedBox, new MapMLProjection(pt)); // Copy the base params to create one for self style Map projParams = new HashMap<>(wmsParams); projParams.put("crs", pt.getCRSCode()); @@ -972,9 +968,9 @@ private String buildStyles() throws IOException { * @throws FactoryException In the event of a factory error. * @throws TransformException In the event of a transform error. */ - private ReferencedEnvelope reproject(ReferencedEnvelope bounds, ProjType pt) + private ReferencedEnvelope reproject(ReferencedEnvelope bounds, MapMLProjection pt) throws FactoryException, TransformException { - CoordinateReferenceSystem targetCRS = PREVIEW_TCRS_MAP.get(pt.value()).getCRS(); + CoordinateReferenceSystem targetCRS = pt.getCRS(); // leverage the rendering ProjectionHandlers to build a set of envelopes // inside the valid area of the target CRS, and fuse them ProjectionHandler ph = ProjectionHandlerFinder.getHandler(bounds, targetCRS, true); @@ -1019,7 +1015,8 @@ private List prepareExtents() throws IOException { List extents = new ArrayList<>(); for (MapMLLayerMetadata mapMLLayerMetadata : mapMLLayerMetadataList) { Extent extent = new Extent(); - extent.setUnits(projType); + TiledCRS tiledCRS = projType.getTiledCRS(); + extent.setUnits(tiledCRS.getName()); extentList = extent.getInputOrDatalistOrLink(); // zoom @@ -1036,7 +1033,6 @@ private List prepareExtents() throws IOException { } Input extentZoomInput = new Input(); - TiledCRS tiledCRS = PREVIEW_TCRS_MAP.get(projType.value()); extentZoomInput.setName("z"); extentZoomInput.setType(InputType.ZOOM); // passing in max sld denominator to get min zoom @@ -1046,7 +1042,7 @@ private List prepareExtents() throws IOException { tiledCRS.getMinZoomForDenominator( scaleDenominators.getMaxValue().intValue())) : "0"); - int mxz = PREVIEW_TCRS_MAP.get(projType.value()).getScales().length - 1; + int mxz = tiledCRS.getScales().length - 1; // passing in min sld denominator to get max zoom String maxZoom = scaleDenominators != null @@ -1362,7 +1358,7 @@ private void generateTiledWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) // of WGS84 is a cartesian cs per the table on this page: // https://docs.geotools.org/stable/javadocs/org/opengis/referencing/cs/package-summary.html#AxisNames // input.setAxis(previewTcrsMap.get(projType.value()).getCRS(UnitType.PCRS).getAxisByDirection(AxisDirection.DISPLAY_RIGHT)); - bbbox = new ReferencedEnvelope(PREVIEW_TCRS_MAP.get(projType.value()).getCRS()); + bbbox = new ReferencedEnvelope(projType.getCRS()); LayerInfo layerInfo = mapMLLayerMetadata.getLayerInfo(); try { @@ -1370,12 +1366,12 @@ private void generateTiledWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) mapMLLayerMetadata.isLayerGroup() ? mapMLLayerMetadata.getLayerGroupInfo().getBounds() : layerInfo.getResource().boundingBox(); - bbbox = bbbox.transform(PREVIEW_TCRS_MAP.get(projType.value()).getCRS(), true); + bbbox = bbbox.transform(projType.getCRS(), true); } catch (Exception e) { // sometimes, when the geographicBox is right to 90N or 90S, in epsg:3857, // the transform method will throw. In that case, use the // bounds of the TCRS to define the geographicBox for the layer - TiledCRS t = PREVIEW_TCRS_MAP.get(projType.value()); + TiledCRS t = projType.getTiledCRS(); double x1 = t.getBounds().getMax().x; double y1 = t.getBounds().getMax().y; double x2 = t.getBounds().getMin().x; @@ -1392,7 +1388,7 @@ private void generateTiledWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) input.setUnits(UnitType.TILEMATRIX); input.setPosition(PositionType.TOP_LEFT); input.setRel(InputRelType.TILE); - input.setAxis(projType == projType.WGS_84 ? AxisType.LONGITUDE : AxisType.EASTING); + input.setAxis(ProjType.WGS_84 == projType.unwrap() ? AxisType.LONGITUDE : AxisType.EASTING); input.setMin(Double.toString(bbbox.getMinX())); input.setMax(Double.toString(bbbox.getMaxX())); extentList.add(input); @@ -1404,7 +1400,7 @@ private void generateTiledWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) input.setUnits(UnitType.TILEMATRIX); input.setPosition(PositionType.BOTTOM_LEFT); input.setRel(InputRelType.TILE); - input.setAxis(projType == projType.WGS_84 ? AxisType.LATITUDE : AxisType.NORTHING); + input.setAxis(ProjType.WGS_84 == projType.unwrap() ? AxisType.LATITUDE : AxisType.NORTHING); input.setMin(Double.toString(bbbox.getMinY())); input.setMax(Double.toString(bbbox.getMaxY())); extentList.add(input); @@ -1416,7 +1412,7 @@ private void generateTiledWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) input.setUnits(UnitType.TILEMATRIX); input.setPosition(PositionType.TOP_RIGHT); input.setRel(InputRelType.TILE); - input.setAxis(projType == projType.WGS_84 ? AxisType.LONGITUDE : AxisType.EASTING); + input.setAxis(ProjType.WGS_84 == projType.unwrap() ? AxisType.LONGITUDE : AxisType.EASTING); input.setMin(Double.toString(bbbox.getMinX())); input.setMax(Double.toString(bbbox.getMaxX())); extentList.add(input); @@ -1428,7 +1424,7 @@ private void generateTiledWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) input.setUnits(UnitType.TILEMATRIX); input.setPosition(PositionType.TOP_LEFT); input.setRel(InputRelType.TILE); - input.setAxis(projType == projType.WGS_84 ? AxisType.LATITUDE : AxisType.NORTHING); + input.setAxis(ProjType.WGS_84 == projType.unwrap() ? AxisType.LATITUDE : AxisType.NORTHING); input.setMin(Double.toString(bbbox.getMinY())); input.setMax(Double.toString(bbbox.getMaxY())); extentList.add(input); @@ -1490,7 +1486,7 @@ public void generateWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) { try { // initialization is necessary so as to set the PCRS to which // the resource's geographicBox will be transformed, below. - bbbox = new ReferencedEnvelope(PREVIEW_TCRS_MAP.get(projType.value()).getCRS()); + bbbox = new ReferencedEnvelope(projType.getCRS()); bbbox = mapMLLayerMetadata.isLayerGroup ? mapMLLayerMetadata.getLayerGroupInfo().getBounds() @@ -1503,19 +1499,17 @@ public void generateWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) { // the projectedBox.transform will leave the CRS set to that of whatever // was returned by layerInfo.getResource().boundingBox() or // layerGroupInfo.getBounds(), above. - bbbox = bbbox.transform(PREVIEW_TCRS_MAP.get(projType.value()).getCRS(), true); + bbbox = bbbox.transform(projType.getCRS(), true); } catch (Exception e) { // get the default max/min of the pcrs from the TCRS - Bounds defaultBounds = PREVIEW_TCRS_MAP.get(projType.value()).getBounds(); + Bounds defaultBounds = projType.getTiledCRS().getBounds(); double x1, x2, y1, y2; x1 = defaultBounds.getMin().x; x2 = defaultBounds.getMax().x; y1 = defaultBounds.getMin().y; y2 = defaultBounds.getMax().y; // use the bounds of the TCRS as the default bounds for this layer - bbbox = - new ReferencedEnvelope( - x1, x2, y1, y2, PREVIEW_TCRS_MAP.get(projType.value()).getCRS()); + bbbox = new ReferencedEnvelope(x1, x2, y1, y2, projType.getCRS()); } } @@ -1524,10 +1518,10 @@ public void generateWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) { Input input = new Input(); input.setName("xmin"); input.setType(InputType.LOCATION); - input.setUnits(projType == projType.WGS_84 ? UnitType.GCRS : UnitType.PCRS); + input.setUnits(ProjType.WGS_84 == projType.unwrap() ? UnitType.GCRS : UnitType.PCRS); input.setPosition(PositionType.TOP_LEFT); input.setRel(InputRelType.IMAGE); - input.setAxis(projType == projType.WGS_84 ? AxisType.LONGITUDE : AxisType.EASTING); + input.setAxis(ProjType.WGS_84 == projType.unwrap() ? AxisType.LONGITUDE : AxisType.EASTING); input.setMin(Double.toString(bbbox.getMinX())); input.setMax(Double.toString(bbbox.getMaxX())); extentList.add(input); @@ -1536,10 +1530,10 @@ public void generateWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) { input = new Input(); input.setName("ymin"); input.setType(InputType.LOCATION); - input.setUnits(projType == projType.WGS_84 ? UnitType.GCRS : UnitType.PCRS); + input.setUnits(ProjType.WGS_84 == projType.unwrap() ? UnitType.GCRS : UnitType.PCRS); input.setPosition(PositionType.BOTTOM_LEFT); input.setRel(InputRelType.IMAGE); - input.setAxis(projType == projType.WGS_84 ? AxisType.LATITUDE : AxisType.NORTHING); + input.setAxis(ProjType.WGS_84 == projType.unwrap() ? AxisType.LATITUDE : AxisType.NORTHING); input.setMin(Double.toString(bbbox.getMinY())); input.setMax(Double.toString(bbbox.getMaxY())); extentList.add(input); @@ -1548,10 +1542,10 @@ public void generateWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) { input = new Input(); input.setName("xmax"); input.setType(InputType.LOCATION); - input.setUnits(projType == projType.WGS_84 ? UnitType.GCRS : UnitType.PCRS); + input.setUnits(ProjType.WGS_84 == projType.unwrap() ? UnitType.GCRS : UnitType.PCRS); input.setPosition(PositionType.TOP_RIGHT); input.setRel(InputRelType.IMAGE); - input.setAxis(projType == projType.WGS_84 ? AxisType.LONGITUDE : AxisType.EASTING); + input.setAxis(ProjType.WGS_84 == projType.unwrap() ? AxisType.LONGITUDE : AxisType.EASTING); input.setMin(Double.toString(bbbox.getMinX())); input.setMax(Double.toString(bbbox.getMaxX())); extentList.add(input); @@ -1560,10 +1554,10 @@ public void generateWMSClientLinks(MapMLLayerMetadata mapMLLayerMetadata) { input = new Input(); input.setName("ymax"); input.setType(InputType.LOCATION); - input.setUnits(projType == projType.WGS_84 ? UnitType.GCRS : UnitType.PCRS); + input.setUnits(ProjType.WGS_84 == projType.unwrap() ? UnitType.GCRS : UnitType.PCRS); input.setPosition(PositionType.TOP_LEFT); input.setRel(InputRelType.IMAGE); - input.setAxis(projType == projType.WGS_84 ? AxisType.LATITUDE : AxisType.NORTHING); + input.setAxis(ProjType.WGS_84 == projType.unwrap() ? AxisType.LATITUDE : AxisType.NORTHING); input.setMin(Double.toString(bbbox.getMinY())); input.setMax(Double.toString(bbbox.getMaxY())); extentList.add(input); @@ -2314,7 +2308,7 @@ static class MapMLLayerMetadata { private boolean isTransparent; private String layerName; private String layerTitle; - private ProjType projType; + private MapMLProjection projType; private String styleName; private boolean tileLayerExists; @@ -2361,7 +2355,7 @@ public void setUseFeatures(boolean useFeatures) { * @param isTransparent boolean * @param layerName String * @param layerTitle String - * @param projType ProjType object + * @param projType ProjType * @param styleName String * @param tileLayerExists boolean * @param useTiles boolean @@ -2378,7 +2372,7 @@ public MapMLLayerMetadata( boolean isTransparent, String layerName, String layerTitle, - ProjType projType, + MapMLProjection projType, String styleName, boolean tileLayerExists, boolean useTiles, @@ -2678,7 +2672,7 @@ public void setLayerTitle(String layerTitle) { * * @return ProjType */ - public ProjType getProjType() { + public MapMLProjection getProjType() { return projType; } @@ -2687,7 +2681,7 @@ public ProjType getProjType() { * * @param projType ProjType */ - public void setProjType(ProjType projType) { + public void setProjType(MapMLProjection projType) { this.projType = projType; } diff --git a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLFeatureUtil.java b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLFeatureUtil.java index 5fe33a7dec8..47ac81aa1a0 100644 --- a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLFeatureUtil.java +++ b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLFeatureUtil.java @@ -37,7 +37,6 @@ import org.geoserver.mapml.xml.Link; import org.geoserver.mapml.xml.Mapml; import org.geoserver.mapml.xml.Meta; -import org.geoserver.mapml.xml.ProjType; import org.geoserver.mapml.xml.RelType; import org.geoserver.ows.Request; import org.geoserver.ows.URLMangler; @@ -45,7 +44,6 @@ import org.geoserver.platform.ServiceException; import org.geoserver.wms.featureinfo.FeatureTemplate; import org.geotools.api.feature.simple.SimpleFeature; -import org.geotools.api.referencing.FactoryException; import org.geotools.api.referencing.crs.CoordinateReferenceSystem; import org.geotools.api.referencing.crs.GeodeticCRS; import org.geotools.api.style.Style; @@ -409,7 +407,7 @@ private static Set deduceProjectionAndExtent( if (requestCRS != null) { responseCRS = requestCRS; responseCRSCode = CRS.toSRS(requestCRS); - tcrs = TiledCRSConstants.lookupTCRS(responseCRSCode); + tcrs = TiledCRSConstants.lookupTCRSParams(responseCRSCode); if (tcrs != null) { projection.setContent(tcrs.getName()); crs = (responseCRS instanceof GeodeticCRS) ? "gcrs" : "pcrs"; @@ -453,7 +451,7 @@ private static String getExtent( "top-left-easting=%1$.2f,top-left-northing=%2$.2f,bottom-right-easting=%3$.2f,bottom-right-northing=%4$.2f"; double minLong, minLat, maxLong, maxLat; double minEasting, minNorthing, maxEasting, maxNorthing; - TiledCRSParams tcrs = TiledCRSConstants.lookupTCRS(responseCRSCode); + TiledCRSParams tcrs = TiledCRSConstants.lookupTCRSParams(responseCRSCode); try { if (responseCRS instanceof GeodeticCRS) { re = r.getLatLonBoundingBox(); @@ -507,14 +505,10 @@ public static List alternateProjections( ArrayList links = new ArrayList<>(); Set projections = TiledCRSConstants.tiledCRSBySrsName.keySet(); projections.forEach( - (String p) -> { + (String proj) -> { Link l = new Link(); - TiledCRSParams projection = TiledCRSConstants.lookupTCRS(p); - try { - l.setProjection(ProjType.fromValue(projection.getName())); - } catch (FactoryException e) { - throw new ServiceException("Invalid TCRS name"); - } + TiledCRSParams projection = TiledCRSConstants.lookupTCRSParams(proj); + l.setProjection(projection.getName()); l.setRel(RelType.ALTERNATE); query.put("srsName", "MapML:" + projection.getName()); HashMap kvp = new HashMap<>(query.size()); @@ -529,7 +523,6 @@ public static List alternateProjections( base, path, kvp, URLMangler.URLType.SERVICE))); links.add(l); }); - return links; } diff --git a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLHTMLGetFeatureOutputFormat.java b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLHTMLGetFeatureOutputFormat.java index d7cfd22d05a..7d524c83990 100644 --- a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLHTMLGetFeatureOutputFormat.java +++ b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLHTMLGetFeatureOutputFormat.java @@ -20,7 +20,7 @@ import javax.servlet.http.HttpServletRequest; import org.geoserver.catalog.LayerInfo; import org.geoserver.config.GeoServer; -import org.geoserver.mapml.xml.ProjType; +import org.geoserver.mapml.tcrs.MapMLProjection; import org.geoserver.ows.Dispatcher; import org.geoserver.ows.Request; import org.geoserver.ows.URLMangler; @@ -83,7 +83,7 @@ protected void write( ReferencedEnvelope projectedBbox = extractBbox(fc); LayerInfo layerInfo = gs.getCatalog().getLayerByName(fc.getSchema().getTypeName()); CoordinateReferenceSystem crs = projectedBbox.getCoordinateReferenceSystem(); - ProjType projType = parseProjType(request); + MapMLProjection projType = parseProjType(request); double longitude; double latitude; ReferencedEnvelope geographicBox; @@ -116,7 +116,7 @@ protected void write( osw.flush(); } - private ProjType parseProjType(Request request) throws ServiceException { + private MapMLProjection parseProjType(Request request) throws ServiceException { try { Map rawKvp = request.getRawKvp(); String srs; @@ -127,7 +127,7 @@ private ProjType parseProjType(Request request) throws ServiceException { } else { srs = "EPSG:4326"; } - return ProjType.fromValue(srs.toUpperCase()); + return new MapMLProjection(srs.toUpperCase()); } catch (IllegalArgumentException | FactoryException iae) { // figure out the parameter name (version dependent) and the actual original // string value for the srs/crs parameter diff --git a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLHTMLOutput.java b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLHTMLOutput.java index 4c45c3c817e..578b6f238a2 100644 --- a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLHTMLOutput.java +++ b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLHTMLOutput.java @@ -6,32 +6,27 @@ import static org.apache.commons.text.StringEscapeUtils.escapeHtml4; -import java.util.HashMap; +import java.util.Locale; import javax.servlet.http.HttpServletRequest; import org.geoserver.mapml.tcrs.Bounds; +import org.geoserver.mapml.tcrs.MapMLProjection; import org.geoserver.mapml.tcrs.Point; import org.geoserver.mapml.tcrs.TiledCRS; -import org.geoserver.mapml.xml.ProjType; +import org.geoserver.mapml.tcrs.TiledCRSParams; import org.geoserver.ows.URLMangler; import org.geoserver.ows.util.ResponseUtils; +import org.geotools.api.referencing.crs.CoordinateReferenceSystem; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.referencing.CRS; +import org.geotools.referencing.proj.PROJFormattable; +import org.geotools.referencing.proj.PROJFormatter; /** Class delegated to build an HTML Document embedding a MapML Viewer. */ public class MapMLHTMLOutput { - public static final HashMap PREVIEW_TCRS_MAP = new HashMap<>(); - - static { - PREVIEW_TCRS_MAP.put("OSMTILE", new TiledCRS("OSMTILE")); - PREVIEW_TCRS_MAP.put("CBMTILE", new TiledCRS("CBMTILE")); - PREVIEW_TCRS_MAP.put("APSTILE", new TiledCRS("APSTILE")); - PREVIEW_TCRS_MAP.put("WGS84", new TiledCRS("WGS84")); - } - private String layerLabel; private HttpServletRequest request; - private ProjType projType; + private MapMLProjection projType; private String sourceUrL; private int zoom = 0; private Double latitude = 0.0; @@ -54,7 +49,7 @@ private MapMLHTMLOutput(HTMLOutputBuilder builder) { public static class HTMLOutputBuilder { private String layerLabel; private HttpServletRequest request; - private ProjType projType; + private MapMLProjection projType; private String sourceUrL; private ReferencedEnvelope projectedBbox; private int zoom = 0; @@ -72,7 +67,7 @@ public HTMLOutputBuilder setRequest(HttpServletRequest request) { return this; } - public HTMLOutputBuilder setProjType(ProjType projType) { + public HTMLOutputBuilder setProjType(MapMLProjection projType) { this.projType = projType; return this; } @@ -126,8 +121,9 @@ public String toHTML() { "mapml-viewer:defined { max-width: 100%; width: 100%; height: 100%; border: none; vertical-align: middle }\n") .append("mapml-viewer:not(:defined) > * { display: none; } n") .append("map-layer { display: none; }\n") - .append("\n") - .append("