diff --git a/builds-applications/apps/vertx-site/README.adoc b/builds-applications/apps/vertx-site/README.adoc
new file mode 100644
index 0000000000..a7fd350329
--- /dev/null
+++ b/builds-applications/apps/vertx-site/README.adoc
@@ -0,0 +1,32 @@
+= Vertx-helloworld
+
+image:https://img.shields.io/badge/vert.x-4.4.4-purple.svg[link="https://vertx.io"]
+
+This application was generated using http://start.vertx.io
+
+== Building
+
+To launch your tests:
+```
+./mvnw clean test
+```
+
+To package your application:
+```
+./mvnw clean package
+```
+
+To run your application:
+```
+./mvnw clean compile exec:java
+```
+
+== Help
+
+* https://vertx.io/docs/[Vert.x Documentation]
+* https://stackoverflow.com/questions/tagged/vert.x?sort=newest&pageSize=15[Vert.x Stack Overflow]
+* https://groups.google.com/forum/?fromgroups#!forum/vertx[Vert.x User Group]
+* https://discord.gg/6ry7aqPWXy[Vert.x Discord]
+* https://gitter.im/eclipse-vertx/vertx-users[Vert.x Gitter]
+
+
diff --git a/builds-applications/apps/vertx-site/oc-new-app.sh b/builds-applications/apps/vertx-site/oc-new-app.sh
new file mode 100755
index 0000000000..9403e5bbc9
--- /dev/null
+++ b/builds-applications/apps/vertx-site/oc-new-app.sh
@@ -0,0 +1,7 @@
+#!/bin/env bash
+
+oc new-app --name vertx-site \
+ --build-env MAVEN_MIRROR_URL=http://nexus-infra.apps.ocp4.example.com/repository/java \
+ -i redhat-openjdk18-openshift:1.8 \
+ --context-dir builds-applications/apps/vertx-site \
+ https://git.ocp4.example.com/developer/DO288-apps
diff --git a/builds-applications/apps/vertx-site/pom.xml b/builds-applications/apps/vertx-site/pom.xml
new file mode 100644
index 0000000000..0a540f91d1
--- /dev/null
+++ b/builds-applications/apps/vertx-site/pom.xml
@@ -0,0 +1,116 @@
+
+
+ 4.0.0
+
+ com.redhat
+ vertx-site
+ 1.0.0-SNAPSHOT
+
+
+ UTF-8
+
+ 3.8.1
+ 3.2.4
+ 3.0.0-M5
+ 3.0.0
+
+ 4.4.4
+ 5.9.1
+
+ com.redhat.vertx_site.MainVerticle
+ io.vertx.core.Launcher
+
+
+
+
+
+ io.vertx
+ vertx-stack-depchain
+ ${vertx.version}
+ pom
+ import
+
+
+
+
+
+
+ io.vertx
+ vertx-core
+
+
+ io.vertx
+ vertx-web
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ io.vertx
+ vertx-unit
+ test
+
+
+
+
+
+
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+ 1.8
+ true
+
+
+
+ maven-shade-plugin
+ ${maven-shade-plugin.version}
+
+
+ package
+
+ shade
+
+
+
+
+
+ ${launcher.class}
+ ${main.verticle}
+
+
+
+
+ ${project.build.directory}/${project.artifactId}-${project.version}-fat.jar
+
+
+
+
+
+
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ ${exec-maven-plugin.version}
+
+ io.vertx.core.Launcher
+
+ run
+ ${main.verticle}
+
+
+
+
+
+
diff --git a/builds-applications/apps/vertx-site/src/main/java/com/redhat/vertx_site/MainVerticle.java b/builds-applications/apps/vertx-site/src/main/java/com/redhat/vertx_site/MainVerticle.java
new file mode 100644
index 0000000000..96c271c612
--- /dev/null
+++ b/builds-applications/apps/vertx-site/src/main/java/com/redhat/vertx_site/MainVerticle.java
@@ -0,0 +1,41 @@
+package com.redhat.vertx_site;
+
+import io.vertx.core.AbstractVerticle;
+import io.vertx.core.Vertx;
+import io.vertx.core.http.HttpServer;
+import io.vertx.core.http.HttpServerResponse;
+import io.vertx.ext.web.Router;
+import io.vertx.ext.web.RoutingContext;
+
+public class MainVerticle extends AbstractVerticle {
+
+ @Override
+ public void start() {
+ // Create an HTTP server
+ HttpServer server = vertx.createHttpServer();
+
+ // Create a router to handle the HTTP requests
+ Router router = Router.router(vertx);
+
+ // Define the route for the root path
+ router.get("/").handler(this::handleRoot);
+
+ // Start the server and listen on port 8080
+ server.requestHandler(router).listen(8080);
+ }
+
+ private void handleRoot(RoutingContext routingContext) {
+ HttpServerResponse response = routingContext.response();
+
+ // Set the content type header
+ response.putHeader("Content-Type", "text/html");
+
+ // Send HTML content as the response
+ response.end("
Welcome to your Vert.x v1.0 application!
");
+ }
+
+ public static void main(String[] args) {
+ Vertx vertx = Vertx.vertx();
+ vertx.deployVerticle(new MainVerticle());
+ }
+}
diff --git a/builds-applications/apps/vertx-site/src/test/java/com/redhat/tests/VertxSiteTest.java b/builds-applications/apps/vertx-site/src/test/java/com/redhat/tests/VertxSiteTest.java
new file mode 100644
index 0000000000..5c801044ed
--- /dev/null
+++ b/builds-applications/apps/vertx-site/src/test/java/com/redhat/tests/VertxSiteTest.java
@@ -0,0 +1,43 @@
+package com.redhat.tests;
+
+import com.redhat.vertx_site.MainVerticle;
+import io.vertx.core.Vertx;
+import io.vertx.core.http.HttpClient;
+import io.vertx.core.http.HttpClientResponse;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.ext.unit.TestContext;
+import io.vertx.ext.unit.junit.VertxUnitRunner;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@RunWith(VertxUnitRunner.class)
+public class VertxSiteTest {
+ private Vertx vertx;
+
+ @Before
+ public void setUp(TestContext context) {
+ vertx = Vertx.vertx();
+ vertx.deployVerticle(new MainVerticle(), context.asyncAssertSuccess());
+ }
+
+ @After
+ public void tearDown(TestContext context) {
+ vertx.close(context.asyncAssertSuccess());
+ }
+
+ @Test
+ public void testHomePage(TestContext context) {
+ final HttpClient client = vertx.createHttpClient();
+
+ client.request(HttpMethod.GET, 8080, "localhost", "/")
+ .compose(request -> request.send().compose(HttpClientResponse::body))
+ .onComplete(context.asyncAssertSuccess(buffer -> {
+ context.assertTrue(buffer.toString().contains("Welcome to your Vert.x"));
+ client.close();
+ }));
+ }
+
+}
diff --git a/builds-applications/solutions/oc-new-app.sh b/builds-applications/solutions/oc-new-app.sh
new file mode 100755
index 0000000000..42d8f0ac9e
--- /dev/null
+++ b/builds-applications/solutions/oc-new-app.sh
@@ -0,0 +1,8 @@
+#!/bin/env bash
+
+oc new-app --name vertx-site \
+ --build-env MAVEN_MIRROR_URL=http://nexus-infra.apps.ocp4.example.com/repository/java \
+ --env JAVA_APP_JAR=vertx-site-1.0.0-SNAPSHOT-fat.jar \
+ -i redhat-openjdk18-openshift:1.8 \
+ --context-dir builds-applications/apps/vertx-site \
+ https://git.ocp4.example.com/developer/DO288-apps
diff --git a/images-ubi/apps/greetings/.containerignore b/images-ubi/apps/greetings/.containerignore
new file mode 100644
index 0000000000..8d5b76ac06
--- /dev/null
+++ b/images-ubi/apps/greetings/.containerignore
@@ -0,0 +1,5 @@
+.git
+.npm
+.containerignore
+node_modules
+Containerfile
\ No newline at end of file
diff --git a/images-ubi/apps/greetings/Containerfile b/images-ubi/apps/greetings/Containerfile
new file mode 100644
index 0000000000..7cec2e323f
--- /dev/null
+++ b/images-ubi/apps/greetings/Containerfile
@@ -0,0 +1,12 @@
+FROM registry.ocp4.example.com:8443/ubi9/nodejs-18-minimal:1-51
+
+ENV PORT=80
+EXPOSE ${PORT}
+
+USER root
+
+ADD . $HOME
+
+RUN npm ci --omit=dev && rm -rf .npm
+
+CMD npm start
diff --git a/images-ubi/apps/greetings/LocalizationService.js b/images-ubi/apps/greetings/LocalizationService.js
new file mode 100644
index 0000000000..e0b10c72fc
--- /dev/null
+++ b/images-ubi/apps/greetings/LocalizationService.js
@@ -0,0 +1,93 @@
+/**
+ * Simulate an external localization service
+ */
+const fs = require("fs").promises;
+
+
+const TRANSLATIONS = {
+ "greeting": {
+ "de-de": "Guten tag",
+ "en-us": "Hi!",
+ "es-es": "Hola, ¿que tal?",
+ "fr-be": "Bonjour, ça va bien?",
+ "it-it": "Ciao, come stai?",
+ "ca": "Bon dia",
+ "pt-pt": "Olá, tudo bem?",
+ "hi": "Namaste",
+ "nl-nl": "Hallo",
+ "no-no": "Hei!",
+ "el": "Yassou",
+ "cs": "Ahoj!",
+ "pl": "Cześć!",
+ "sv-se": "Hej",
+ "ru": "Privet",
+ "tr": "Selam"
+ }
+}
+
+
+async function translate(key, locale) {
+ let translated;
+
+ try {
+ translated = await readFromFileCache(key, locale);
+ console.info(`${locale} '${key}' found in cache`);
+ } catch (error) {
+ // Only handle the not found case (ENOENT)
+ if (error.code !== "ENOENT") {
+ throw err;
+ }
+
+ translated = await getTranslationFromExternalService(key, locale);
+
+ await writeToFileCache(key, locale, translated);
+ }
+
+ return translated;
+}
+
+
+async function readFromFileCache(key, locale) {
+ const buffer = await fs.readFile(generateCacheFilename(key, locale));
+ return buffer.toString();
+}
+
+
+function writeToFileCache(key, locale, value) {
+ return fs.writeFile(generateCacheFilename(key, locale), value);
+}
+
+
+function generateCacheFilename(key, locale) {
+ return `/var/cache/translation_${key}_${locale}`;
+}
+
+
+function getTranslationFromExternalService(key, locale) {
+ // Simulate a network delay of 500 millis
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ const translated = TRANSLATIONS[key][locale];
+ resolve(translated);
+ }, 500);
+ });
+}
+
+
+function getSupportedLocaleIDs() {
+ return Object.keys(TRANSLATIONS.greeting);
+}
+
+
+function getRandomLocaleID() {
+ const locales = getSupportedLocaleIDs();
+ const localeIndex = Math.floor(Math.random() * locales.length);
+ return locales[localeIndex];
+}
+
+
+module.exports = {
+ translate,
+ getRandomLocaleID,
+ getSupportedLocaleIDs
+}
diff --git a/images-ubi/apps/greetings/index.js b/images-ubi/apps/greetings/index.js
new file mode 100644
index 0000000000..58e14a2f56
--- /dev/null
+++ b/images-ubi/apps/greetings/index.js
@@ -0,0 +1,41 @@
+const os = require("os");
+const http = require("http");
+const localization = require("./LocalizationService");
+
+
+const hostname = "0.0.0.0";
+const userInfo = os.userInfo();
+const port = process.env.PORT || 8080;
+
+
+main();
+
+
+async function main() {
+ console.info(`Running with user ID: ${userInfo.uid}, group ID: ${userInfo.gid}`);
+
+ console.info("Verifying file cache...");
+ try {
+ await localization.translate("greeting", "en-us");
+ } catch(error) {
+ console.error("File cache does not work due to", error);
+ }
+
+ console.info("Starting server...");
+ http
+ .createServer(handleRequest)
+ .listen(port, hostname, () => {
+ console.log(`Server listening at http://${hostname}:${port}/`);
+ });
+}
+
+
+async function handleRequest(req, res) {
+ // Return a greeting message in a random language
+ const locale = localization.getRandomLocaleID();
+ const message = await localization.translate("greeting", locale);
+
+ res.statusCode = 200;
+ res.setHeader("Content-Type", "application/json");
+ res.end(JSON.stringify({ message }));
+}
diff --git a/images-ubi/apps/greetings/package-lock.json b/images-ubi/apps/greetings/package-lock.json
new file mode 100644
index 0000000000..6bc64955bf
--- /dev/null
+++ b/images-ubi/apps/greetings/package-lock.json
@@ -0,0 +1,12 @@
+{
+ "name": "greetings",
+ "version": "1.0.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "greetings",
+ "version": "1.0.0"
+ }
+ }
+}
diff --git a/images-ubi/apps/greetings/package.json b/images-ubi/apps/greetings/package.json
new file mode 100644
index 0000000000..eea36bbf46
--- /dev/null
+++ b/images-ubi/apps/greetings/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "greetings",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "start": "node index.js",
+ "test": "echo \"Error: no test specified\" && exit 1"
+ }
+}
diff --git a/images-ubi/solutions/greetings/Containerfile b/images-ubi/solutions/greetings/Containerfile
new file mode 100644
index 0000000000..4c5b2e0c2d
--- /dev/null
+++ b/images-ubi/solutions/greetings/Containerfile
@@ -0,0 +1,20 @@
+FROM registry.ocp4.example.com:8443/ubi9/nodejs-18-minimal:1-51
+
+# Application listens on this port
+ENV PORT=8080
+EXPOSE ${PORT}
+
+# Copy the application source code
+ADD . $HOME
+
+# Install application dependencies and clean up
+RUN npm ci --omit=dev && rm -rf .npm
+
+# Fix permissions to write to /var/cache
+USER root
+RUN chgrp -R 0 /var/cache && \
+ chmod -R g=u /var/cache
+USER 1001
+
+# Run the server
+CMD npm start
diff --git a/nodejs-helloworld/package.json b/nodejs-helloworld/package.json
index 338e1f7ead..29b13f406d 100644
--- a/nodejs-helloworld/package.json
+++ b/nodejs-helloworld/package.json
@@ -9,6 +9,6 @@
"author": "Red Hat Training",
"license": "ASL",
"dependencies": {
- "express" "4.14.x"
+ "express": "4.14.x"
}
}
diff --git a/quip/pom.xml b/quip/pom.xml
index 452cf93ebb..701b67fae3 100644
--- a/quip/pom.xml
+++ b/quip/pom.xml
@@ -9,7 +9,7 @@
war
- 2.1.0.Final
+ 2.4.0.Final
1.8
1.8
false
diff --git a/ubi-echo/Dockerfile b/ubi-echo/Dockerfile
index 176078e5f5..0b28fb3c8b 100644
--- a/ubi-echo/Dockerfile
+++ b/ubi-echo/Dockerfile
@@ -1,3 +1,3 @@
FROM registry.access.redhat.com/ubi8/ubi:8.0
USER 1001
-CMD bash -c "while true; do echo test; sleep 5; done"
+CMD bash -c "while true; do (( i++ )); echo test \$i; sleep 5; done"