You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@baremaps.apache.org by bc...@apache.org on 2023/06/16 22:01:48 UTC

[incubator-baremaps] 02/02: Add tile store supplier

This is an automated email from the ASF dual-hosted git repository.

bchapuis pushed a commit to branch server-refactoring
in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git

commit 409c14ea4acf85004c57c95999b71df45b5f0c94
Author: Bertil Chapuis <bc...@gmail.com>
AuthorDate: Fri Jun 16 23:58:33 2023 +0200

    Add tile store supplier
---
 .run/basemap-serve.run.xml                         | 17 +++++
 .../main/java/org/apache/baremaps/cli/map/Dev.java | 76 +++++++++++++---------
 .../java/org/apache/baremaps/cli/map/Serve.java    | 11 +++-
 .../apache/baremaps/server/ServerResources.java    | 47 ++-----------
 .../{ServerResources.java => TileResources.java}   | 49 +++-----------
 .../apache/baremaps/server/ViewerResources.java    | 50 ++------------
 6 files changed, 91 insertions(+), 159 deletions(-)

diff --git a/.run/basemap-serve.run.xml b/.run/basemap-serve.run.xml
new file mode 100644
index 00000000..a4a0153a
--- /dev/null
+++ b/.run/basemap-serve.run.xml
@@ -0,0 +1,17 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="basemap-serve" type="Application" factoryName="Application">
+    <option name="MAIN_CLASS_NAME" value="org.apache.baremaps.cli.Baremaps" />
+    <module name="baremaps-cli" />
+    <option name="PROGRAM_PARAMETERS" value="map serve --tileset tileset.js --style style.js" />
+    <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/basemap" />
+    <extension name="coverage">
+      <pattern>
+        <option name="PATTERN" value="org.apache.baremaps.server.ogcapi.*" />
+        <option name="ENABLED" value="true" />
+      </pattern>
+    </extension>
+    <method v="2">
+      <option name="Make" enabled="true" />
+    </method>
+  </configuration>
+</component>
\ No newline at end of file
diff --git a/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Dev.java b/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Dev.java
index 4f083525..58ac2f46 100644
--- a/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Dev.java
+++ b/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Dev.java
@@ -12,22 +12,27 @@
 
 package org.apache.baremaps.cli.map;
 
-import static io.servicetalk.data.jackson.jersey.ServiceTalkJacksonSerializerFeature.contextResolverFor;
+import static io.servicetalk.data.jackson.jersey.ServiceTalkJacksonSerializerFeature.newContextResolver;
 import static org.apache.baremaps.utils.ObjectMapperUtils.objectMapper;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import io.servicetalk.http.netty.HttpServers;
 import io.servicetalk.http.router.jersey.HttpJerseyRouterBuilder;
+import java.io.IOException;
 import java.nio.file.Path;
 import java.util.concurrent.Callable;
-import javax.sql.DataSource;
+import java.util.function.Supplier;
 import org.apache.baremaps.cli.Options;
 import org.apache.baremaps.config.ConfigReader;
 import org.apache.baremaps.postgres.PostgresUtils;
 import org.apache.baremaps.server.ClassPathResources;
 import org.apache.baremaps.server.CorsFilter;
+import org.apache.baremaps.server.TileResources;
 import org.apache.baremaps.server.ViewerResources;
+import org.apache.baremaps.tilestore.TileStore;
+import org.apache.baremaps.tilestore.postgres.PostgresTileStore;
 import org.apache.baremaps.vectortile.tileset.Tileset;
+import org.glassfish.hk2.api.TypeLiteral;
 import org.glassfish.hk2.utilities.binding.AbstractBinder;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.slf4j.Logger;
