11 KiB
Developer's Guide
Contents
{:.no_toc}
- Will be replaced with the ToC, excluding the "Contents" header {:toc}
Technology Overview
With GeoServer being a traditional, Spring Framework based, monolithic servlet application, a logical choice has been made to base the GeoServer derived microservices in the Spring Boot framework.
Additionally, Spring Cloud technologies enable crucial capabilities such as dynamic service discovery, externalized configuration, distributed events, API gateway, and more.
Only a curated list of the vast amount of GeoServer extensions will be supported, as they are verified and possibly adapted to work with this project's architecture.
System Architecture
The following diagram depicts the System's general architecture:
- Hexagons represent microservices;
- coloured rectangles, logical groupings of components;
- lines connecting a group to another component: connector applies to all services of the outgoing end, to all components of the incoming end;
- white rectangles, components that are platform/deployment choices. For example:
- "Event bus" could be a cloud provider's native service (event queue), or a microservice implementing a distributed event broker;
- "Catalog/Config backend" is the software component used to access the catalog and configuration. Might be a microservice itself, catalog/config provider for "data directory", database, or other kind of external service store, catalog/config backend implementations;
- "Catalog/Config storage" is the storage mechanism that backs the catalog/config software component. Might be a shared "data directory" or database, a "per instance" data directory or database, and so on, depending on the available catalog/config backend implementations, and how they're configured and provisioned;
- "Geospatial data sources" is whatever method is used to access the actual data served up by the microservices.
Does that mean GeoServer's .war is deployed several times, with each instance exposing a given "business capability"?
ABSOLUTELY NOT.
Each microservice is its own self-contained application, including only the GeoServer dependencies it needs. Moreover, care has been taken so that when a dependency has both required and non-required components, only the required ones are loaded.
Note the above diagram represents the overall system's architecture. This is not a deployment diagram. Deployment involves choice of platforms, configurations, and more; without affecting the general architecture. Some microservices/components, though planned and represented in the architecture diagram, have not yet been developed/integrated. For instance: the logging, tracing, and monitoring components, as well as the GWC and WPS microservices.
Components Overview
- Front services:
- Gateway
- Monitoring
- Infrastructure:
- Discovery
- Config
- Event bus
- Logging
- Tracing
- Cache
- GeoServer:
- Catalog
- OWS services
- REST API service
- Web-UI service
- GWC service
Building
Requirements:
- Java >= 11 JDK
- Maven >=
3.6.3 - Docker version >=
19.03.3 - docker-compose version >=
1.26.2
CN GeoServer uses Apache Maven (included) for a build system.
You need to have docker and docker-compose installed.
Build
Clone the repository, including submodules:
git clone --recursive /data2/groldan/git/geoserver-microservices
To build the applications run the following command from the root project directory:
./mvnw clean install
That will compile, run unit and integration tests, install maven artifacts to the local maven repository, and create all microservices docker images.
The maven build uses the com.spotify:dockerfile-maven-plugin maven plugin to build the microservice docker images.
The simple build command above creates the following docker images:
$ docker images|grep geoserver-cloud|sort
geoservercloud/geoserver-cloud-catalog 1.0-SNAPSHOT afed2dc4888e 39 minutes ago 403MB
geoservercloud/geoserver-cloud-config 1.0-SNAPSHOT be987ff2a85e 42 minutes ago 319MB
geoservercloud/geoserver-cloud-discovery 1.0-SNAPSHOT abc5a17cf14c 42 minutes ago 320MB
geoservercloud/geoserver-cloud-gateway 1.0-SNAPSHOT 10f267950c15 42 minutes ago 317MB
geoservercloud/geoserver-cloud-rest 1.0-SNAPSHOT 29406a1e1fdb 36 minutes ago 429MB
geoservercloud/geoserver-cloud-wcs 1.0-SNAPSHOT c77ac22aa522 37 minutes ago 391MB
geoservercloud/geoserver-cloud-webui 1.0-SNAPSHOT 876d6fc3fac0 36 minutes ago 449MB
geoservercloud/geoserver-cloud-wfs 1.0-SNAPSHOT 62960137eb5a 38 minutes ago 410MB
geoservercloud/geoserver-cloud-wms 1.0-SNAPSHOT 6686ca90b552 38 minutes ago 437MB
geoservercloud/geoserver-cloud-wps 1.0-SNAPSHOT 73bae600226c 37 minutes ago 416MB
To run the build without building the docker images, disable the docker maven profile:
$ ./mvnw clean install -P-docker
Running
docker-compose
Now run the docker composition as follows, the first time it might need to download some additional images for the rabbitmq event broker and the postgresql config database:
$ docker-compose --compatibility up -d
Run docker-compose --compatibility logs -f to watch startup progress of all services.
Watch the output of docker-compose ps until all services are healthy:
$ docker-compose --compatibility ps
Name Command State Ports
-----------------------------------------------------------------------------------------------------------------
gscloud_catalog_1 dockerize -wait http://con ... Up (healthy)
gscloud_config_1 dockerize -wait http://dis ... Up (healthy)
gscloud_database_1 docker-entrypoint.sh postgres Up (healthy) 0.0.0.0:5432->5432/tcp
gscloud_discovery_1 /bin/sh -c exec java $JAVA ... Up (healthy) 0.0.0.0:8761->8761/tcp
gscloud_gateway_1 dockerize -wait http://con ... Up (healthy) 0.0.0.0:9090->8080/tcp
gscloud_rabbitmq_1 docker-entrypoint.sh rabbi ... Up 15671/tcp, 0.0.0.0:15672->15672/tcp, ...
gscloud_rest_1 dockerize -wait http://con ... Up (healthy)
gscloud_wcs_1 dockerize -wait http://con ... Up (healthy)
gscloud_webui_1 dockerize -wait http://con ... Up (healthy)
gscloud_wfs_1 dockerize --timeout 60s -w ... Up (healthy)
gscloud_wms_1 dockerize -wait http://con ... Up (healthy)
Now you can access all front-services (wms, wfs, wcs, rest, and webui) through the gateway service at http://localhost:9090
Running a service in development/debug mode
Running a single service in "local" mode (that is, outside the docker composition) can be done either through the command line or through the IDE.
First, make sure at least the essential infrastructure services are running:
$ docker-compose up -d discovery rabbitmq config database catalog gateway
The
gatewayservice is not essential, but useful to check it's correctly proxy'ing requests to your locally running services as well as the ones in the docker composition.
To run a specific service through the command line, for example, wfs-service, run:
$ ./mvnw -f services/wfs spring-boot:run -Dspring-boot.run.profiles=local
To run a service through the IDE, execute the specific application class (for example, org.geoserver.cloud.wfs.app.WfsApplication), which is a regular Java class with a main() method, passing the JVM argument -Dspring-boot.run.profiles=local.
The "local" spring profile in each config/<service>.yml file sets a different hard-coded port for each service, which aids in debugging a locally running service:
catalog-service: 9100wfs-service: 9101wms-service: 9102wcs-service: 9103wps-service: 9100restconfig-v1: 9105web-ui: 9106
At startup time, as configured in its src/main/resources/bootstrap.yml file, the service will contact the discovery-service at the default http://localhost:8761/eureka location, given there's no eureka.server.url configuration property set (which is otherwise provided by docker-compose.yml).
Since docker-compose.yml exposes the discovery-service at the local port 8761, that's all the service being run locally needs to engage in the cluster. The discovery service will provide it with the location of any other service it needs to contact, starting with the config-service, where it will ultimatelly get the rest of the application configuration from.