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

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

commit 8d040716b57d9527ad503f534b1a3e7fa8cac102
Author: Bertil Chapuis <[email protected]>
AuthorDate: Sun Jan 14 09:26:46 2024 +0100

    Enable armeria in dev mode
---
 .../main/java/org/apache/baremaps/cli/map/Dev.java | 67 +++++++++++-----------
 baremaps-server/pom.xml                            |  8 +++
 .../org/apache/baremaps/server/ChangeResource.java | 49 ++++++----------
 .../org/apache/baremaps/server/StyleResource.java  | 15 ++---
 .../apache/baremaps/server/TileJSONResource.java   | 15 ++---
 .../org/apache/baremaps/server/TileResource.java   | 38 ++++++------
 .../apache/baremaps/server/TilesetResource.java    | 15 ++---
 pom.xml                                            | 11 ++++
 8 files changed, 98 insertions(+), 120 deletions(-)

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 dc85e334..f335ab6b 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
@@ -17,27 +17,29 @@
 
 package org.apache.baremaps.cli.map;
 
-import static 
io.servicetalk.data.jackson.jersey.ServiceTalkJacksonSerializerFeature.newContextResolver;
 import static org.apache.baremaps.utils.ObjectMapperUtils.objectMapper;
 
-import io.servicetalk.http.netty.HttpServers;
-import io.servicetalk.http.router.jersey.HttpJerseyRouterBuilder;
+import com.linecorp.armeria.common.HttpMethod;
+import com.linecorp.armeria.server.Server;
+import com.linecorp.armeria.server.annotation.JacksonResponseConverterFunction;
+import com.linecorp.armeria.server.cors.CorsService;
+import com.linecorp.armeria.server.file.FileService;
 import java.io.IOException;
 import java.nio.file.Path;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
 import java.util.function.Supplier;
+
+import com.linecorp.armeria.server.file.HttpFile;
 import org.apache.baremaps.cli.Options;
 import org.apache.baremaps.config.ConfigReader;
 import org.apache.baremaps.server.*;
-import org.apache.baremaps.server.CorsFilter;
 import org.apache.baremaps.tilestore.TileStore;
 import org.apache.baremaps.tilestore.postgres.PostgresTileStore;
 import org.apache.baremaps.utils.PostgresUtils;
 import org.apache.baremaps.vectortile.style.Style;
 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;
 import org.slf4j.LoggerFactory;
 import picocli.CommandLine.Command;
@@ -88,7 +90,6 @@ public class Dev implements Callable<Integer> {
       }
     };
 
-    var styleSupplierType = new TypeLiteral<Supplier<Style>>() {};
     var styleSupplier = (Supplier<Style>) () -> {
       try {
         var config = configReader.read(stylePath);
@@ -98,7 +99,6 @@ public class Dev implements Callable<Integer> {
       }
     };
 
-    var tileJSONSupplierType = new TypeLiteral<Supplier<Tileset>>() {};
     var tileJSONSupplier = (Supplier<Tileset>) () -> {
       try {
         var config = configReader.read(tilesetPath);
@@ -108,33 +108,30 @@ public class Dev implements Callable<Integer> {
       }
     };
 
-    var application = new ResourceConfig()
-        .register(CorsFilter.class)
-        .register(ChangeResource.class)
-        .register(TileResource.class)
-        .register(StyleResource.class)
-        .register(TilesetResource.class)
-        .register(ChangeResource.class)
-        .register(ClassPathResource.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(tilesetPath).to(Path.class).named("tileset");
-            bind(stylePath).to(Path.class).named("style");
-            bind(tileStoreSupplier).to(tileStoreType);
-            bind(styleSupplier).to(styleSupplierType);
-            bind(tileJSONSupplier).to(tileJSONSupplierType);
-          }
-        });
-
-    var httpService = new 
HttpJerseyRouterBuilder().buildBlockingStreaming(application);
-    var serverContext = 
HttpServers.forPort(port).listenBlockingStreamingAndAwait(httpService);
-
-    logger.info("Listening on {}", serverContext.listenAddress());
-    serverContext.awaitShutdown();
+    var serverBuilder = Server.builder();
+    serverBuilder.http(port);
+
+    JacksonResponseConverterFunction jsonResponseConverter = new 
JacksonResponseConverterFunction(objectMapper);
+    serverBuilder.annotatedService(new ChangeResource(tilesetPath, stylePath), 
jsonResponseConverter);
+    serverBuilder.annotatedService(new TileResource(tileStoreSupplier), 
jsonResponseConverter);
+    serverBuilder.annotatedService(new StyleResource(styleSupplier), 
jsonResponseConverter);
+    serverBuilder.annotatedService(new TilesetResource(tileJSONSupplier), 
jsonResponseConverter);
+
+    HttpFile index = HttpFile.of(ClassLoader.getSystemClassLoader(), 
"/assets/viewer.html");
+    serverBuilder.service("/", index.asService());
+    serverBuilder.serviceUnder("/", 
FileService.of(ClassLoader.getSystemClassLoader(), "/assets"));
+
+    serverBuilder.decorator(CorsService.builderForAnyOrigin()
+          .allowRequestMethods(HttpMethod.POST, HttpMethod.GET, HttpMethod.PUT)
+          .allowRequestHeaders("Origin", "Content-Type", "Accept")
+          .newDecorator());
+    
+    serverBuilder.disableServerHeader();
+    serverBuilder.disableDateHeader();
+
+    Server server = serverBuilder.build();
+    CompletableFuture<Void> future = server.start();
+    future.join();
 
     return 0;
   }
