vertx-greet/.gitignore | ●●●●● patch | view | raw | blame | history | |
vertx-greet/Dockerfile | ●●●●● patch | view | raw | blame | history | |
vertx-greet/README.adoc | ●●●●● patch | view | raw | blame | history | |
vertx-greet/pom.xml | ●●●●● patch | view | raw | blame | history | |
vertx-greet/src/main/java/io/vertx/greet/GreetMain.java | ●●●●● patch | view | raw | blame | history | |
vertx-greet/src/main/java/io/vertx/greet/GreetServer.java | ●●●●● patch | view | raw | blame | history |
vertx-greet/.gitignore
New file @@ -0,0 +1,87 @@ ############################## ## Java ############################## .mtj.tmp/ *.class *.jar *.war *.ear *.nar hs_err_pid* ############################## ## Maven ############################## target/ pom.xml.tag pom.xml.releaseBackup pom.xml.versionsBackup pom.xml.next pom.xml.bak release.properties dependency-reduced-pom.xml buildNumber.properties .mvn/timing.properties .mvn/wrapper/maven-wrapper.jar ############################## ## Gradle ############################## bin/ build/ .gradle .gradletasknamecache gradle-app.setting !gradle-wrapper.jar ############################## ## IntelliJ ############################## out/ .idea/ .idea_modules/ *.iml *.ipr *.iws ############################## ## Eclipse ############################## .settings/ bin/ tmp/ .metadata .classpath .project *.tmp *.bak *.swp *~.nib local.properties .loadpath .factorypath ############################## ## NetBeans ############################## nbproject/private/ build/ nbbuild/ dist/ nbdist/ nbactions.xml nb-configuration.xml ############################## ## Visual Studio Code ############################## .vscode/ ############################## ## OS X ############################## .DS_Store # Logs logs *.log vertx-greet/Dockerfile
New file @@ -0,0 +1,17 @@ FROM openjdk:8-jre-alpine ENV VERTICLE_FILE vertx-greet-3.9.0-fat.jar # Set the location of the verticles ENV VERTICLE_HOME /usr/verticles EXPOSE 8080 COPY target/$VERTICLE_FILE $VERTICLE_HOME/ # Launch the verticle WORKDIR $VERTICLE_HOME ENTRYPOINT ["sh", "-c"] CMD ["exec java -jar $VERTICLE_FILE"] vertx-greet/README.adoc
New file @@ -0,0 +1,61 @@ = Vert.x Greet service A simple Vert.x greeting service with the following features: * Configurable greeting message. * Request counter. * Basic rate limiting. In this example Vert.x is used embedded. I.e. we use the Vert.x APIs directly in our own classes rather than deploying the code in verticles. == How to run You can run or debug the example in your IDE by just right clicking the main class and run as.. or debug as... The pom.xml uses the Maven shade plugin to assemble the application and all it's dependencies into a single "fat" jar. To run with maven mvn compile exec:java To build a "fat jar" mvn package To run the fat jar: java -jar target/maven-simplest-3.9.0-fat.jar (You can take that jar and run it anywhere there is a Java 8+ JDK. It contains all the dependencies it needs so you don't need to install Vert.x on the target machine). You can also run the fat jar with maven: mvn package exec:exec@run-app Now point your browser at http://localhost:8080 == Configuration The service uses two optional environment variables to control the greeting message and a very basic rate limiting feature: * GRETTING: defines the message returned when requesting the route `/`. If not specified, a default message is used. * MAX_REQUESTS_PER_SECOND: Indicates the number of requests per second that the service is able to handle. When a user surpasses this limit, the service returns 503 for each rate-limited request. Ignore this variable to deactivate the rate limit. == Container Image To publish the application as a container image in quay.io, first build the jar: mvn package Next, build the image: docker build -t quay.io/redhattraining/ossm-vertx-greet . Finally, push the image to quay: docker push quay.io/redhattraining/ossm-vertx-greet vertx-greet/pom.xml
New file @@ -0,0 +1,118 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>io.vertx</groupId> <artifactId>vertx-greet</artifactId> <version>3.9.0</version> <properties> <!-- the main class --> <exec.mainClass>io.vertx.greet.GreetMain</exec.mainClass> </properties> <dependencies> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-core</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-web</artifactId> <version>${project.version}</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <!-- We specify the Maven compiler plugin as we need to set it to Java 1.8 --> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </pluginManagement> <!-- You only need the part below if you want to build your application into a fat executable jar. This is a jar that contains all the dependencies required to run it, so you can just run it with java -jar --> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.3</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>${exec.mainClass}</Main-Class> </manifestEntries> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/services/io.vertx.core.spi.VerticleFactory</resource> </transformer> </transformers> <artifactSet> </artifactSet> <outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.4.0</version> <executions> <execution> <!-- run the application using the fat jar --> <id>run-app</id> <goals> <goal>exec</goal> </goals> <configuration> <executable>java</executable> <arguments> <argument>-jar</argument> <argument>target/${project.artifactId}-${project.version}-fat.jar</argument> </arguments> </configuration> </execution> </executions> </plugin> </plugins> </build> <profiles> <profile> <id>staging</id> <repositories> <repository> <id>staging</id> <url>https://oss.sonatype.org/content/repositories/iovertx-3868/</url> </repository> </repositories> </profile> </profiles> </project> vertx-greet/src/main/java/io/vertx/greet/GreetMain.java
New file @@ -0,0 +1,24 @@ package io.vertx.greet; import java.util.Optional; public class GreetMain { public static void main(String[] args) { String GREETING = Optional.ofNullable(System.getenv("GREETING")).orElse("Hello World!").trim(); String MAX_REQUESTS_PER_SECOND = Optional.ofNullable(System.getenv("MAX_REQUESTS_PER_SECOND")).orElse("0").trim(); if (!MAX_REQUESTS_PER_SECOND.equals("0")) { System.out.println("Service will limit requests to " + MAX_REQUESTS_PER_SECOND + " req/second"); } GreetServer server = new GreetServer( GREETING, Float.parseFloat(MAX_REQUESTS_PER_SECOND) ); server.start(); } } vertx-greet/src/main/java/io/vertx/greet/GreetServer.java
New file @@ -0,0 +1,61 @@ package io.vertx.greet; import java.time.Instant; import io.vertx.core.Vertx; import io.vertx.ext.web.Router; public class GreetServer { private int counter; private float maxRequestsPerSecond; private String greeting; private Instant lastRequestInstant; private Vertx vertx; GreetServer(String greeting, float maxRequestsPerSecond) { this.greeting = greeting; this.maxRequestsPerSecond = maxRequestsPerSecond; lastRequestInstant = Instant.MIN; vertx = Vertx.vertx(); } public void start() { vertx .createHttpServer() .requestHandler(defineRoutes()) .listen(8080); } private Router defineRoutes() { Router router = Router.router(vertx); router.get("/").handler(req -> { Instant now = Instant.now(); if (isRequestWithinRateLimits(now)) { req.response().end(greeting + "\n"); } else { req.response().setStatusCode(503).end(); } lastRequestInstant = now; counter++; }); router.get("/counter").handler(req -> req.response().end(counter + "\n") ); return router; } private boolean isRequestWithinRateLimits(Instant instant) { if (maxRequestsPerSecond == 0) { return true; } long millis = (long) (1000 / maxRequestsPerSecond); return lastRequestInstant.plusMillis(millis).isBefore(instant); } }