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 2024/01/14 22:44:21 UTC
(incubator-baremaps) 01/02: Enable armeria in dev mode
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 <bc...@gmail.com>
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
-@javax.ws.rs.Path("/")
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
-@javax.ws.rs.Path("/")
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
-@javax.ws.rs.Path("/")
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
-@javax.ws.rs.Path("/")
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
-@javax.ws.rs.Path("/")
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>