Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kie-tools#2695: [SonataFlow Management Console Image] Use mod_proxy to proxy request to the data-index #2750

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ packages/scesim-marshaller/**/ts-gen
!packages/sonataflow-image-common/test-resources/
!packages/sonataflow-builder-image/test-resources/
!packages/sonataflow-devmode-image/test-resources/
!packages/sonataflow-management-console-image/test-resources/
fantonangeli marked this conversation as resolved.
Show resolved Hide resolved

# kogito-images: excluding test-resources
!packages/kogito-data-index-ephemeral-image/test-resources/
Expand Down
12 changes: 12 additions & 0 deletions packages/sonataflow-dev-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ To run the development app, use the following command:

`pnpm start`

# Configuration

The `SonataFlow Dev App` can be configured via environment variables:

- _SONATAFLOW_DEV_APP_DELAY_: Defines the server's response delay in milliseconds

For example:

```bash
$ export SONATAFLOW_DEV_APP_DELAY=500
```

### GraphQL Modifications

This section covers modifications to the GraphQL database.
Expand Down
4 changes: 2 additions & 2 deletions packages/sonataflow-dev-app/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const data = require("./MockData/graphql");
const controller = require("./MockData/controllers");
const typeDefs = require("./MockData/types");

const DEFAULT_TIMEOUT = 2000;
const DEFAULT_DELAY = Number(process.env.SONATAFLOW_DEV_APP_DELAY || 2000);

