Marek Czernek
2020-04-23 542955739d8461cb59963c33c2d7dea90e33e1e5
Add source code for application used in Chapter 8 (and others) (#7)

27 files added
846 ■■■■■ changed files
customer/quarkus/.dockerignore 4 ●●●● patch | view | raw | blame | history
customer/quarkus/pom.xml 129 ●●●●● patch | view | raw | blame | history
customer/quarkus/src/main/docker/Dockerfile.jvm 11 ●●●●● patch | view | raw | blame | history
customer/quarkus/src/main/docker/Dockerfile.native 11 ●●●●● patch | view | raw | blame | history
customer/quarkus/src/main/java/com/redhat/developer/demos/customer/rest/BaggageHeadersFactory.java 33 ●●●●● patch | view | raw | blame | history
customer/quarkus/src/main/java/com/redhat/developer/demos/customer/rest/CustomerResource.java 47 ●●●●● patch | view | raw | blame | history
customer/quarkus/src/main/java/com/redhat/developer/demos/customer/rest/PreferenceService.java 19 ●●●●● patch | view | raw | blame | history
customer/quarkus/src/main/resources/application.properties 1 ●●●● patch | view | raw | blame | history
customer/quarkus/src/test/java/com/redhat/developer/demos/customer/rest/CustomerResourceTest.java 22 ●●●●● patch | view | raw | blame | history
customer/quarkus/src/test/java/com/redhat/developer/demos/customer/rest/NativeCustomerResourceIT.java 9 ●●●●● patch | view | raw | blame | history
preference/quarkus/.dockerignore 4 ●●●● patch | view | raw | blame | history
preference/quarkus/pom.xml 129 ●●●●● patch | view | raw | blame | history
preference/quarkus/src/main/docker/Dockerfile.jvm 11 ●●●●● patch | view | raw | blame | history
preference/quarkus/src/main/docker/Dockerfile.native 11 ●●●●● patch | view | raw | blame | history
preference/quarkus/src/main/java/com/redhat/developer/demos/preference/rest/BaggageHeadersFactory.java 31 ●●●●● patch | view | raw | blame | history
preference/quarkus/src/main/java/com/redhat/developer/demos/preference/rest/PreferenceResource.java 44 ●●●●● patch | view | raw | blame | history
preference/quarkus/src/main/java/com/redhat/developer/demos/preference/rest/RecommendationService.java 19 ●●●●● patch | view | raw | blame | history
preference/quarkus/src/main/resources/application.properties 2 ●●●●● patch | view | raw | blame | history
preference/quarkus/src/test/java/com/redhat/developer/demos/preference/rest/NativePreferenceResourceIT.java 9 ●●●●● patch | view | raw | blame | history
preference/quarkus/src/test/java/com/redhat/developer/demos/preference/rest/PreferenceResourceTest.java 21 ●●●●● patch | view | raw | blame | history
recommendation/quarkus/.dockerignore 4 ●●●● patch | view | raw | blame | history
recommendation/quarkus/pom.xml 132 ●●●●● patch | view | raw | blame | history
recommendation/quarkus/src/main/docker/Dockerfile.jvm 11 ●●●●● patch | view | raw | blame | history
recommendation/quarkus/src/main/docker/Dockerfile.native 11 ●●●●● patch | view | raw | blame | history
recommendation/quarkus/src/main/java/com/redhat/developer/demos/recommendation/rest/RecommendationResource.java 91 ●●●●● patch | view | raw | blame | history
recommendation/quarkus/src/test/java/com/redhat/developer/demos/recommendation/rest/NativeRecommendationResourceIT.java 9 ●●●●● patch | view | raw | blame | history
recommendation/quarkus/src/test/java/com/redhat/developer/demos/recommendation/rest/RecommendationResourceTest.java 21 ●●●●● patch | view | raw | blame | history
customer/quarkus/.dockerignore
New file
@@ -0,0 +1,4 @@
*
!target/*-runner
!target/*-runner.jar
!target/lib/*
customer/quarkus/pom.xml
New file
@@ -0,0 +1,129 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.redhat.developer.demos.customer.rest</groupId>
  <artifactId>customer</artifactId>
  <version>1.0-SNAPSHOT</version>
  <properties>
    <surefire-plugin.version>2.22.0</surefire-plugin.version>
    <quarkus.version>1.1.0.Final</quarkus.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-bom</artifactId>
        <version>${quarkus.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-rest-client</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-opentracing</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-health</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-metrics</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>build</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <configuration>
          <systemProperties>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
          </systemProperties>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>native</id>
      <activation>
        <property>
          <name>native</name>
        </property>
      </activation>
      <build>
        <plugins>
          <plugin>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-maven-plugin</artifactId>
            <version>${quarkus.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>native-image</goal>
                </goals>
                <configuration>
                  <enableHttpUrlHandler>true</enableHttpUrlHandler>
                </configuration>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>${surefire-plugin.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
                </goals>
                <configuration>
                  <systemProperties>
                    <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                  </systemProperties>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>
customer/quarkus/src/main/docker/Dockerfile.jvm
New file
@@ -0,0 +1,11 @@
FROM fabric8/java-jboss-openjdk8-jdk:1.5.4
ENV JAVA_OPTIONS=-Dquarkus.http.host=0.0.0.0
ENV JAEGER_SERVICE_NAME=customer\
  JAEGER_ENDPOINT=http://jaeger-collector.istio-system.svc:14268/api/traces\
  JAEGER_PROPAGATION=b3\
  JAEGER_SAMPLER_TYPE=const\
  JAEGER_SAMPLER_PARAM=1
EXPOSE 8080 8778 9779
COPY target/lib/* /deployments/lib/
COPY target/*-runner.jar /deployments/app.jar
ENTRYPOINT [ "/deployments/run-java.sh" ]
customer/quarkus/src/main/docker/Dockerfile.native
New file
@@ -0,0 +1,11 @@
FROM registry.access.redhat.com/ubi8/ubi-minimal
ENV JAEGER_SERVICE_NAME=customer\
  JAEGER_ENDPOINT=http://jaeger-collector.istio-system.svc:14268/api/traces\
  JAEGER_PROPAGATION=b3\
  JAEGER_SAMPLER_TYPE=const\
  JAEGER_SAMPLER_PARAM=1
WORKDIR /work/
COPY target/*-runner /work/customer
RUN chmod 775 /work
EXPOSE 8080 8778 9779
CMD ["./customer", "-Dquarkus.http.host=0.0.0.0", "-Xmx8m", "-Xmn8m", "-Xms8m"]
customer/quarkus/src/main/java/com/redhat/developer/demos/customer/rest/BaggageHeadersFactory.java
New file
@@ -0,0 +1,33 @@
package com.redhat.developer.demos.customer.rest;
import org.eclipse.microprofile.rest.client.ext.ClientHeadersFactory;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public class BaggageHeadersFactory implements ClientHeadersFactory {
    @Override
    public MultivaluedMap<String, String> update(MultivaluedMap<String, String> incomingHeaders, MultivaluedMap<String, String> clientOutgoingHeaders) {
        MultivaluedHashMap<String, String> headers = new MultivaluedHashMap<>();
        String userAgent = incomingHeaders.getFirst("user-agent");
        headers.putSingle("baggage-user-agent", userAgent);
        String authorization = incomingHeaders.getFirst("Authorization");
        if (authorization != null) {
            headers.putSingle("Authorization", authorization);
        }
        String userPreference = incomingHeaders.getFirst("user-preference");
        if (userPreference != null) {
            headers.putSingle("user-preference", userPreference);
        }
        return headers;
    }
}
customer/quarkus/src/main/java/com/redhat/developer/demos/customer/rest/CustomerResource.java
New file
@@ -0,0 +1,47 @@
package com.redhat.developer.demos.customer.rest;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("/")
public class CustomerResource {
    private static final String RESPONSE_STRING_FORMAT = "customer => %s\n";
    private final Logger logger = LoggerFactory.getLogger(getClass());
    @Inject
    @RestClient
    PreferenceService preferenceService;
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Response getCustomer() {
        try {
            String response = preferenceService.getPreference().trim();
            return Response.ok(String.format(RESPONSE_STRING_FORMAT, response)).build();
        } catch (WebApplicationException ex) {
            Response response = ex.getResponse();
            logger.warn("Non HTTP 20x trying to get the response from preference service: " + response.getStatus());
            return Response
                    .status(Response.Status.SERVICE_UNAVAILABLE)
                    .entity(String.format(RESPONSE_STRING_FORMAT,
                            String.format("Error: %d - %s", response.getStatus(), response.readEntity(String.class)))
                    )
                    .build();
        } catch (ProcessingException ex) {
            logger.warn("Exception trying to get the response from preference service.", ex);
            return Response
                    .status(Response.Status.SERVICE_UNAVAILABLE)
                    .entity(String.format(RESPONSE_STRING_FORMAT, ex.getCause().getClass().getSimpleName() + ": " + ex.getCause().getMessage()))
                    .build();
        }
    }
}
customer/quarkus/src/main/java/com/redhat/developer/demos/customer/rest/PreferenceService.java
New file
@@ -0,0 +1,19 @@
package com.redhat.developer.demos.customer.rest;
import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@RegisterClientHeaders(BaggageHeadersFactory.class)
@RegisterRestClient
public interface PreferenceService {
    @Path("/")
    @GET
    @Produces("text/plain")
    public String getPreference();
}
customer/quarkus/src/main/resources/application.properties
New file
@@ -0,0 +1 @@
com.redhat.developer.demos.customer.rest.PreferenceService/mp-rest/url=http://preference:8080
customer/quarkus/src/test/java/com/redhat/developer/demos/customer/rest/CustomerResourceTest.java
New file
@@ -0,0 +1,22 @@
package com.redhat.developer.demos.customer.rest;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.startsWith;
@QuarkusTest
public class CustomerResourceTest {
    @Test
    public void testHelloEndpoint() {
        given()
          .when().get("/")
          .then()
             .statusCode(503)
             .body(startsWith("customer =>"));
    }
}
customer/quarkus/src/test/java/com/redhat/developer/demos/customer/rest/NativeCustomerResourceIT.java
New file
@@ -0,0 +1,9 @@
package com.redhat.developer.demos.customer.rest;
import io.quarkus.test.junit.NativeImageTest;
@NativeImageTest
public class NativeCustomerResourceIT extends CustomerResourceTest {
    // Execute the same tests but in native mode.
}
preference/quarkus/.dockerignore
New file
@@ -0,0 +1,4 @@
*
!target/*-runner
!target/*-runner.jar
!target/lib/*
preference/quarkus/pom.xml
New file
@@ -0,0 +1,129 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.redhat.developer.demos.preference.rest</groupId>
  <artifactId>preference</artifactId>
  <version>1.0-SNAPSHOT</version>
  <properties>
    <surefire-plugin.version>2.22.0</surefire-plugin.version>
    <quarkus.version>1.1.0.Final</quarkus.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-bom</artifactId>
        <version>${quarkus.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-rest-client</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-opentracing</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-health</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-metrics</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>build</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <configuration>
          <systemProperties>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
          </systemProperties>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>native</id>
      <activation>
        <property>
          <name>native</name>
        </property>
      </activation>
      <build>
        <plugins>
          <plugin>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-maven-plugin</artifactId>
            <version>${quarkus.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>native-image</goal>
                </goals>
                <configuration>
                  <enableHttpUrlHandler>true</enableHttpUrlHandler>
                </configuration>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>${surefire-plugin.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
                </goals>
                <configuration>
                  <systemProperties>
                    <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                  </systemProperties>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>
preference/quarkus/src/main/docker/Dockerfile.jvm
New file
@@ -0,0 +1,11 @@
FROM fabric8/java-jboss-openjdk8-jdk:1.5.4
ENV JAVA_OPTIONS=-Dquarkus.http.host=0.0.0.0
ENV JAEGER_SERVICE_NAME=preference \
  JAEGER_ENDPOINT=http://jaeger-collector.istio-system.svc:14268/api/traces \
  JAEGER_PROPAGATION=b3 \
  JAEGER_SAMPLER_TYPE=const \
  JAEGER_SAMPLER_PARAM=1
EXPOSE 8080 8778 9779
COPY target/lib/* /deployments/lib/
COPY target/*-runner.jar /deployments/app.jar
ENTRYPOINT [ "/deployments/run-java.sh" ]
preference/quarkus/src/main/docker/Dockerfile.native
New file
@@ -0,0 +1,11 @@
FROM registry.access.redhat.com/ubi8/ubi-minimal
ENV JAEGER_SERVICE_NAME=preference\
  JAEGER_ENDPOINT=http://jaeger-collector.istio-system.svc:14268/api/traces\
  JAEGER_PROPAGATION=b3\
  JAEGER_SAMPLER_TYPE=const\
  JAEGER_SAMPLER_PARAM=1
WORKDIR /work/
COPY target/*-runner /work/preference
RUN chmod 775 /work
EXPOSE 8080 8778 9779
CMD ["./preference", "-Dquarkus.http.host=0.0.0.0", "-Xmx8m", "-Xmn8m", "-Xms8m"]
preference/quarkus/src/main/java/com/redhat/developer/demos/preference/rest/BaggageHeadersFactory.java
New file
@@ -0,0 +1,31 @@
package com.redhat.developer.demos.preference.rest;
import io.quarkus.runtime.annotations.RegisterForReflection;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import org.eclipse.microprofile.rest.client.ext.ClientHeadersFactory;
@RegisterForReflection
public class BaggageHeadersFactory implements ClientHeadersFactory {
    @Override
    public MultivaluedMap<String, String> update(MultivaluedMap<String, String> incomingHeaders, MultivaluedMap<String, String> clientOutgoingHeaders) {
        MultivaluedHashMap<String, String> headers = new MultivaluedHashMap<>();
        String userAgent = incomingHeaders.getFirst("baggage-user-agent");
        headers.putSingle("baggage-user-agent", userAgent);
        String authorization = incomingHeaders.getFirst("Authorization");
        if (authorization != null) {
            headers.putSingle("Authorization", authorization);
        }
        String userPreference = incomingHeaders.getFirst("user-preference");
        if (userPreference != null) {
            headers.putSingle("user-preference", userPreference);
        }
        return headers;
    }
}
preference/quarkus/src/main/java/com/redhat/developer/demos/preference/rest/PreferenceResource.java
New file
@@ -0,0 +1,44 @@
package com.redhat.developer.demos.preference.rest;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("/")
public class PreferenceResource {
    private static final String RESPONSE_STRING_FORMAT = "preference => %s\n";
    private final Logger logger = LoggerFactory.getLogger(getClass());
    @Inject
    @RestClient
    RecommendationService recommendationService;
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Response getPreference() {
        try {
            String response = recommendationService.getRecommendation();
            return Response.ok(String.format(RESPONSE_STRING_FORMAT, response)).build();
        } catch (WebApplicationException ex) {
            Response response = ex.getResponse();
            logger.warn("Non HTTP 20x trying to get the response from recommendation service: " + response.getStatus());
            ex.printStackTrace();
            return Response.status(Response.Status.SERVICE_UNAVAILABLE)
                    .entity(String.format(RESPONSE_STRING_FORMAT,
                            String.format("Error: %d - %s", response.getStatus(), response.readEntity(String.class))))
                    .build();
        } catch (ProcessingException ex) {
            logger.warn("Exception trying to get the response from recommendation service.", ex);
            return Response.status(Response.Status.SERVICE_UNAVAILABLE).entity(String.format(RESPONSE_STRING_FORMAT,
                    ex.getCause().getClass().getSimpleName() + ": " + ex.getCause().getMessage())).build();
        }
    }
}
preference/quarkus/src/main/java/com/redhat/developer/demos/preference/rest/RecommendationService.java
New file
@@ -0,0 +1,19 @@
package com.redhat.developer.demos.preference.rest;
import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@RegisterClientHeaders(BaggageHeadersFactory.class)
@RegisterRestClient
public interface RecommendationService {
    @Path("/")
    @GET
    @Produces("text/plain")
    public String getRecommendation();
}
preference/quarkus/src/main/resources/application.properties
New file
@@ -0,0 +1,2 @@
org.eclipse.microprofile.rest.client.propagateHeaders=baggage-user-agent
com.redhat.developer.demos.preference.rest.RecommendationService/mp-rest/url=http://recommendation:8080
preference/quarkus/src/test/java/com/redhat/developer/demos/preference/rest/NativePreferenceResourceIT.java
New file
@@ -0,0 +1,9 @@
package com.redhat.developer.demos.preference.rest;
import io.quarkus.test.junit.NativeImageTest;
@NativeImageTest
public class NativePreferenceResourceIT extends PreferenceResourceTest {
    // Execute the same tests but in native mode.
}
preference/quarkus/src/test/java/com/redhat/developer/demos/preference/rest/PreferenceResourceTest.java
New file
@@ -0,0 +1,21 @@
package com.redhat.developer.demos.preference.rest;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.startsWith;
@QuarkusTest
public class PreferenceResourceTest {
    @Test
    public void testHelloEndpoint() {
        given()
          .when().get("/")
          .then()
             .statusCode(503)
             .body(startsWith("preference =>"));
    }
}
recommendation/quarkus/.dockerignore
New file
@@ -0,0 +1,4 @@
*
!target/*-runner
!target/*-runner.jar
!target/lib/*
recommendation/quarkus/pom.xml
New file
@@ -0,0 +1,132 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.redhat.developers</groupId>
  <artifactId>recommendation</artifactId>
  <version>1.0-SNAPSHOT</version>
  <properties>
    <surefire-plugin.version>2.22.0</surefire-plugin.version>
    <quarkus.version>1.1.0.Final</quarkus.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-bom</artifactId>
        <version>${quarkus.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-rest-client</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-arc</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
    </dependency>
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-health</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-metrics</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-opentracing</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>build</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <configuration>
          <systemProperties>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
          </systemProperties>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>native</id>
      <activation>
        <property>
          <name>native</name>
        </property>
      </activation>
      <build>
        <plugins>
          <plugin>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-maven-plugin</artifactId>
            <version>${quarkus.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>native-image</goal>
                </goals>
                <configuration>
                  <enableHttpUrlHandler>true</enableHttpUrlHandler>
                </configuration>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>${surefire-plugin.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
                </goals>
                <configuration>
                  <systemProperties>
                    <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                  </systemProperties>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>
recommendation/quarkus/src/main/docker/Dockerfile.jvm
New file
@@ -0,0 +1,11 @@
FROM fabric8/java-jboss-openjdk8-jdk:1.5.4
ENV JAVA_OPTIONS=-Dquarkus.http.host=0.0.0.0
ENV JAEGER_SERVICE_NAME=recommendation \
  JAEGER_ENDPOINT=http://jaeger-collector.istio-system.svc:14268/api/traces \
  JAEGER_PROPAGATION=b3 \
  JAEGER_SAMPLER_TYPE=const \
  JAEGER_SAMPLER_PARAM=1
EXPOSE 8080 8778 9779
COPY target/lib/* /deployments/lib/
COPY target/*-runner.jar /deployments/app.jar
ENTRYPOINT [ "/deployments/run-java.sh" ]
recommendation/quarkus/src/main/docker/Dockerfile.native
New file
@@ -0,0 +1,11 @@
FROM registry.access.redhat.com/ubi8/ubi-minimal
ENV JAEGER_SERVICE_NAME=recommendation\
  JAEGER_ENDPOINT=http://jaeger-collector.istio-system.svc:14268/api/traces\
  JAEGER_PROPAGATION=b3\
  JAEGER_SAMPLER_TYPE=const\
  JAEGER_SAMPLER_PARAM=1
WORKDIR /work/
COPY target/*-runner /work/recommendation
RUN chmod 775 /work
EXPOSE 8080 8778 9779
CMD ["./recommendation", "-Dquarkus.http.host=0.0.0.0", "-Xmx8m", "-Xmn8m", "-Xms8m"]
recommendation/quarkus/src/main/java/com/redhat/developer/demos/recommendation/rest/RecommendationResource.java
New file
@@ -0,0 +1,91 @@
package com.redhat.developer.demos.recommendation.rest;
import java.io.ByteArrayInputStream;
import javax.json.Json;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import org.jboss.logging.Logger;
@Path("/")
public class RecommendationResource {
    private static final String RESPONSE_STRING_FORMAT = "recommendation v1 from '%s': %d\n";
    private static final String RESPONSE_STRING_NOW_FORMAT = "recommendation v3 %s from '%s': %d\n";
    private final Logger logger = Logger.getLogger(getClass());
    /**
     * Counter to help us see the lifecycle
     */
    private int count = 0;
    /**
     * Flag for throwing a 503 when enabled
     */
    private boolean misbehave = false;
    private static final String HOSTNAME = parseContainerIdFromHostname(
            System.getenv().getOrDefault("HOSTNAME", "unknown"));
    static String parseContainerIdFromHostname(String hostname) {
        return hostname.replaceAll("recommendation-v\\d+-", "");
    }
    @GET
    public Response getRecommendations() {
        count++;
        logger.info(String.format("recommendation request from %s: %d", HOSTNAME, count));
        // timeout();
        logger.debug("recommendation service ready to return");
        if (misbehave) {
            return doMisbehavior();
        }
        return Response.ok(String.format(RESPONSE_STRING_FORMAT, HOSTNAME, count)).build();
        // return Response.ok(String.format(RESPONSE_STRING_NOW_FORMAT, getNow(), HOSTNAME, count)).build();
    }
    private void timeout() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            logger.info("Thread interrupted");
        }
    }
    private Response doMisbehavior() {
        logger.debug(String.format("Misbehaving %d", count));
        return Response.status(Response.Status.SERVICE_UNAVAILABLE)
                .entity(String.format("recommendation misbehavior from '%s'\n", HOSTNAME)).build();
    }
    @GET
    @Path("/misbehave")
    public Response flagMisbehave() {
        this.misbehave = true;
        logger.debug("'misbehave' has been set to 'true'");
        return Response.ok("Following requests to / will return a 503\n").build();
    }
    @GET
    @Path("/behave")
    public Response flagBehave() {
        this.misbehave = false;
        logger.debug("'misbehave' has been set to 'false'");
        return Response.ok("Following requests to / will return 200\n").build();
    }
    private String getNow() {
        final Client client = ClientBuilder.newClient();
        final Response res = client.target("http://worldclockapi.com/api/json/cet/now").request().get();
        final String jsonObject = res.readEntity(String.class);
        return Json.createReader(new ByteArrayInputStream(jsonObject.getBytes())).readObject().getString("currentDateTime");
    }
}
recommendation/quarkus/src/test/java/com/redhat/developer/demos/recommendation/rest/NativeRecommendationResourceIT.java
New file
@@ -0,0 +1,9 @@
package com.redhat.developer.demos.recommendation.rest;
import io.quarkus.test.junit.NativeImageTest;
@NativeImageTest
public class NativeRecommendationResourceIT extends RecommendationResourceTest {
    // Execute the same tests but in native mode.
}
recommendation/quarkus/src/test/java/com/redhat/developer/demos/recommendation/rest/RecommendationResourceTest.java
New file
@@ -0,0 +1,21 @@
package com.redhat.developer.demos.recommendation.rest;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.startsWith;
@QuarkusTest
public class RecommendationResourceTest {
    @Test
    public void testHelloEndpoint() {
        given()
          .when().get("/")
          .then()
             .statusCode(200)
             .body(startsWith("recommendation"));
    }
}