diff --git a/baremaps-server/pom.xml b/baremaps-server/pom.xml
index 291e6b72..8ebd29dd 100644
--- a/baremaps-server/pom.xml
+++ b/baremaps-server/pom.xml
@@ -26,6 +26,14 @@ limitations under the License.
   <artifactId>baremaps-server</artifactId>
 
   <dependencies>
+    <dependency>
+      <groupId>com.linecorp.armeria</groupId>
+      <artifactId>armeria</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.linecorp.armeria</groupId>
+      <artifactId>armeria-reactor3</artifactId>
+    </dependency>
     <dependency>
       <groupId>io.servicetalk</groupId>
       <artifactId>servicetalk-http-api</artifactId>
diff --git 
a/baremaps-server/src/main/java/org/apache/baremaps/server/ChangeResource.java 
b/baremaps-server/src/main/java/org/apache/baremaps/server/ChangeResource.java
index 0b714edb..ebd80eee 100644
--- 
a/baremaps-server/src/main/java/org/apache/baremaps/server/ChangeResource.java
+++ 
b/baremaps-server/src/main/java/org/apache/baremaps/server/ChangeResource.java
@@ -22,28 +22,21 @@ import static 
java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.linecorp.armeria.common.sse.ServerSentEvent;
+import com.linecorp.armeria.server.ServiceRequestContext;
+import com.linecorp.armeria.server.annotation.Get;
+import com.linecorp.armeria.server.annotation.ProducesEventStream;
 import java.io.IOException;
 import java.nio.file.*;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import javax.ws.rs.GET;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-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.jvnet.hk2.annotations.Optional;
+import org.reactivestreams.Publisher;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import reactor.core.publisher.Sinks;
 
 /**
  * A resource that provides the changes in the tileset and style.
  */