@@ -63,37 +68,46 @@ public class Dev implements Callable<Integer> {
   @Override
   public Integer call() throws Exception {
     var configReader = new ConfigReader();
-    // Configure serialization
     var objectMapper = objectMapper();
+    var tileset = objectMapper.readValue(configReader.read(this.tileset), Tileset.class);
+    var datasource = PostgresUtils.dataSource(tileset.getDatabase());
+
+    // Configure the tile store
+    var tileStoreType = new TypeLiteral<Supplier<TileStore>>() {};
+    var tileStoreSupplier = (Supplier<TileStore>) () -> {
+      try {
+        var tilesetObject = objectMapper.readValue(configReader.read(this.tileset), Tileset.class);
+        return new PostgresTileStore(datasource, tilesetObject);
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    };
+
+    // Configure the application
+    var application = new ResourceConfig()
+        .register(CorsFilter.class)
+        .register(ViewerResources.class)
+        .register(TileResources.class)
+        .register(ClassPathResources.class)
+        .register(newContextResolver(objectMapper))
+        .register(new AbstractBinder() {
+          @Override
+          protected void configure() {
+            bind("assets").to(String.class).named("directory");
+            bind("viewer.html").to(String.class).named("index");
+            bind(Dev.this.tileset.toAbsolutePath()).to(Path.class).named("tileset");
+            bind(style.toAbsolutePath()).to(Path.class).named("style");
+            bind(objectMapper).to(ObjectMapper.class);
+            bind(tileStoreSupplier).to(tileStoreType);
+          }
+        });
+
+    var httpService = new HttpJerseyRouterBuilder().buildBlockingStreaming(application);
+    var serverContext = HttpServers.forPort(port).listenBlockingStreamingAndAwait(httpService);
+
+    logger.info("Listening on {}", serverContext.listenAddress());
+    serverContext.awaitShutdown();
 
-    var tileSet = objectMapper.readValue(configReader.read(tileset), Tileset.class);
-    var database = tileSet.getDatabase();
-
-    try (var dataSource = PostgresUtils.dataSource(database)) {
-      // Configure the application
-      var application = new ResourceConfig()
-          .register(CorsFilter.class)
-          .register(ViewerResources.class)
-          .register(ClassPathResources.class)
-          .register(contextResolverFor(objectMapper))
-          .register(new AbstractBinder() {
-            @Override
-            protected void configure() {
-              bind("assets").to(String.class).named("directory");
-              bind("viewer.html").to(String.class).named("index");
-              bind(tileset.toAbsolutePath()).to(Path.class).named("tileset");
-              bind(style.toAbsolutePath()).to(Path.class).named("style");
-              bind(dataSource).to(DataSource.class);
-              bind(objectMapper).to(ObjectMapper.class);
-            }
-          });
-
-      var httpService = new HttpJerseyRouterBuilder().buildBlockingStreaming(application);
-      var serverContext = HttpServers.forPort(port).listenBlockingStreamingAndAwait(httpService);
-
-      logger.info("Listening on {}", serverContext.listenAddress());
-      serverContext.awaitShutdown();
-    }
     return 0;
   }
 }
diff --git a/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Serve.java b/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Serve.java
index 018c5809..537a2f79 100644
--- a/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Serve.java
+++ b/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Serve.java
@@ -12,7 +12,7 @@
 
 package org.apache.baremaps.cli.map;
 
-import static io.servicetalk.data.jackson.jersey.ServiceTalkJacksonSerializerFeature.contextResolverFor;
+import static io.servicetalk.data.jackson.jersey.ServiceTalkJacksonSerializerFeature.newContextResolver;
 import static org.apache.baremaps.utils.ObjectMapperUtils.objectMapper;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -21,16 +21,19 @@ import io.servicetalk.http.netty.HttpServers;
 import io.servicetalk.http.router.jersey.HttpJerseyRouterBuilder;
 import java.nio.file.Path;
 import java.util.concurrent.Callable;
+import java.util.function.Supplier;
 import org.apache.baremaps.cli.Options;
 import org.apache.baremaps.config.ConfigReader;
 import org.apache.baremaps.postgres.PostgresUtils;
 import org.apache.baremaps.server.ClassPathResources;
 import org.apache.baremaps.server.CorsFilter;
 import org.apache.baremaps.server.ServerResources;
+import org.apache.baremaps.server.TileResources;
 import org.apache.baremaps.tilestore.TileCache;
 import org.apache.baremaps.tilestore.TileStore;
 import org.apache.baremaps.tilestore.postgres.PostgresTileStore;
 import org.apache.baremaps.vectortile.tileset.Tileset;
+import org.glassfish.hk2.api.TypeLiteral;
 import org.glassfish.hk2.utilities.binding.AbstractBinder;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.slf4j.Logger;
@@ -72,16 +75,19 @@ public class Serve implements Callable<Integer> {
     var caffeineSpec = CaffeineSpec.parse(cache);
     var datasource = PostgresUtils.dataSource(tileset.getDatabase());
 
+    var tileStoreType = new TypeLiteral<Supplier<TileStore>>() {};
     var tileStore = new PostgresTileStore(datasource, tileset);
     var tileCache = new TileCache(tileStore, caffeineSpec);
+    var tileStoreSupplier = (Supplier<TileStore>) () -> tileCache;
 
     // Configure the application
     var application =
         new ResourceConfig()
             .register(CorsFilter.class)
             .register(ServerResources.class)
+            .register(TileResources.class)
             .register(ClassPathResources.class)
-            .register(contextResolverFor(objectMapper))
+            .register(newContextResolver(objectMapper))
             .register(new AbstractBinder() {
               @Override
               protected void configure() {
@@ -91,6 +97,7 @@ public class Serve implements Callable<Integer> {
                 bind(style).to(Path.class).named("style");
                 bind(tileCache).to(TileStore.class);
                 bind(objectMapper).to(ObjectMapper.class);
+                bind(tileStoreSupplier).to(tileStoreType);
               }
             });
 
diff --git a/baremaps-server/src/main/java/org/apache/baremaps/server/ServerResources.java b/baremaps-server/src/main/java/org/apache/baremaps/server/ServerResources.java
index dda8e904..9d51fd92 100644
--- a/baremaps-server/src/main/java/org/apache/baremaps/server/ServerResources.java
+++ b/baremaps-server/src/main/java/org/apache/baremaps/server/ServerResources.java
@@ -12,27 +12,18 @@
 
 package org.apache.baremaps.server;
 
-import static com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN;
-import static com.google.common.net.HttpHeaders.CONTENT_ENCODING;
-import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
 import java.nio.file.Path;
 import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Singleton;
 import javax.ws.rs.GET;
-import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
 import org.apache.baremaps.config.ConfigReader;
-import org.apache.baremaps.tilestore.TileCoord;
 import org.apache.baremaps.tilestore.TileStore;
-import org.apache.baremaps.tilestore.TileStoreException;
 import org.apache.baremaps.vectortile.style.Style;
 import org.apache.baremaps.vectortile.tilejson.TileJSON;
 
@@ -44,17 +35,12 @@ public class ServerResources {
 
   private final TileJSON tileJSON;
 
-  private final TileStore tileStore;
-
-  public static final String TILE_ENCODING = "gzip";
-
-  public static final String TILE_TYPE = "application/vnd.mapbox-vector-tile";
-
   @Inject
-  public ServerResources(@Named("tileset") Path tileset, @Named("style") Path style,
-      TileStore tileStore, ObjectMapper objectMapper) throws IOException {
-    this.tileStore = tileStore;
-    var configReader = new ConfigReader();
+  public ServerResources(
+          @Named("tileset") Path tileset,
+          @Named("style") Path style,
+          ObjectMapper objectMapper) throws IOException {
+    ConfigReader configReader = new ConfigReader();
     this.style = objectMapper.readValue(configReader.read(style), Style.class);
     this.tileJSON = objectMapper.readValue(configReader.read(tileset), TileJSON.class);
   }
@@ -72,27 +58,4 @@ public class ServerResources {
   public TileJSON getTileset() {
     return tileJSON;
   }
-
-  @GET
-  @javax.ws.rs.Path("/tiles/{z}/{x}/{y}.mvt")
-  public Response getTile(@PathParam("z") int z, @PathParam("x") int x, @PathParam("y") int y) {
-    TileCoord tileCoord = new TileCoord(x, y, z);
-    try {
-      ByteBuffer blob = tileStore.read(tileCoord);
-      if (blob != null) {
-        byte[] bytes = new byte[blob.remaining()];
-        blob.get(bytes);
-        return Response.status(200) // lgtm [java/xss]
-            .header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
-            .header(CONTENT_TYPE, TILE_TYPE)
-            .header(CONTENT_ENCODING, TILE_ENCODING)
-            .entity(bytes)
-            .build();
-      } else {
-        return Response.status(204).build();
-      }
-    } catch (TileStoreException ex) {
-      return Response.status(404).build();
-    }
-  }
 }
diff --git a/baremaps-server/src/main/java/org/apache/baremaps/server/ServerResources.java b/baremaps-server/src/main/java/org/apache/baremaps/server/TileResources.java
similarity index 57%
copy from baremaps-server/src/main/java/org/apache/baremaps/server/ServerResources.java
copy to baremaps-server/src/main/java/org/apache/baremaps/server/TileResources.java
index dda8e904..e990e7c9 100644
--- a/baremaps-server/src/main/java/org/apache/baremaps/server/ServerResources.java
+++ b/baremaps-server/src/main/java/org/apache/baremaps/server/TileResources.java
@@ -12,65 +12,32 @@
 
 package org.apache.baremaps.server;
 
-import static com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN;
-import static com.google.common.net.HttpHeaders.CONTENT_ENCODING;
-import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
+import static com.google.common.net.HttpHeaders.*;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import java.io.IOException;
-import java.io.InputStream;
 import java.nio.ByteBuffer;
-import java.nio.file.Path;
+import java.util.function.Supplier;
 import javax.inject.Inject;
-import javax.inject.Named;
 import javax.inject.Singleton;
 import javax.ws.rs.GET;
 import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import org.apache.baremaps.config.ConfigReader;
 import org.apache.baremaps.tilestore.TileCoord;
 import org.apache.baremaps.tilestore.TileStore;
 import org.apache.baremaps.tilestore.TileStoreException;
-import org.apache.baremaps.vectortile.style.Style;
-import org.apache.baremaps.vectortile.tilejson.TileJSON;
 
 @Singleton
 @javax.ws.rs.Path("/")
-public class ServerResources {
-
-  private final Style style;
-
-  private final TileJSON tileJSON;
-
-  private final TileStore tileStore;
+public class TileResources {
 
   public static final String TILE_ENCODING = "gzip";
 
   public static final String TILE_TYPE = "application/vnd.mapbox-vector-tile";
 
-  @Inject
-  public ServerResources(@Named("tileset") Path tileset, @Named("style") Path style,
-      TileStore tileStore, ObjectMapper objectMapper) throws IOException {
-    this.tileStore = tileStore;
-    var configReader = new ConfigReader();
-    this.style = objectMapper.readValue(configReader.read(style), Style.class);
-    this.tileJSON = objectMapper.readValue(configReader.read(tileset), TileJSON.class);
-  }
+  private final Supplier<TileStore> tileStoreSupplier;
 
-  @GET
-  @javax.ws.rs.Path("style.json")
-  @Produces(MediaType.APPLICATION_JSON)
-  public Style getStyle() {
-    return style;
-  }
-
-  @GET
-  @javax.ws.rs.Path("tiles.json")
-  @Produces(MediaType.APPLICATION_JSON)
-  public TileJSON getTileset() {
-    return tileJSON;
+  @Inject
+  public TileResources(Supplier<TileStore> tileStoreSupplier) {
+    this.tileStoreSupplier = tileStoreSupplier;
   }
 
   @GET
@@ -78,6 +45,7 @@ public class ServerResources {
   public Response getTile(@PathParam("z") int z, @PathParam("x") int x, @PathParam("y") int y) {
     TileCoord tileCoord = new TileCoord(x, y, z);
     try {
+      TileStore tileStore = tileStoreSupplier.get();
       ByteBuffer blob = tileStore.read(tileCoord);
       if (blob != null) {
         byte[] bytes = new byte[blob.remaining()];
@@ -95,4 +63,5 @@ public class ServerResources {
       return Response.status(404).build();
     }
   }
+
 }
diff --git a/baremaps-server/src/main/java/org/apache/baremaps/server/ViewerResources.java b/baremaps-server/src/main/java/org/apache/baremaps/server/ViewerResources.java
index 0519f58a..72794021 100644
--- a/baremaps-server/src/main/java/org/apache/baremaps/server/ViewerResources.java
+++ b/baremaps-server/src/main/java/org/apache/baremaps/server/ViewerResources.java
@@ -12,13 +12,10 @@
 
 package org.apache.baremaps.server;
 
-import static com.google.common.net.HttpHeaders.CONTENT_ENCODING;
-import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import java.io.IOException;
-import java.io.InputStream;
 import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -27,21 +24,16 @@ import javax.inject.Named;
 import javax.inject.Singleton;
 import javax.sql.DataSource;
 import javax.ws.rs.GET;
-import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
 import javax.ws.rs.sse.OutboundSseEvent;
 import javax.ws.rs.sse.Sse;
 import javax.ws.rs.sse.SseBroadcaster;
 import javax.ws.rs.sse.SseEventSink;
 import org.apache.baremaps.config.ConfigReader;
-import org.apache.baremaps.tilestore.TileCoord;
-import org.apache.baremaps.tilestore.postgres.PostgresTileStore;
 import org.apache.baremaps.vectortile.style.Style;
 import org.apache.baremaps.vectortile.tilejson.TileJSON;
-import org.apache.baremaps.vectortile.tileset.Tileset;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -57,33 +49,26 @@ public class ViewerResources {
 
   private final Path tileset;
 
-  private final DataSource dataSource;
-
   private final ObjectMapper objectMapper;
 
-  private final Sse sse;
-
   private final SseBroadcaster sseBroadcaster;
 
   private final OutboundSseEvent.Builder sseEventBuilder;
 
-  public static final String TILE_ENCODING = "gzip";
-
-  public static final String TILE_TYPE = "application/vnd.mapbox-vector-tile";
-
   @Inject
-  public ViewerResources(@Named("tileset") Path tileset, @Named("style") Path style,
-      DataSource dataSource, ObjectMapper objectMapper, Sse sse) {
+  public ViewerResources(
+          @Named("tileset") Path tileset,
+          @Named("style") Path style,
+      ObjectMapper objectMapper,
+          Sse sse) {
     this.tileset = tileset.toAbsolutePath();
     this.style = style.toAbsolutePath();
-    this.dataSource = dataSource;
     this.objectMapper = objectMapper;
-    this.sse = sse;
     this.sseBroadcaster = sse.newBroadcaster();
     this.sseEventBuilder = sse.newEventBuilder();
 
     // Observe the file system for changes
-    var directories = new HashSet<Path>(Arrays.asList(tileset.getParent(), style.getParent()));
+    var directories = new HashSet<>(Arrays.asList(tileset.getParent(), style.getParent()));
     new Thread(new DirectoryWatcher(directories, this::broadcastChanges)).start();
   }
 
@@ -126,27 +111,4 @@ public class ViewerResources {
     var object = objectMapper.readValue(config, TileJSON.class);
     return object;
   }
-
-  @GET
-  @javax.ws.rs.Path("/tiles/{z}/{x}/{y}.mvt")
-  public Response getTile(@PathParam("z") int z, @PathParam("x") int x, @PathParam("y") int y) {
-    try {
-      var tileStore = new PostgresTileStore(dataSource,
-          objectMapper.readValue(configReader.read(tileset), Tileset.class));
-      var tileCoord = new TileCoord(x, y, z);
-      var blob = tileStore.read(tileCoord);
-      if (blob != null) {
-        return Response.status(200)
-            .header(CONTENT_TYPE, TILE_TYPE)
-            .header(CONTENT_ENCODING, TILE_ENCODING)
-            .entity(blob.array())
-            .build();
-      } else {
-        return Response.status(204).build();
-      }
-    } catch (Exception ex) {
-      logger.error("Tile error", ex);
-      return Response.status(404).build();
-    }
-  }
 }