const swaggerOptions = {
swaggerOptions: {
Expand Down Expand Up @@ -96,7 +96,7 @@ app.post("/forms/:formName", controller.saveFormContent);

app.post(/^\/(service|hello|systout|jsongreet|order|yamlgreet)$/, controller.startProcessInstance);

function timeout(ms = DEFAULT_TIMEOUT) {
function timeout(ms = DEFAULT_DELAY) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

Expand Down
19 changes: 19 additions & 0 deletions packages/sonataflow-management-console-image/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,25 @@ The port used internally on the container can be changed:

When building, set the `SONATAFLOW_MANAGEMENT_CONSOLE__port` environment variable to any port you want, and the Containerfile will be built using that port.

## Run the Docker Image Locally

1. This command will start the container and configure it to access your local data-index service from the container.
Replace `<HOST_IP_ADDRESS>` with the IP address of your host machine.

```bash
docker run --rm -it -p 8080:8080 \
-e SONATAFLOW_MANAGEMENT_CONSOLE_KOGITO_ENV_MODE='DEV' \
-e SONATAFLOW_MANAGEMENT_CONSOLE_DATA_INDEX_ENDPOINT='http://<HOST_IP_ADDRESS>:4000/graphql' \
docker.io/apache/incubator-kie-sonataflow-management-console:main
```

2. In a separate terminal, start Sonataflow Dev App for the Data Index service.

```bash
cd ../sonataflow-dev-app
pnpm start
```

---

Apache KIE (incubating) is an effort undergoing incubation at The Apache Software
Expand Down
9 changes: 7 additions & 2 deletions packages/sonataflow-management-console-image/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
},
"scripts": {
"build:dev": "pnpm cleanup && pnpm env-json:schema:generate && pnpm copy:assets && run-script-if --bool \"$(build-env containerImages.build)\" --then \"pnpm image:cekit:build\"",
"build:prod": "pnpm cleanup && pnpm env-json:schema:generate && pnpm copy:assets && run-script-if --bool \"$(build-env containerImages.build)\" --then \"pnpm image:cekit:build\"",
"build:prod": "pnpm cleanup && pnpm env-json:schema:generate && pnpm copy:assets && run-script-if --bool \"$(build-env containerImages.build)\" --then \"pnpm image:cekit:build && pnpm image:test\"",
"cleanup": "rimraf dist-dev && mkdir dist-dev",
"copy:assets": "pnpm copy:webapp-assets && pnpm copy:image-env-to-json",
"copy:image-env-to-json": "run-script-os",
"copy:image-env-to-json:linux:darwin": "cp ./node_modules/@kie-tools/image-env-to-json/dist/linux/image-env-to-json-standalone ./dist-dev/",
"copy:image-env-to-json:win32": "pnpm powershell \"Copy-Item ./node_modules/@kie-tools/image-env-to-json/dist/linux/image-env-to-json-standalone ./dist-dev/\"",
"copy:test-assets": "run-script-os",
"copy:test-assets:linux:darwin": "cp -R test-resources/* dist-dev",
"copy:webapp-assets": "run-script-os",
"copy:webapp-assets:linux:darwin": "cp -R ./node_modules/@kie-tools/sonataflow-management-console-webapp/dist/ ./dist-dev/sonataflow-management-console-webapp",
"copy:webapp-assets:win32": "pnpm powershell \"Copy-Item -R ./node_modules/@kie-tools/sonataflow-management-console-webapp/dist/ ./dist-dev/sonataflow-management-console-webapp\"",
Expand All @@ -28,7 +30,10 @@
"image:cekit:build:linux": "pnpm image:cekit:copy && pnpm image:cekit:setup:env make -C ./dist-dev build",
"image:cekit:build:win32:darwin": "echo \"Build skipped on macOS and Windows\"",
"image:cekit:copy": "cp -R ./node_modules/@kie-tools/sonataflow-image-common/resources/* ./dist-dev/ && cp -R resources/* ./dist-dev/",
"image:cekit:setup:env": ". ./node_modules/@kie-tools/python-venv/venv/bin/activate && cross-env KOGITO_IMAGE_REGISTRY=$(build-env sonataflowManagementConsoleImageEnv.registry) KOGITO_IMAGE_REGISTRY_ACCOUNT=$(build-env sonataflowManagementConsoleImageEnv.account) KOGITO_IMAGE_NAME=$(build-env sonataflowManagementConsoleImageEnv.name) KOGITO_IMAGE_TAG=$(build-env sonataflowManagementConsoleImageEnv.buildTag) QUARKUS_PLATFORM_VERSION=$(build-env versions.quarkus) KOGITO_VERSION=$(build-env versions.kogito) SONATAFLOW_MANAGEMENT_CONSOLE_PORT=$(build-env sonataflowManagementConsoleImageEnv.port)"
"image:cekit:setup:env": ". ./node_modules/@kie-tools/python-venv/venv/bin/activate && cross-env KOGITO_IMAGE_REGISTRY=$(build-env sonataflowManagementConsoleImageEnv.registry) KOGITO_IMAGE_REGISTRY_ACCOUNT=$(build-env sonataflowManagementConsoleImageEnv.account) KOGITO_IMAGE_NAME=$(build-env sonataflowManagementConsoleImageEnv.name) KOGITO_IMAGE_TAG=$(build-env sonataflowManagementConsoleImageEnv.buildTag) QUARKUS_PLATFORM_VERSION=$(build-env versions.quarkus) KOGITO_VERSION=$(build-env versions.kogito) SONATAFLOW_MANAGEMENT_CONSOLE_PORT=$(build-env sonataflowManagementConsoleImageEnv.port)",
"image:test": "run-script-if --ignore-errors \"$(build-env tests.ignoreFailures)\" --bool \"$(build-env endToEndTests.run)\" --then \"mkdir -p dist-dev/target/test/results\" \"run-script-os\" --finally \"cp -R dist-dev/target/test/results dist-tests-e2e/\"",
"image:test:darwin:win32": "echo \"Tests skipped on macOS and Windows\"",
"image:test:linux": "pnpm copy:test-assets && pnpm image:cekit:setup:env SONATAFLOW_MANAGEMENT_CONSOLE_DATA_INDEX_ENDPOINT='http://$(hostname -I | awk '{print $1}'):4000/graphql' make -C ./dist-dev test-image"
ricardozanini marked this conversation as resolved.
Show resolved Hide resolved
},
"devDependencies": {
"@kie-tools/image-env-to-json": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# specific language governing permissions and limitations
# under the License.
#
- name: "docker.io/apache/incubator-kie-sonataflow-devmode"
- name: "docker.io/apache/incubator-kie-sonataflow-management-console"
from: "registry.access.redhat.com/ubi9/httpd-24:1-336.1725850633"
version: "0.0.0"
description: "SonataFlow Management Console Image"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,23 @@ sed -i "s/Listen 80/Listen ${SONATAFLOW_MANAGEMENT_CONSOLE_PORT}/g" "${HTTPD_MAI
sed -i "s/#ServerName www.example.com:80/ServerName 127.0.0.1:${SONATAFLOW_MANAGEMENT_CONSOLE_PORT}/g" "${HTTPD_MAIN_CONF_PATH}/httpd.conf"
sed -i '$ a ServerTokens Prod' "${HTTPD_MAIN_CONF_PATH}/httpd.conf"
sed -i '$ a ServerSignature Off' "${HTTPD_MAIN_CONF_PATH}/httpd.conf"
sed -i -e '/<Directory "\/var\/www\/html">/a RewriteEngine on\n RewriteCond %{REQUEST_FILENAME} -f [OR]\n RewriteCond %{REQUEST_FILENAME} -d\n RewriteRule ^ - [L]\n RewriteRule ^ index.html [L]' "${HTTPD_MAIN_CONF_PATH}/httpd.conf"
sed -i '$ a SSLProxyEngine on' "${HTTPD_MAIN_CONF_PATH}/httpd.conf"

# Add RewriteRules
sed -i -e '/<Directory "\/var\/www\/html">/a \
RewriteEngine on \
# Data Index rewrite rules \
RewriteCond %{REQUEST_URI} ^\/graphql([\/\?$]|$) \
RewriteCond %{ENV:SONATAFLOW_MANAGEMENT_CONSOLE_DATA_INDEX_ENDPOINT} ^$ \
RewriteRule ^.*$ - [R=503,L] \
RewriteCond %{REQUEST_URI} ^\/graphql([\/\?$]|$) \
RewriteCond %{ENV:SONATAFLOW_MANAGEMENT_CONSOLE_DATA_INDEX_ENDPOINT} ^(.*)$ \
RewriteRule ^.*$ %1 [P,L]\n \
RewriteCond %{REQUEST_FILENAME} -f [OR] \
RewriteCond %{REQUEST_FILENAME} -d \
RewriteRule ^ - [L] \
RewriteRule ^ index.html [L]\n' \
"${HTTPD_MAIN_CONF_PATH}/httpd.conf"

# Set the required paths
mkdir -p "${MGMT_CONSOLE_HOME}/launch"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@docker.io/apache/incubator-kie-sonataflow-management-console
Feature: Serverless Workflow Management Console images

Scenario: verify that the home page is served
When container is started with env
| variable | value |
Then container log should contain httpd -D FOREGROUND
Then check that page is served
| property | value |
| port | 8080 |
| path | / |
| request_method | GET |
| wait | 480 |
| expected_status_code | 200 |

Scenario: Verify that the rewrite rule for /graphql is in httpd.conf
When container is started with env
| variable | value |
Then container log should contain httpd -D FOREGROUND
Then file /etc/httpd/conf/httpd.conf should contain /graphql


Scenario: verify that the data-index is available from the container
When container is started with env
| variable | value |
| SONATAFLOW_MANAGEMENT_CONSOLE_DATA_INDEX_ENDPOINT | http://192.168.138.171:4000/graphql |
ricardozanini marked this conversation as resolved.
Show resolved Hide resolved
Then container log should contain httpd -D FOREGROUND
Then check that page is served
| property | value |
| port | 8080 |
| path | /graphql |
| request_method | POST |
| request_body | { "query": "{ProcessInstances{ id } }" } |
| content_type | application/json |
| wait | 15 |
| expected_status_code | 200 |
| expected_phrase | "data":{"ProcessInstances |
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "RunTests-port-4004",
"request": "attach",
"hostName": "localhost",
"port": 4004
},
{
"type": "java",
"name": "Debug (Launch) - RunTests",
"request": "launch",
"mainClass": "RunTests",
"projectName": "RunTests"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"java.import.gradle.enabled": false,
"java.import.maven.enabled": false,
"java.eclipse.downloadSources": true,
"files.exclude": {
"bin/": true,
".eclipse/": true,
".project": true,
".classpath": true,
"build.gradle": true
},
"java.completion.importOrder": ["", "javax", "java", "#"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"id": "jsongreet",
"version": "1.0",
"name": "Greeting workflow",
"description": "JSON based greeting workflow",
"start": "ChooseOnLanguage",
"functions": [
{
"name": "greetFunction",
"type": "custom",
"operation": "sysout"
}
],
"states": [
{
"name": "ChooseOnLanguage",
"type": "switch",
"dataConditions": [
{
"condition": "${ .language == \"English\" }",
"transition": "GreetInEnglish"
},
{
"condition": "${ .language == \"Spanish\" }",
"transition": "GreetInSpanish"
}
],
"defaultCondition": {
"transition": "GreetInEnglish"
}
},
{
"name": "GreetInEnglish",
"type": "inject",
"data": {
"greeting": "Hello from JSON Workflow, "
},
"transition": "GreetPerson"
},
{
"name": "GreetInSpanish",
"type": "inject",
"data": {
"greeting": "Saludos desde JSON Workflow, "
},
"transition": "GreetPerson"
},
{
"name": "GreetPerson",
"type": "operation",
"actions": [
{
"name": "greetAction",
"functionRef": {
"refName": "greetFunction",
"arguments": {
"message": ".greeting+.name"
}
}
}
],
"end": {
"terminate": true
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
///usr/bin/env jbang "$0" "$@" ; exit $?

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

//DEPS org.slf4j:slf4j-simple:2.0.9

// Junit console to start the test engine:
//DEPS org.junit.platform:junit-platform-console:1.10.1

// engine to run the tests (tests are written with Junit5):
//DEPS org.junit.jupiter:junit-jupiter-engine:5.10.1

// testcontainers
//DEPS org.testcontainers:testcontainers:1.19.3
//DEPS org.testcontainers:junit-jupiter:1.19.3

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.nio.file.Paths;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import org.junit.platform.console.ConsoleLauncher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.BindMode;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
public class RunTests {

private static Logger LOGGER = LoggerFactory.getLogger(RunTests.class);

private Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(LOGGER);

@Container
private GenericContainer devModeImage = new GenericContainer(getTestImage())
.withEnv("MAVEN_ARGS_APPEND", "-Ddebug=false -Dquarkus.devservices.enabled=false")
.withFileSystemBind(getScriptDirPath() + "/resources",
"/home/kogito/serverless-workflow-project/src/main/resources", BindMode.READ_ONLY)
.withExposedPorts(8080)
.waitingFor(Wait.forHttp("/jsongreet"))
.withStartupTimeout(Duration.ofMinutes(2))
.withLogConsumer(logConsumer);

@Test
public void testBuiltContainerAnswerCorrectly() throws URISyntaxException, IOException, InterruptedException {
devModeImage.start();
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI(
"http://" + devModeImage.getHost() + ":" + devModeImage.getFirstMappedPort() + "/jsongreet"))
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.timeout(Duration.ofSeconds(10))
.POST(HttpRequest.BodyPublishers
.ofString("{\"workflowdata\" : {\"name\": \"John\", \"language\": \"English\"}}"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, BodyHandlers.ofString());
assertEquals(201, response.statusCode());
}

public static void main(String... args) throws Exception {
ConsoleLauncher.main("--select-class=" + RunTests.class.getName(),
"--reports-dir=" + Paths.get(getOutputDir()).toString());
}

static String getTestImage() {
return System.getenv("TEST_IMAGE");
}

static String getOutputDir() {
return System.getenv("OUTPUT_DIR");
}

static String getScriptDirPath() {
return System.getenv("TESTS_SCRIPT_DIR_PATH");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export const defaultEnvJson: EnvJson = {
KOGITO_CONSOLES_KEYCLOAK_REALM: "kogito",
KOGITO_CONSOLES_KEYCLOAK_UPDATE_TOKEN_VALIDITY: 30,
KOGITO_CONSOLES_KEYCLOAK_URL: "http://localhost:8280",
SONATAFLOW_MANAGEMENT_CONSOLE_DATA_INDEX_ENDPOINT: buildEnv.sonataflowManagementConsoleWebapp.sonataflowDataIndexUrl,
SONATAFLOW_MANAGEMENT_CONSOLE_KOGITO_APP_NAME: "SonataFlow Management Console",
SONATAFLOW_MANAGEMENT_CONSOLE_KOGITO_APP_VERSION: version,
SONATAFLOW_MANAGEMENT_CONSOLE_KOGITO_ENV_MODE: buildEnv.sonataflowManagementConsoleWebapp.sonataflowEnvMode,
Expand Down
Loading