-@Singleton
[email protected]("/")
 public class ChangeResource {
 
   private static final Logger logger = 
LoggerFactory.getLogger(ChangeResource.class);
@@ -56,40 +49,30 @@ public class ChangeResource {
 
   private final Path style;
 
-  private final SseBroadcaster sseBroadcaster;
-
-  private final OutboundSseEvent.Builder sseEventBuilder;
+  private final Sinks.Many<ServerSentEvent> changes = 
Sinks.many().multicast().directBestEffort();
 
   /**
    * Constructs a {@code ChangeResource}.
    * 
    * @param tileset the path to the tileset
    * @param style the path to the style
-   * @param sse the server-sent events
    */
-  @Inject
-  public ChangeResource(
-      @Named("tileset") @Optional Path tileset,
-      @Named("style") @Optional Path style,
-      Sse sse) {
+  public ChangeResource(Path tileset, Path style) {
     this.tileset = tileset;
     this.style = style;
-    this.sseBroadcaster = sse.newBroadcaster();
-    this.sseEventBuilder = sse.newEventBuilder();
-    var changeListener = new ChangeListener();
-    new Thread(changeListener).start();
+    new Thread(new ChangeListener()).start();
   }
 
   /**
    * Returns the changes in the tileset and style.
    * 
-   * @param sseEventSink the server-sent events
+   * @param ctx the service request context
    */
-  @GET
-  @javax.ws.rs.Path("changes")
-  @Produces("text/event-stream")
-  public void changes(@Context SseEventSink sseEventSink) {
-    sseBroadcaster.register(sseEventSink);
+  @Get("/changes")
+  @ProducesEventStream
+  public Publisher<ServerSentEvent> changes(ServiceRequestContext ctx) {
+    ctx.clearRequestTimeout();
+    return changes.asFlux();
   }
 
   /**
@@ -127,7 +110,7 @@ public class ChangeResource {
               }
 
               // broadcast the changes
-              
sseBroadcaster.broadcast(sseEventBuilder.data(styleObjectNode.toString()).build());
+              
changes.tryEmitNext(ServerSentEvent.ofData(styleObjectNode.toString()));
             }
           }
           key.reset();
diff --git 
a/baremaps-server/src/main/java/org/apache/baremaps/server/StyleResource.java 
b/baremaps-server/src/main/java/org/apache/baremaps/server/StyleResource.java
index 4302e5b1..2e25245a 100644
--- 
a/baremaps-server/src/main/java/org/apache/baremaps/server/StyleResource.java
+++ 
b/baremaps-server/src/main/java/org/apache/baremaps/server/StyleResource.java
@@ -17,31 +17,24 @@
 
 package org.apache.baremaps.server;
 
+import com.linecorp.armeria.server.annotation.Get;
+import com.linecorp.armeria.server.annotation.ProducesJson;
 import java.util.function.Supplier;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.ws.rs.GET;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
 import org.apache.baremaps.vectortile.style.Style;
 
 /**
  * A resource that provides access to the style.
  */
-@Singleton
[email protected]("/")
 public class StyleResource {
 
   private final Supplier<Style> styleSupplier;
 
-  @Inject
   public StyleResource(Supplier<Style> styleSupplier) {
     this.styleSupplier = styleSupplier;
   }
 
-  @GET
-  @javax.ws.rs.Path("style.json")
-  @Produces(MediaType.APPLICATION_JSON)
+  @Get("/style.json")
+  @ProducesJson
   public Style getStyle() {
     return styleSupplier.get();
   }
diff --git 
a/baremaps-server/src/main/java/org/apache/baremaps/server/TileJSONResource.java
 
b/baremaps-server/src/main/java/org/apache/baremaps/server/TileJSONResource.java
index 396328c8..321a0f31 100644
--- 
a/baremaps-server/src/main/java/org/apache/baremaps/server/TileJSONResource.java
+++ 
b/baremaps-server/src/main/java/org/apache/baremaps/server/TileJSONResource.java
@@ -17,31 +17,24 @@
 
 package org.apache.baremaps.server;
 
+import com.linecorp.armeria.server.annotation.Get;
+import com.linecorp.armeria.server.annotation.ProducesJson;
 import java.util.function.Supplier;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.ws.rs.GET;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
 import org.apache.baremaps.vectortile.tilejson.TileJSON;
 
 /**
  * A resource that provides access to the tileJSON file.
  */
-@Singleton
[email protected]("/")
 public class TileJSONResource {
 
   private final Supplier<TileJSON> tileJSONSupplier;
 
-  @Inject
   public TileJSONResource(Supplier<TileJSON> tileJSONSupplier) {
     this.tileJSONSupplier = tileJSONSupplier;
   }
 
-  @GET
-  @javax.ws.rs.Path("tiles.json")
-  @Produces(MediaType.APPLICATION_JSON)
+  @Get("/tiles.json")
+  @ProducesJson
   public TileJSON getTileset() {
     return tileJSONSupplier.get();
   }
diff --git 
a/baremaps-server/src/main/java/org/apache/baremaps/server/TileResource.java 
b/baremaps-server/src/main/java/org/apache/baremaps/server/TileResource.java
index bb074b94..964ac158 100644
--- a/baremaps-server/src/main/java/org/apache/baremaps/server/TileResource.java
+++ b/baremaps-server/src/main/java/org/apache/baremaps/server/TileResource.java
@@ -19,13 +19,14 @@ package org.apache.baremaps.server;
 
 import static com.google.common.net.HttpHeaders.*;
 
+import com.linecorp.armeria.common.HttpData;
+import com.linecorp.armeria.common.HttpResponse;
+import com.linecorp.armeria.common.ResponseHeaders;
+import com.linecorp.armeria.server.annotation.Blocking;
+import com.linecorp.armeria.server.annotation.Get;
+import com.linecorp.armeria.server.annotation.Param;
 import java.nio.ByteBuffer;
 import java.util.function.Supplier;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.ws.rs.GET;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.core.Response;
 import org.apache.baremaps.tilestore.TileCoord;
 import org.apache.baremaps.tilestore.TileStore;
 import org.apache.baremaps.tilestore.TileStoreException;
@@ -35,8 +36,6 @@ import org.slf4j.LoggerFactory;
 /**
  * A resource that provides access to the tiles.
  */
-@Singleton
[email protected]("/")
 public class TileResource {
 
   private static final Logger logger = 
LoggerFactory.getLogger(TileResource.class);
@@ -47,33 +46,34 @@ public class TileResource {
 
   private final Supplier<TileStore> tileStoreSupplier;
 
-  @Inject
   public TileResource(Supplier<TileStore> tileStoreSupplier) {
     this.tileStoreSupplier = tileStoreSupplier;
   }
 
-  @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) {
+  @Get("regex:^/tiles/(?<z>[0-9]+)/(?<x>[0-9]+)/(?<y>[0-9]+).mvt$")
+  @Blocking
+  public HttpResponse tile(@Param("z") int z, @Param("x") int x, @Param("y") 
int y) {
     TileCoord tileCoord = new TileCoord(x, y, z);
     try {
       TileStore tileStore = tileStoreSupplier.get();
       ByteBuffer blob = tileStore.read(tileCoord);
       if (blob != null) {
+        var headers = ResponseHeaders.builder(200)
+            .add(CONTENT_TYPE, TILE_TYPE)
+            .add(CONTENT_ENCODING, TILE_ENCODING)
+            .add(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
+            .build();
         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();
+        HttpData data = HttpData.wrap(bytes);
+        return HttpResponse.of(headers, data);
+
       } else {
-        return Response.status(204).build();
+        return HttpResponse.of(204);
       }
     } catch (TileStoreException ex) {
       logger.error("Error while reading tile.", ex);
-      return Response.status(404).build();
+      return HttpResponse.of(404);
     }
   }
 
diff --git 
a/baremaps-server/src/main/java/org/apache/baremaps/server/TilesetResource.java 
b/baremaps-server/src/main/java/org/apache/baremaps/server/TilesetResource.java
index d2434b84..eb317ad9 100644
--- 
a/baremaps-server/src/main/java/org/apache/baremaps/server/TilesetResource.java
+++ 
b/baremaps-server/src/main/java/org/apache/baremaps/server/TilesetResource.java
@@ -17,32 +17,25 @@
 
 package org.apache.baremaps.server;
 
+import com.linecorp.armeria.server.annotation.Get;
+import com.linecorp.armeria.server.annotation.ProducesJson;
 import java.util.function.Supplier;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.ws.rs.GET;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
 import org.apache.baremaps.vectortile.tileset.Tileset;
 
 /**
  * A resource that provides access to the tileset file. Only suitable for 
development purposes, as
  * it exposes SQL queries.
  */
-@Singleton
[email protected]("/")
 public class TilesetResource {
 
   private final Supplier<Tileset> tilesetSupplier;
 
-  @Inject
   public TilesetResource(Supplier<Tileset> tilesetSupplier) {
     this.tilesetSupplier = tilesetSupplier;
   }
 
-  @GET
-  @javax.ws.rs.Path("tiles.json")
-  @Produces(MediaType.APPLICATION_JSON)
+  @Get("/tiles.json")
+  @ProducesJson
   public Tileset getTileset() {
     var tileset = tilesetSupplier.get();
     // Hide the database connection
diff --git a/pom.xml b/pom.xml
index 54a75195..2aa0e735 100644
--- a/pom.xml
+++ b/pom.xml
@@ -80,6 +80,7 @@ limitations under the License.
     <sonar.organization>apache</sonar.organization>
     <sonar.projectKey>apache_baremaps</sonar.projectKey>
     <version.lib.annotation-api>1.3.2</version.lib.annotation-api>
+    <version.lib.armeria>1.26.4</version.lib.armeria>
     <version.lib.awaitability>4.2.0</version.lib.awaitability>
     <version.lib.awssdk>2.21.5</version.lib.awssdk>
     <version.lib.caffeine>3.1.8</version.lib.caffeine>
@@ -180,6 +181,16 @@ limitations under the License.
         <artifactId>protobuf-java</artifactId>
         <version>${version.lib.protobuf}</version>
       </dependency>
+      <dependency>
+        <groupId>com.linecorp.armeria</groupId>
+        <artifactId>armeria</artifactId>
+        <version>${version.lib.armeria}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.linecorp.armeria</groupId>
+        <artifactId>armeria-reactor3</artifactId>
+        <version>${version.lib.armeria}</version>
+      </dependency>
       <dependency>
         <groupId>com.zaxxer</groupId>
         <artifactId>HikariCP</artifactId>

Reply via email to