From 1027ccfb11e8693148d63534c27a6e1915b1403f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pere=20Fern=C3=A1ndez?= Date: Thu, 23 Jan 2025 10:03:41 +0100 Subject: [PATCH 1/4] NO-ISSUE: applying missing renames on process-usertasks-timer-quarkus example (#2056) --- kogito-quarkus-examples/pom.xml | 2 +- .../process-usertasks-timer-quarkus/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kogito-quarkus-examples/pom.xml b/kogito-quarkus-examples/pom.xml index 63e1eb28eb..b529e79954 100644 --- a/kogito-quarkus-examples/pom.xml +++ b/kogito-quarkus-examples/pom.xml @@ -159,7 +159,7 @@ process-timer-quarkus process-usertasks-custom-lifecycle-quarkus process-usertasks-quarkus - process-usertasks-timer-quarkus-with-console + process-usertasks-timer-quarkus process-usertasks-with-security-oidc-quarkus process-usertasks-with-security-quarkus rules-quarkus-helloworld diff --git a/kogito-quarkus-examples/process-usertasks-timer-quarkus/pom.xml b/kogito-quarkus-examples/process-usertasks-timer-quarkus/pom.xml index 2c86c37f94..2e28a070fa 100644 --- a/kogito-quarkus-examples/process-usertasks-timer-quarkus/pom.xml +++ b/kogito-quarkus-examples/process-usertasks-timer-quarkus/pom.xml @@ -27,8 +27,8 @@ 999-SNAPSHOT - process-usertasks-timer-quarkus-with-console - Kogito Example :: Process UserTasks with Timer Quarkus :: Console + process-usertasks-timer-quarkus + Kogito Example :: Process UserTasks with Timer Quarkus 3.8.6 quarkus-bom From b097f23e8801c4eefca392349499de61eaab5e38 Mon Sep 17 00:00:00 2001 From: Kbowers <92726146+kbowers-ibm@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:13:01 +0100 Subject: [PATCH 2/4] kie-issues#1774:Bump Axios version (#2058) Co-authored-by: Kennedy Bowers --- .../loanbroker-js/package.json | 2 +- .../loanbroker-js/yarn.lock | 24 ++++++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/serverless-workflow-examples/serverless-workflow-loanbroker-showcase/loanbroker-js/package.json b/serverless-workflow-examples/serverless-workflow-loanbroker-showcase/loanbroker-js/package.json index 6a6de4204a..7a911e802b 100644 --- a/serverless-workflow-examples/serverless-workflow-loanbroker-showcase/loanbroker-js/package.json +++ b/serverless-workflow-examples/serverless-workflow-loanbroker-showcase/loanbroker-js/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "axios": "^0.27.2", + "axios": "^1.7.4", "bootstrap": "^5.2.0", "bootstrap-icons": "^1.9.1", "cloudevents": "^6.0.2", diff --git a/serverless-workflow-examples/serverless-workflow-loanbroker-showcase/loanbroker-js/yarn.lock b/serverless-workflow-examples/serverless-workflow-loanbroker-showcase/loanbroker-js/yarn.lock index bf906dc335..2206ba50d6 100644 --- a/serverless-workflow-examples/serverless-workflow-loanbroker-showcase/loanbroker-js/yarn.lock +++ b/serverless-workflow-examples/serverless-workflow-loanbroker-showcase/loanbroker-js/yarn.lock @@ -377,13 +377,14 @@ axe-core@^4.4.3: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f" integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w== -axios@^0.27.2: - version "0.27.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" - integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== +axios@^1.7.4: + version "1.7.9" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.9.tgz#d7d071380c132a24accda1b2cfc1535b79ec650a" + integrity sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw== dependencies: - follow-redirects "^1.14.9" + follow-redirects "^1.15.6" form-data "^4.0.0" + proxy-from-env "^1.1.0" axobject-query@^2.2.0: version "2.2.0" @@ -935,10 +936,10 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== -follow-redirects@^1.14.9: - version "1.15.1" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" - integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== +follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== for-each@^0.3.3: version "0.3.3" @@ -1662,6 +1663,11 @@ prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" From c9a9adca8445cc8d0329f3b22326c3699bc3ee9b Mon Sep 17 00:00:00 2001 From: bncriju Date: Thu, 23 Jan 2025 22:32:02 +0530 Subject: [PATCH 3/4] [incubator-kie-issues#1780] Cleanup rules springboot examples (#2059) * Corrected README.md files for 5 examples * Modified Swagger Info --- .../decisiontable-springboot-example/README.md | 3 ++- .../rules-legacy-scesim-springboot-example/README.md | 5 +++-- .../rules-legacy-springboot-example/README.md | 5 +++-- .../ruleunit-event-driven-springboot/README.md | 10 ++++++++-- .../ruleunit-springboot-example/README.md | 3 ++- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/kogito-springboot-examples/decisiontable-springboot-example/README.md b/kogito-springboot-examples/decisiontable-springboot-example/README.md index e0096074ae..33bd66ac8a 100644 --- a/kogito-springboot-examples/decisiontable-springboot-example/README.md +++ b/kogito-springboot-examples/decisiontable-springboot-example/README.md @@ -35,7 +35,8 @@ java -jar target/decisiontable-springboot-example.jar ## OpenAPI (Swagger) documentation [Specification at swagger.io](https://swagger.io/docs/specification/about/) -You can take a look at the [OpenAPI definition](http://localhost:8080/v3/api-docs) - automatically generated and included in this service - to determine all available operations exposed by this service. For easy readability you can visualize the OpenAPI definition file using a UI tool like for example available [Swagger UI](https://editor.swagger.io). +The [Swagger](http://localhost:8080/swagger-ui/index.html) page shows all the available endpoints, and it could be used to test them. +You can take a look at the [OpenAPI definition](http://localhost:8080/v3/api-docs) - automatically generated and included in this service - to determine all available operations exposed by this service. For easy readability you can visualize the OpenAPI definition file using a UI tool like for example available [Swagger Editor](https://editor.swagger.io). In addition, various clients to interact with this service can be easily generated using this OpenAPI definition. diff --git a/kogito-springboot-examples/rules-legacy-scesim-springboot-example/README.md b/kogito-springboot-examples/rules-legacy-scesim-springboot-example/README.md index 1d3b145fa5..4d61cd9571 100644 --- a/kogito-springboot-examples/rules-legacy-scesim-springboot-example/README.md +++ b/kogito-springboot-examples/rules-legacy-scesim-springboot-example/README.md @@ -43,13 +43,14 @@ mvn clean compile spring-boot:run ```sh mvn clean package -java -jar target/ruleunit-springboot-example.jar +java -jar target/rules-legacy-scesim-springboot-example.jar ``` ## OpenAPI (Swagger) documentation [Specification at swagger.io](https://swagger.io/docs/specification/about/) -You can take a look at the [OpenAPI definition](http://localhost:8080/v3/api-docs) - automatically generated and included in this service - to determine all available operations exposed by this service. For easy readability you can visualize the OpenAPI definition file using a UI tool like for example available [Swagger UI](https://editor.swagger.io). +The [Swagger](http://localhost:8080/swagger-ui/index.html) page shows all the available endpoints, and it could be used to test them. +You can take a look at the [OpenAPI definition](http://localhost:8080/v3/api-docs) - automatically generated and included in this service - to determine all available operations exposed by this service. For easy readability you can visualize the OpenAPI definition file using a UI tool like for example available [Swagger Editor](https://editor.swagger.io). In addition, various clients to interact with this service can be easily generated using this OpenAPI definition. diff --git a/kogito-springboot-examples/rules-legacy-springboot-example/README.md b/kogito-springboot-examples/rules-legacy-springboot-example/README.md index c272139876..a6d0dc3f09 100644 --- a/kogito-springboot-examples/rules-legacy-springboot-example/README.md +++ b/kogito-springboot-examples/rules-legacy-springboot-example/README.md @@ -25,13 +25,14 @@ mvn clean compile spring-boot:run ```sh mvn clean package -java -jar target/ruleunit-springboot-example.jar +java -jar target/rules-legacy-springboot-example.jar ``` ## OpenAPI (Swagger) documentation [Specification at swagger.io](https://swagger.io/docs/specification/about/) -You can take a look at the [OpenAPI definition](http://localhost:8080/v3/api-docs) - automatically generated and included in this service - to determine all available operations exposed by this service. For easy readability you can visualize the OpenAPI definition file using a UI tool like for example available [Swagger UI](https://editor.swagger.io). +The [Swagger](http://localhost:8080/swagger-ui/index.html) page shows all the available endpoints, and it could be used to test them. +You can take a look at the [OpenAPI definition](http://localhost:8080/v3/api-docs) - automatically generated and included in this service - to determine all available operations exposed by this service. For easy readability you can visualize the OpenAPI definition file using a UI tool like for example available [Swagger Editor](https://editor.swagger.io). In addition, various clients to interact with this service can be easily generated using this OpenAPI definition. diff --git a/kogito-springboot-examples/ruleunit-event-driven-springboot/README.md b/kogito-springboot-examples/ruleunit-event-driven-springboot/README.md index a22962f99e..7eeec7d621 100644 --- a/kogito-springboot-examples/ruleunit-event-driven-springboot/README.md +++ b/kogito-springboot-examples/ruleunit-event-driven-springboot/README.md @@ -70,16 +70,22 @@ mvn clean compile spring-boot:run ``` mvn clean package -java -jar target/dmn-event-driven-springboot.jar +java -jar target/ruleunit-event-driven-springboot.jar ``` or on Windows ``` mvn clean package -java -jar target\dmn-event-driven-springboot.jar +java -jar target\ruleunit-event-driven-springboot.jar ``` +## OpenAPI (Swagger) documentation +[Specification at swagger.io](https://swagger.io/docs/specification/about/) + +The [Swagger](http://localhost:8080/swagger-ui/index.html) page shows all the available endpoints, and it could be used to test them. +You can take a look at the [OpenAPI definition](http://localhost:8080/v3/api-docs) - automatically generated and included in this service - to determine all available operations exposed by this service. For easy readability you can visualize the OpenAPI definition file using a UI tool like for example available [Swagger Editor](https://editor.swagger.io). + ## Example Usage Here is an example of a input event that triggers the evaluation of the [Loan Unit](src/main/resources/org/kie/kogito/queries/RuleUnitQuery.drl) queries diff --git a/kogito-springboot-examples/ruleunit-springboot-example/README.md b/kogito-springboot-examples/ruleunit-springboot-example/README.md index 8b6bb20633..e7178d97d4 100644 --- a/kogito-springboot-examples/ruleunit-springboot-example/README.md +++ b/kogito-springboot-examples/ruleunit-springboot-example/README.md @@ -31,7 +31,8 @@ java -jar target/ruleunit-springboot-example.jar ## OpenAPI (Swagger) documentation [Specification at swagger.io](https://swagger.io/docs/specification/about/) -You can take a look at the [OpenAPI definition](http://localhost:8080/v3/api-docs) - automatically generated and included in this service - to determine all available operations exposed by this service. For easy readability you can visualize the OpenAPI definition file using a UI tool like for example available [Swagger UI](https://editor.swagger.io). +The [Swagger](http://localhost:8080/swagger-ui/index.html) page shows all the available endpoints, and it could be used to test them. +You can take a look at the [OpenAPI definition](http://localhost:8080/v3/api-docs) - automatically generated and included in this service - to determine all available operations exposed by this service. For easy readability you can visualize the OpenAPI definition file using a UI tool like for example available [Swagger Editor](https://editor.swagger.io). In addition, various clients to interact with this service can be easily generated using this OpenAPI definition. From b69f379b405a585f92000d4bb8d46bf4dce3cfe1 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> Date: Mon, 27 Jan 2025 06:09:11 -0500 Subject: [PATCH 4/4] Fix kie-issues #1217 Remove infinispan based images from a few examples (#1927) * Remove infinispan based images from a few examples Signed-off-by: Ricardo Zanini * Remove Infinispan from ocp-tryout Signed-off-by: Ricardo Zanini --------- Signed-off-by: Ricardo Zanini --- .ci/jenkins/Jenkinsfile.setup-branch | 2 +- .../dmn-tracing-quarkus/Dockerfile | 31 -- .../dmn-tracing-quarkus/README.md | 3 +- .../dmn-tracing-quarkus/docker-compose.yml | 77 --- .../docker-compose/infinispan/infinispan.xml | 39 -- .../kogito-travel-agency/README.md | 2 +- .../extended/docker-compose/README.md | 4 +- .../docker-compose/docker-compose.yml | 75 ++- .../docker-compose/infinispan/infinispan.xml | 39 -- .../extended/docker-compose/sql/init.sql | 20 + .../extended/travels/README.md | 2 +- .../extended/travels/pom.xml | 33 +- .../travels/src/main/docker/Dockerfile.jvm | 4 +- .../travels/src/main/docker/Dockerfile.native | 2 +- .../src/main/resources/application.properties | 10 +- .../test/java/org/acme/travel/TravelIT.java | 2 - .../extended/visas/README.md | 2 +- .../extended/visas/pom.xml | 33 +- .../src/main/resources/application.properties | 11 +- kogito-quarkus-examples/ocp-tryout/README.md | 17 +- .../infinispan/infinispan-values.yaml | 41 -- .../ocp-tryout/installer.properties | 2 +- .../ocp-tryout/installer.sh | 10 +- ....yaml => deployment-patch-postgresql.yaml} | 35 +- .../kogito-data-index/kogito-data-index.sh | 2 +- .../kogito-jobs-service/deployment-patch.yaml | 40 +- .../kogito-jobs-service.sh | 2 +- .../ocp-tryout/kogito-shared/README.md | 10 +- .../kogito-shared/kogito-configs.yaml | 14 +- .../postgresql/postgresql-values.yaml | 14 +- .../postgresql.sh} | 10 +- .../testapp/example/apps/travels.yaml | 4 +- .../testapp/example/apps/visas.yaml | 4 +- .../ocp-tryout/tryout-kogito-app/Chart.yaml | 2 +- .../templates/deployment.yaml | 38 +- .../ocp-tryout/uninstaller.sh | 8 +- .../process-usertasks-timer-quarkus/README.md | 2 +- .../docker-compose/README.md | 29 +- .../docker-compose-infinispan.yml | 107 ---- .../docker-compose-postgresql.yml | 37 ++ .../docker-compose/infinispan/infinispan.xml | 39 -- .../docker-compose/startServices.sh | 35 +- .../process-usertasks-timer-quarkus/pom.xml | 44 -- .../src/main/resources/application.properties | 6 +- .../src/main/resources/application.properties | 18 +- .../dmn-tracing-springboot/README.md | 2 - .../dmn-tracing-springboot/docker-compose.yml | 76 --- .../docker-compose/infinispan/infinispan.xml | 39 -- .../process-monitoring-springboot/Dockerfile | 2 +- .../docker-compose/docker-compose.yml | 2 +- .../docker-compose/docker-compose.yml | 2 +- .../docker-compose-with-data-index.yml | 2 +- .../.gitignore | 3 - .../README.md | 84 --- .../github-showcase-architecture-overview.png | Bin 72050 -> 0 bytes .../github-service/.gitignore | 2 - .../github-service/Dockerfile | 32 -- .../github-service/README.md | 196 ------- .../github-service/configure.sh | 87 --- .../github-service/deploy-kubernetes.sh | 29 - .../github-service/expose-on-minikube.sh | 23 - .../kubernetes/00-deployment.yaml | 53 -- .../kubernetes/application.properties | 22 - .../kubernetes/apply_image_ns.yaml.tpl | 3 - .../kubernetes/github-app.env.tpl | 2 - .../kubernetes/kustomization.yaml | 45 -- .../github-service/pom.xml | 171 ------ .../sw/github/service/GitHubResource.java | 80 --- .../github/service/GitHubWrapperService.java | 57 -- .../service/GitHubWrapperServiceImpl.java | 90 ---- .../sw/github/service/TokenProvider.java | 128 ----- .../src/main/resources/application.properties | 34 -- .../sw/github/service/GitHubResourceTest.java | 60 --- .../service/GitHubWrapperServiceIT.java | 65 --- .../service/MockedGitHubWrapperService.java | 46 -- .../src/test/resources/application.properties | 25 - .../notification-service/.gitignore | 3 - .../notification-service/Dockerfile | 32 -- .../notification-service/README.md | 162 ------ .../notification-service/configure.sh | 68 --- .../notification-service/deploy-kubernetes.sh | 31 -- .../kubernetes/00-broker.yaml | 25 - .../kubernetes/01-deployment.yaml | 42 -- .../kubernetes/02-trigger.yaml | 36 -- .../kubernetes/application.properties | 20 - .../kubernetes/apply_image_ns.yaml.tpl | 3 - .../kubernetes/kustomization.yaml | 43 -- .../kubernetes/slack.env.tpl | 1 - .../notification-service/pom.xml | 162 ------ .../service/NotificationResource.java | 80 --- .../javax.ws.rs.client.ClientRequestFilter | 1 - .../javax.ws.rs.ext.MessageBodyReader | 1 - .../javax.ws.rs.ext.MessageBodyWriter | 1 - .../src/main/resources/application.properties | 31 -- .../service/NotificationResourceIT.java | 60 --- .../pom.xml | 52 -- .../pr-checker-workflow/.gitignore | 4 - .../pr-checker-workflow/Dockerfile | 6 - .../pr-checker-workflow/README.md | 180 ------- .../pr-checker-workflow/configure.sh | 70 --- .../pr-checker-workflow/deploy-kubernetes.sh | 31 -- .../docs/handle-backend.png | Bin 51943 -> 0 bytes .../docs/handle-frontend.png | Bin 51319 -> 0 bytes .../docs/pr-checker-workflow.png | Bin 54907 -> 0 bytes .../pr-checker-workflow/expose-on-minikube.sh | 31 -- .../kubernetes/base/00-broker.yaml | 23 - .../kubernetes/base/01-github-source.yaml | 41 -- .../kubernetes/base/02-kogito-service.yaml | 29 - .../base/03-pr-checker-trigger.yaml | 37 -- .../base/04-pr-checker-sinkbinding.yaml | 36 -- .../kubernetes/base/apply_image_ns.yaml.tpl | 3 - .../kubernetes/base/kustomization.yaml | 55 -- .../kubernetes/base/patch_repository.yaml.tpl | 3 - .../kubernetes/base/patch_trigger.yaml.tpl | 3 - .../local/00-github-smee-virtualservice.yaml | 42 -- .../local/01-kogito-service-ingress.yaml | 35 -- .../kubernetes/local/kustomization.yaml | 31 -- .../local/patch-virtual-service.yaml.tpl | 6 - .../pr-checker-workflow/pom.xml | 178 ------- .../sw/github/workflow/GitHubClient.java | 61 --- .../sw/github/workflow/GitHubService.java | 118 ----- .../src/main/resources/application.properties | 44 -- .../src/main/resources/handle-backend.sw.json | 74 --- .../src/main/resources/handle-backend.sw.svg | 1 - .../main/resources/handle-frontend.sw.json | 74 --- .../src/main/resources/handle-frontend.sw.svg | 1 - .../src/main/resources/pr-checker.sw.json | 69 --- .../src/main/resources/pr-checker.sw.svg | 1 - .../workflow/GitHubServiceMockServer.java | 66 --- .../sw/github/workflow/GitHubServiceTest.java | 71 --- .../sw/github/workflow/MessageSinkServer.java | 62 --- .../workflow/PRCheckerWorkflowTest.java | 54 -- .../src/test/resources/application.properties | 34 -- .../src/test/resources/mock/addLabels.json | 93 ---- .../src/test/resources/mock/addReviewers.json | 93 ---- .../test/resources/mock/ce_pr_comment.json | 204 -------- .../src/test/resources/mock/ce_pr_edited.json | 495 ------------------ .../scripts/add-route-to-hosts.sh | 49 -- .../scripts/cleanup-hosts-file.sh | 24 - .../scripts/common.sh | 57 -- .../kubernetes/jobs-service-postgresql.yml | 2 +- .../kubernetes/data-index-services.yml | 2 +- .../kubernetes/supporting-services.yml | 2 +- .../data-index-service-postgresql.yml | 2 +- .../kubernetes/jobs-service-postgresql.yml | 2 +- 145 files changed, 369 insertions(+), 5507 deletions(-) delete mode 100644 kogito-quarkus-examples/dmn-tracing-quarkus/Dockerfile delete mode 100644 kogito-quarkus-examples/dmn-tracing-quarkus/docker-compose.yml delete mode 100644 kogito-quarkus-examples/dmn-tracing-quarkus/docker-compose/infinispan/infinispan.xml delete mode 100755 kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/infinispan/infinispan.xml create mode 100644 kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/sql/init.sql delete mode 100644 kogito-quarkus-examples/ocp-tryout/infinispan/infinispan-values.yaml rename kogito-quarkus-examples/ocp-tryout/kogito-data-index/{deployment-patch-infinispan.yaml => deployment-patch-postgresql.yaml} (64%) rename serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/expose-on-minikube.sh => kogito-quarkus-examples/ocp-tryout/postgresql/postgresql-values.yaml (77%) mode change 100755 => 100644 rename kogito-quarkus-examples/ocp-tryout/{infinispan/infinispan.sh => postgresql/postgresql.sh} (74%) delete mode 100755 kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/docker-compose-infinispan.yml delete mode 100755 kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/infinispan/infinispan.xml delete mode 100644 kogito-springboot-examples/dmn-tracing-springboot/docker-compose.yml delete mode 100644 kogito-springboot-examples/dmn-tracing-springboot/docker-compose/infinispan/infinispan.xml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/.gitignore delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/README.md delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/docs/github-showcase-architecture-overview.png delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/.gitignore delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/Dockerfile delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/README.md delete mode 100755 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/configure.sh delete mode 100755 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/deploy-kubernetes.sh delete mode 100755 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/expose-on-minikube.sh delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/00-deployment.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/application.properties delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/apply_image_ns.yaml.tpl delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/github-app.env.tpl delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/kustomization.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/pom.xml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/GitHubResource.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/GitHubWrapperService.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/GitHubWrapperServiceImpl.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/TokenProvider.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/resources/application.properties delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/java/org/kogito/examples/sw/github/service/GitHubResourceTest.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/java/org/kogito/examples/sw/github/service/GitHubWrapperServiceIT.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/java/org/kogito/examples/sw/github/service/MockedGitHubWrapperService.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/resources/application.properties delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/.gitignore delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/Dockerfile delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/README.md delete mode 100755 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/configure.sh delete mode 100755 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/deploy-kubernetes.sh delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/00-broker.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/01-deployment.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/02-trigger.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/application.properties delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/apply_image_ns.yaml.tpl delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/kustomization.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/slack.env.tpl delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/pom.xml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/java/org/kogito/examples/sw/notification/service/NotificationResource.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/META-INF/javax.ws.rs.client.ClientRequestFilter delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/META-INF/javax.ws.rs.ext.MessageBodyReader delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/META-INF/javax.ws.rs.ext.MessageBodyWriter delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/application.properties delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/test/java/org/kogito/examples/sw/notification/service/NotificationResourceIT.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pom.xml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/.gitignore delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/Dockerfile delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/README.md delete mode 100755 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/configure.sh delete mode 100755 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/deploy-kubernetes.sh delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/docs/handle-backend.png delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/docs/handle-frontend.png delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/docs/pr-checker-workflow.png delete mode 100755 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/expose-on-minikube.sh delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/base/00-broker.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/base/01-github-source.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/base/02-kogito-service.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/base/03-pr-checker-trigger.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/base/04-pr-checker-sinkbinding.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/base/apply_image_ns.yaml.tpl delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/base/kustomization.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/base/patch_repository.yaml.tpl delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/base/patch_trigger.yaml.tpl delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/local/00-github-smee-virtualservice.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/local/01-kogito-service-ingress.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/local/kustomization.yaml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/kubernetes/local/patch-virtual-service.yaml.tpl delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/pom.xml delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/java/org/kogito/examples/sw/github/workflow/GitHubClient.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/java/org/kogito/examples/sw/github/workflow/GitHubService.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/application.properties delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-backend.sw.json delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-backend.sw.svg delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-frontend.sw.json delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-frontend.sw.svg delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/pr-checker.sw.json delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/pr-checker.sw.svg delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/GitHubServiceMockServer.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/GitHubServiceTest.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/MessageSinkServer.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/PRCheckerWorkflowTest.java delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/application.properties delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/addLabels.json delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/addReviewers.json delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/ce_pr_comment.json delete mode 100644 serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/ce_pr_edited.json delete mode 100755 serverless-workflow-examples/serverless-workflow-github-showcase/scripts/add-route-to-hosts.sh delete mode 100755 serverless-workflow-examples/serverless-workflow-github-showcase/scripts/cleanup-hosts-file.sh delete mode 100755 serverless-workflow-examples/serverless-workflow-github-showcase/scripts/common.sh diff --git a/.ci/jenkins/Jenkinsfile.setup-branch b/.ci/jenkins/Jenkinsfile.setup-branch index 10317d138b..927a3ce174 100644 --- a/.ci/jenkins/Jenkinsfile.setup-branch +++ b/.ci/jenkins/Jenkinsfile.setup-branch @@ -121,7 +121,7 @@ pipeline { String[] versionSplit = getKogitoVersion().split("\\.") String reducedTag = "${versionSplit[0]}.${versionSplit[1]}" sh """ - grep -r -l --exclude-dir=.ci 'quay.io/kiegroup' | xargs -I{} sed -i 's|quay.io/kiegroup/\\(.*\\):.*|quay.io/kiegroup/\\1:${reducedTag}|g' {} + grep -r -l --exclude-dir=.ci 'docker.io/apache/incubator-kie-' | xargs -I{} sed -i 's|docker.io/apache/incubator-kie-\\(.*\\):.*|docker.io/apache/incubator-kie-\\1:${reducedTag}|g' {} """ } } diff --git a/kogito-quarkus-examples/dmn-tracing-quarkus/Dockerfile b/kogito-quarkus-examples/dmn-tracing-quarkus/Dockerfile deleted file mode 100644 index 96dd8f1b90..0000000000 --- a/kogito-quarkus-examples/dmn-tracing-quarkus/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -# -# 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. -# - -FROM --platform=linux/amd64 registry.access.redhat.com/ubi9/openjdk-17:1.20 - -ENV RUNTIME_TYPE quarkus - -COPY target/quarkus-app/lib/ $KOGITO_HOME/bin/lib/ -COPY target/quarkus-app/*.jar $KOGITO_HOME/bin -COPY target/quarkus-app/app/ $KOGITO_HOME/bin/app/ -COPY target/quarkus-app/quarkus/ $KOGITO_HOME/bin/quarkus/ - -# For the legacy quarkus application jar use the commands below -# COPY target/*-runner.jar $KOGITO_HOME/bin -# COPY target/lib $KOGITO_HOME/bin/lib diff --git a/kogito-quarkus-examples/dmn-tracing-quarkus/README.md b/kogito-quarkus-examples/dmn-tracing-quarkus/README.md index d6e9756e7d..95846b5ada 100644 --- a/kogito-quarkus-examples/dmn-tracing-quarkus/README.md +++ b/kogito-quarkus-examples/dmn-tracing-quarkus/README.md @@ -135,6 +135,5 @@ Example response: ## Integration example with Trusty Service When the tracing addon is enabled, the tracing events are emitted and pushed to a Kafka broker. The [Trusty Service](https://github.com/apache/incubator-kie-kogito-apps/tree/main/trusty) can consume such events and store them on a storage. The Trusty Service exposes then some api to consume the information that has been collected. -A `docker-compose` example is provided in the current folder. In particular, when `docker-compose up` is run, a Kafka broker, an Infinispan container and the latest build of the trusty service configured to use Infinispan are deployed. -Once the services are up and running, after a decision has been evaluated, you can access the trusty service API to list the evaluations at `localhost:8081/executions` for example. + diff --git a/kogito-quarkus-examples/dmn-tracing-quarkus/docker-compose.yml b/kogito-quarkus-examples/dmn-tracing-quarkus/docker-compose.yml deleted file mode 100644 index 203fad5084..0000000000 --- a/kogito-quarkus-examples/dmn-tracing-quarkus/docker-compose.yml +++ /dev/null @@ -1,77 +0,0 @@ -# -# 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. -# - -version: '2' - -services: - - zookeeper: - image: wurstmeister/zookeeper:3.4.6 - ports: - - "2181:2181" - environment: - LOG_DIR: "/tmp/logs" - - kafka: - image: wurstmeister/kafka:2.12-2.2.1 - depends_on: - - zookeeper - ports: - - "9092:9092" - expose: - - "9093" - environment: - KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9093,OUTSIDE://localhost:9092 - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT - KAFKA_LISTENERS: INSIDE://0.0.0.0:9093,OUTSIDE://0.0.0.0:9092 - KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 - KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE - LOG_DIR: "/tmp/logs" - - kafdrop: - image: obsidiandynamics/kafdrop - depends_on: - - kafka - ports: - - "9000:9000" - environment: - KAFKA_BROKERCONNECT: "kafka:9093" - JVM_OPTS: "-Xms32M -Xmx64M" - SERVER_SERVLET_CONTEXTPATH: "/" - - infinispan: - image: infinispan/server:14.0.4.Final - expose: - - "11222" - command: "-c infinispan-demo.xml" - volumes: - - ./docker-compose/infinispan/infinispan.xml:/opt/infinispan/server/conf/infinispan-demo.xml:z - - trusty: - image: quay.io/kiegroup/kogito-trusty-infinispan:latest - depends_on: - - kafka - - infinispan - ports: - - "8081:8080" - environment: - QUARKUS_INFINISPAN_CLIENT_HOSTS: infinispan:11222 - QUARKUS_INFINISPAN_CLIENT_USE_AUTH: "false" - KAFKA_BOOTSTRAP_SERVERS: kafka:9093 - KAFKA_APPLICATION_FAILURE_STRATEGY: "ignore" diff --git a/kogito-quarkus-examples/dmn-tracing-quarkus/docker-compose/infinispan/infinispan.xml b/kogito-quarkus-examples/dmn-tracing-quarkus/docker-compose/infinispan/infinispan.xml deleted file mode 100644 index 49b57f7d93..0000000000 --- a/kogito-quarkus-examples/dmn-tracing-quarkus/docker-compose/infinispan/infinispan.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/kogito-quarkus-examples/kogito-travel-agency/README.md b/kogito-quarkus-examples/kogito-travel-agency/README.md index c12eb5d51e..35232440ea 100644 --- a/kogito-quarkus-examples/kogito-travel-agency/README.md +++ b/kogito-quarkus-examples/kogito-travel-agency/README.md @@ -18,7 +18,7 @@ and to start any any place. Consists of single service that has both business logic and decision logic included. [Travel agency and visa services with persistence](extended) - deals with all the basic steps to book flight and hotel. -Consists of two services that have both business logic and decision logic included. Preserves data between service restarts and requires Infinispan server to be available. +Consists of two services that have both business logic and decision logic included. Preserves data between service restarts and requires PostgreSQL server to be available. ## Contribution diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/README.md b/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/README.md index 5d313a01fc..60ea3688a4 100644 --- a/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/README.md +++ b/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/README.md @@ -1,7 +1,7 @@ ## Kogito and Infrastructure services To allow a quick setup of all services required to run this demo, we provide a docker compose template that starts the following services: -- Infinispan +- PostgreSQL - Kafka - Prometheus - Grafana @@ -32,7 +32,7 @@ In order to use it, please ensure you have Docker Compose installed on your mach docker-compose up Once all services bootstrap, the following ports will be assigned on your local machine: - - Infinispan: 11222 + - PostgreSQL: 5432 - Kafka: 9092 - Prometheus: 9090 - Grafana: 3000 diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/docker-compose.yml b/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/docker-compose.yml index 66b58e8be2..0ef92cb790 100644 --- a/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/docker-compose.yml +++ b/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/docker-compose.yml @@ -21,19 +21,31 @@ version: '2.1' services: - infinispan: - image: infinispan/server:14.0.4.Final - container_name: infinispan + postgres: + image: postgres:13.4-alpine3.14 ports: - - "11222:11222" - command: "-c infinispan-demo.xml" + - "5432:5432" volumes: - - ./infinispan/infinispan.xml:/opt/infinispan/server/conf/infinispan-demo.xml:z + - ./sql:/docker-entrypoint-initdb.d/ healthcheck: - test: [ "CMD", "curl", "-f", "http://localhost:11222/rest/v2/cache-managers/default/health/status" ] - interval: 1s - timeout: 1s + test: [ "CMD", "pg_isready", "-q", "-d", "kogito", "-U", "kogito-user" ] + timeout: 45s + interval: 10s retries: 50 + environment: + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + + pgadmin-compose: + image: dpage/pgadmin4:5.0 + environment: + PGADMIN_DEFAULT_EMAIL: user@user.org + PGADMIN_DEFAULT_PASSWORD: pass + ports: + - 8055:80 + depends_on: + - postgres + container_name: pgadmin-container zookeeper: container_name: zookeeper @@ -110,19 +122,52 @@ services: data-index: container_name: data-index - image: quay.io/kiegroup/kogito-data-index-infinispan:${KOGITO_VERSION} + image: docker.io/apache/incubator-kie-kogito-data-index-postgresql:${KOGITO_VERSION} ports: - "8180:8080" depends_on: kafka: condition: service_started - infinispan: + postgres: condition: service_healthy volumes: - ./target/protobuf:/home/kogito/data/protobufs/ environment: - QUARKUS_INFINISPAN_CLIENT_HOSTS: infinispan:11222 - QUARKUS_INFINISPAN_CLIENT_USE_AUTH: "false" - QUARKUS_HTTP_CORS_ORIGINS: "/.*/" + QUARKUS_DATASOURCE_JDBC_URL: "jdbc:postgresql://postgres:5432/kogito" + QUARKUS_DATASOURCE_USERNAME: kogito-user + QUARKUS_DATASOURCE_PASSWORD: kogito-pass KAFKA_BOOTSTRAP_SERVERS: kafka:29092 - KOGITO_DATA_INDEX_PROPS: -Dkogito.protobuf.folder=/home/kogito/data/protobufs/ + QUARKUS_HTTP_CORS_ORIGINS: "/.*/" + KOGITO_DATA_INDEX_PROPS: -Dquarkus.hibernate-orm.database.generation=update + + management-console: + container_name: management-console + image: docker.io/apache/incubator-kie-kogito-management-console:${KOGITO_VERSION} + ports: + - 8280:8080 + depends_on: + data-index: + condition: service_started + keycloak: + condition: service_healthy + volumes: + - ./svg/:/home/kogito/data/svg/ + environment: + KOGITO_DATAINDEX_HTTP_URL: http://${DOCKER_GATEWAY_HOST:-host.docker.internal}:8180/graphql + KOGITO_MANAGEMENT_CONSOLE_PROPS: -Dkogito.consoles.keycloak.config.url=http://localhost:8480/auth -Dkogito.consoles.keycloak.config.health-check-url=http://localhost:8480/auth/realms/kogito/.well-known/openid-configuration -Dkogito.svg.folder.path=/home/kogito/data/svg + QUARKUS_HTTP_CORS_ORIGINS: "/.*/" + + task-console: + container_name: task-console + image: docker.io/apache/incubator-kie-kogito-task-console:${KOGITO_VERSION} + ports: + - 8380:8080 + depends_on: + data-index: + condition: service_started + keycloak: + condition: service_healthy + environment: + KOGITO_DATAINDEX_HTTP_URL: http://${DOCKER_GATEWAY_HOST:-host.docker.internal}:8180/graphql + KOGITO_TASK_CONSOLE_PROPS: -Dkogito.consoles.keycloak.config.url=http://localhost:8480/auth -Dkogito.consoles.keycloak.config.health-check-url=http://localhost:8480/auth/realms/kogito/.well-known/openid-configuration + QUARKUS_HTTP_CORS_ORIGINS: "/.*/" diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/infinispan/infinispan.xml b/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/infinispan/infinispan.xml deleted file mode 100755 index a466561b9f..0000000000 --- a/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/infinispan/infinispan.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/sql/init.sql b/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/sql/init.sql new file mode 100644 index 0000000000..ee1a94650d --- /dev/null +++ b/kogito-quarkus-examples/kogito-travel-agency/extended/docker-compose/sql/init.sql @@ -0,0 +1,20 @@ +CREATE ROLE "kogito-user" WITH + LOGIN + SUPERUSER + INHERIT + CREATEDB + CREATEROLE + NOREPLICATION + PASSWORD 'kogito-pass'; + +CREATE DATABASE kogito + WITH + OWNER = "kogito-user" + ENCODING = 'UTF8' + LC_COLLATE = 'en_US.utf8' + LC_CTYPE = 'en_US.utf8' + TABLESPACE = pg_default + CONNECTION LIMIT = -1; + +GRANT ALL PRIVILEGES ON DATABASE kogito TO "kogito-user"; +GRANT ALL PRIVILEGES ON DATABASE kogito TO postgres; diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/travels/README.md b/kogito-quarkus-examples/kogito-travel-agency/extended/travels/README.md index 8f7e92e198..9109ed67ef 100644 --- a/kogito-quarkus-examples/kogito-travel-agency/extended/travels/README.md +++ b/kogito-quarkus-examples/kogito-travel-agency/extended/travels/README.md @@ -145,7 +145,7 @@ cd /docker-compose Once all services bootstrap, the following ports will be assigned on your local machine: -- Infinispan: 11222 +- PostgreSQL: 5432 - Kafka: 9092 - Data Index: 8180 - Keycloak server: 8480 diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/travels/pom.xml b/kogito-quarkus-examples/kogito-travel-agency/extended/travels/pom.xml index 59ae056386..c4f602c877 100644 --- a/kogito-quarkus-examples/kogito-travel-agency/extended/travels/pom.xml +++ b/kogito-quarkus-examples/kogito-travel-agency/extended/travels/pom.xml @@ -102,10 +102,6 @@ org.kie kie-addons-quarkus-monitoring-prometheus - - org.kie - kie-addons-quarkus-persistence-infinispan - org.kie kie-addons-quarkus-events-process @@ -147,6 +143,35 @@ kie-addons-quarkus-source-files + + + default + + true + + + + postgresql + + postgresql + true + + + + org.kie + kie-addons-quarkus-persistence-jdbc + + + io.quarkus + quarkus-jdbc-postgresql + + + io.quarkus + quarkus-agroal + + + + ${project.artifactId} diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/main/docker/Dockerfile.jvm b/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/main/docker/Dockerfile.jvm index 3fbacb695a..ca5f4f6fb5 100644 --- a/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/main/docker/Dockerfile.jvm +++ b/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/main/docker/Dockerfile.jvm @@ -14,7 +14,7 @@ # docker run -i --rm -p 8080:8080 quarkus/kogito-travel-agency-travels-jvm # ### -FROM --platform=linux/amd64 registry.access.redhat.com/ubi9/openjdk-17:1.20 +FROM --platform=linux/amd64 registry.access.redhat.com/ubi9/openjdk-17-runtime:latest ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" ENV AB_ENABLED=jmx_exporter @@ -22,5 +22,3 @@ COPY target/quarkus-app/lib/ /deployments/lib/ COPY target/quarkus-app/*.jar /deployments/ COPY target/quarkus-app/app/ /deployments/app/ COPY target/quarkus-app/quarkus/ /deployments/quarkus/ - -ENTRYPOINT [ "/deployments/run-java.sh" ] diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/main/docker/Dockerfile.native b/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/main/docker/Dockerfile.native index c1a1320724..9e31f9adb2 100644 --- a/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/main/docker/Dockerfile.native +++ b/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/main/docker/Dockerfile.native @@ -14,7 +14,7 @@ # docker run -i --rm -p 8080:8080 quarkus/using-kogito # ### -FROM --platform=linux/amd64 registry.access.redhat.com/ubi9/ubi-minimal:9.4 +FROM --platform=linux/amd64 registry.access.redhat.com/ubi9/ubi-minimal:latest WORKDIR /work/ COPY target/*-runner /work/application RUN chmod 775 /work diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/main/resources/application.properties b/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/main/resources/application.properties index 5869751c51..c453434f49 100644 --- a/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/main/resources/application.properties +++ b/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/main/resources/application.properties @@ -33,9 +33,13 @@ quarkus.oidc.auth-server-url=http://localhost:8281/auth/realms/kogito quarkus.oidc.client-id=kogito-app quarkus.oidc.credentials.secret=secret -quarkus.infinispan-client.hosts=localhost:11222 -quarkus.infinispan-client.use-auth=false -#quarkus.infinispan-client.server-list=kogito-infinispan:11222 +%postgresql.kogito.persistence.type=jdbc +%postgresql.quarkus.datasource.db-kind=postgresql +%postgresql.quarkus.datasource.username=kogito-user +%postgresql.quarkus.datasource.password=kogito-pass +%postgresql.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/kogito +%postgresql.quarkus.kogito.devservices.enabled=false +%postgresql.quarkus.flyway.migrate-at-start=true kafka.bootstrap.servers=localhost:9092 diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/test/java/org/acme/travel/TravelIT.java b/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/test/java/org/acme/travel/TravelIT.java index c9aab73b40..30dc02dd67 100644 --- a/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/test/java/org/acme/travel/TravelIT.java +++ b/kogito-quarkus-examples/kogito-travel-agency/extended/travels/src/test/java/org/acme/travel/TravelIT.java @@ -39,7 +39,6 @@ import org.kie.kogito.process.Process; import org.kie.kogito.process.ProcessInstance; import org.kie.kogito.process.WorkItem; -import org.kie.kogito.testcontainers.quarkus.InfinispanQuarkusTestResource; import org.kie.kogito.testcontainers.quarkus.KafkaQuarkusTestResource; import org.kie.kogito.usertask.UserTaskInstance; import org.kie.kogito.usertask.UserTasks; @@ -59,7 +58,6 @@ import static org.kie.kogito.test.utils.ProcessInstancesTestUtils.abort; @QuarkusTest -@QuarkusTestResource(value = InfinispanQuarkusTestResource.class) @QuarkusTestResource(value = KafkaQuarkusTestResource.class) public class TravelIT { diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/visas/README.md b/kogito-quarkus-examples/kogito-travel-agency/extended/visas/README.md index 114e04cdc1..d40dfbbf2d 100644 --- a/kogito-quarkus-examples/kogito-travel-agency/extended/visas/README.md +++ b/kogito-quarkus-examples/kogito-travel-agency/extended/visas/README.md @@ -91,7 +91,7 @@ cd /docker-compose Once all services bootstrap, the following ports will be assigned on your local machine: -- Infinispan: 11222 +- PostgreSQL: 5432 - Kafka: 9092 - Data Index: 8180 - Keycloak server: 8480 diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/visas/pom.xml b/kogito-quarkus-examples/kogito-travel-agency/extended/visas/pom.xml index ed10fd47d0..93c7bd6288 100644 --- a/kogito-quarkus-examples/kogito-travel-agency/extended/visas/pom.xml +++ b/kogito-quarkus-examples/kogito-travel-agency/extended/visas/pom.xml @@ -108,10 +108,6 @@ io.quarkus quarkus-qute - - org.kie - kie-addons-quarkus-persistence-infinispan - org.kie kie-addons-quarkus-events-process @@ -125,6 +121,35 @@ kie-addons-quarkus-source-files + + + default + + true + + + + postgresql + + postgresql + true + + + + org.kie + kie-addons-quarkus-persistence-jdbc + + + io.quarkus + quarkus-jdbc-postgresql + + + io.quarkus + quarkus-agroal + + + + ${project.artifactId} diff --git a/kogito-quarkus-examples/kogito-travel-agency/extended/visas/src/main/resources/application.properties b/kogito-quarkus-examples/kogito-travel-agency/extended/visas/src/main/resources/application.properties index a65a220a04..867942ae01 100644 --- a/kogito-quarkus-examples/kogito-travel-agency/extended/visas/src/main/resources/application.properties +++ b/kogito-quarkus-examples/kogito-travel-agency/extended/visas/src/main/resources/application.properties @@ -32,10 +32,13 @@ quarkus.oidc.auth-server-url=http://localhost:8281/auth/realms/kogito quarkus.oidc.client-id=kogito-app quarkus.oidc.credentials.secret=secret - -quarkus.infinispan-client.hosts=localhost:11222 -quarkus.infinispan-client.use-auth=false -#quarkus.infinispan-client.hosts=kogito-infinispan:11222 +%postgresql.kogito.persistence.type=jdbc +%postgresql.quarkus.datasource.db-kind=postgresql +%postgresql.quarkus.datasource.username=kogito-user +%postgresql.quarkus.datasource.password=kogito-pass +%postgresql.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/kogito +%postgresql.quarkus.kogito.devservices.enabled=false +%postgresql.quarkus.flyway.migrate-at-start=true kafka.bootstrap.servers=localhost:9092 diff --git a/kogito-quarkus-examples/ocp-tryout/README.md b/kogito-quarkus-examples/ocp-tryout/README.md index 1387781734..75e14354af 100644 --- a/kogito-quarkus-examples/ocp-tryout/README.md +++ b/kogito-quarkus-examples/ocp-tryout/README.md @@ -15,7 +15,7 @@ Make sure you meet the [prerequisites](#prerequisites) and then start [here](#in ### Available Infrastructure - Persistence: - - infinispan/server:14.0.4.Final via helm chart + - PostgreSQL via helm chart - Messaging: - bitnami/kafka:2.8.1-debian-10-r31 via helm chart - Authorization/Authentication: @@ -47,8 +47,8 @@ Installation from pre-build images ``` # example image: - repository: quay.io/kiegroup/examples-travels - tag: 1.16.0.final + repository: quay.io//kogito-examples-travels + tag: 10.0.0.final applicationPort: 8080 ``` - `./testapp/protobuf`: For each Kogito application to be installed add its protobuf files under the `protobuf` folder. Protobuf files for the Kogito examples can be found under folder `target/classes/META-INF/resources/persistence/protobuf`. @@ -72,9 +72,13 @@ All configuration required to make those connections as well as initializations - `keycloak.admin.password` - the administration consoles' users' password - `keycloak.realm.json` - Keycloak initialization file for the Kogito realm creating clients, users, etc. used in Kogito examples - `keycloak.db.vendor` - Keycloak persistence -### Infinispan Configurations -- `quarkus.infinispan.client.hosts` - the infinispan url used by the Kogito application; can be internal service url -- `quarkus.infinispan.client.username` - the user used by the Kogito application to access the infinispan service +#### PostgreSQL Configurations +- `kogito.persistence.type` +- `quarkus.datasource.db-kind` +- `quarkus.datasource.username` +- `quarkus.datasource.password` +- `quarkus.datasource.jdbc.url` +- `quarkus.datasource.reactive.url` ### Kafka Configurations - `kafka.bootstrap.servers` - the kafka url used by the Kogito application; can be internal service url ### Kogito Dataindex Configurations @@ -99,7 +103,6 @@ if marked `-` then namespace defaults are applied |kogito-jobs-service|-|-|-|500Mi| |kogito-travel-agency-travels-jvm|-|-|-|500Mi| |kogito-travel-agency-visas-jvm|-|-|-|500Mi| -|infinispan|500m|512Mi|500m|512Mi| |kafka|-|-|-|-| |kafka-zookeeper|250m|256Mi|-|-| |**sum**|-|-|-|6512Mi| diff --git a/kogito-quarkus-examples/ocp-tryout/infinispan/infinispan-values.yaml b/kogito-quarkus-examples/ocp-tryout/infinispan/infinispan-values.yaml deleted file mode 100644 index 99bde44a6b..0000000000 --- a/kogito-quarkus-examples/ocp-tryout/infinispan/infinispan-values.yaml +++ /dev/null @@ -1,41 +0,0 @@ -# -# 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. -# - -images: - server: quay.io/infinispan/server:14.0.4.Final -deploy: - infinispan: - server: - endpoints: - - securityRealm: default - socketBinding: default - - connectors: - hotrod: - hotrodConnector: - authentication: - sasl: - mechanisms: DIGEST-MD5 - qop: auth - serverName: infinispan - rest: - restConnector: - authentication: - mechanisms: BASIC - securityRealm: metrics - socketBinding: metrics \ No newline at end of file diff --git a/kogito-quarkus-examples/ocp-tryout/installer.properties b/kogito-quarkus-examples/ocp-tryout/installer.properties index 3f1dc40e47..4e1084d0c1 100644 --- a/kogito-quarkus-examples/ocp-tryout/installer.properties +++ b/kogito-quarkus-examples/ocp-tryout/installer.properties @@ -27,7 +27,7 @@ OCP_PROJECT= # or to N or leave empty, if does not need to be installed INSTALL_ALL=Y SHARED_CONFIG=N -INFINISPAN=N +POSTGRESQL=N KAFKA=N KEYCLOAK=N KOGITO_DATA_INDEX=N diff --git a/kogito-quarkus-examples/ocp-tryout/installer.sh b/kogito-quarkus-examples/ocp-tryout/installer.sh index 9575493d20..497c923875 100755 --- a/kogito-quarkus-examples/ocp-tryout/installer.sh +++ b/kogito-quarkus-examples/ocp-tryout/installer.sh @@ -19,8 +19,8 @@ # -# firstly, any Kogito unrelated infrastructure like infinispan, kafka, etc. is installed -# secondly, any Kogito services like data-index, etc. is installed +# firstly, any Kogito unrelated infrastructure like postgresql, kafka, etc. is installed +# secondly, any Kogito services like data-index, management console, etc. is installed # thirdly, the application to try out is installed source installer.properties @@ -28,7 +28,7 @@ source common-functions.sh action=install -components=(SHARED_CONFIG INFINISPAN KAFKA KEYCLOAK \ +components=(SHARED_CONFIG KAFKA KEYCLOAK \ KOGITO_DATA_INDEX KOGITO_JOBS_SERVICE \ TEST_APP) # override the installer properties configuration if needed @@ -103,11 +103,11 @@ function install(){ componentAction "${SHARED_CONFIG}" "kogito-shared" - componentAction "${INFINISPAN}" "infinispan" + componentAction "${POSTGRESQL}" "postgresql" componentAction "${KAFKA}" "kafka" componentAction "${KEYCLOAK}" "keycloak" - dbType="infinispan" + dbType="postgresql" componentAction "${KOGITO_DATA_INDEX}" "kogito-data-index" "${dbType}" componentAction "${KOGITO_JOBS_SERVICE}" "kogito-jobs-service" "${dbType}" diff --git a/kogito-quarkus-examples/ocp-tryout/kogito-data-index/deployment-patch-infinispan.yaml b/kogito-quarkus-examples/ocp-tryout/kogito-data-index/deployment-patch-postgresql.yaml similarity index 64% rename from kogito-quarkus-examples/ocp-tryout/kogito-data-index/deployment-patch-infinispan.yaml rename to kogito-quarkus-examples/ocp-tryout/kogito-data-index/deployment-patch-postgresql.yaml index fed69bc259..8f98bb60ee 100644 --- a/kogito-quarkus-examples/ocp-tryout/kogito-data-index/deployment-patch-infinispan.yaml +++ b/kogito-quarkus-examples/ocp-tryout/kogito-data-index/deployment-patch-postgresql.yaml @@ -25,7 +25,7 @@ spec: configMap: name: data-index-config containers: - - name: kogito-data-index-infinispan + - name: kogito-data-index-postgresql volumeMounts: - name: app-pvc mountPath: /home/kogito/data/protobufs @@ -40,23 +40,36 @@ spec: configMapKeyRef: name: kogito-configs key: kogito.dataindex.props - - name: QUARKUS_INFINISPAN_CLIENT_HOSTS + - name: KOGITO_PERSISTENCE_TYPE valueFrom: configMapKeyRef: name: kogito-configs - key: quarkus.infinispan.client.hosts - - name: QUARKUS_INFINISPAN_CLIENT_USE_AUTH - value: 'true' - - name: QUARKUS_INFINISPAN_CLIENT_USERNAME + key: kogito.persistence.type + - name: QUARKUS_DATASOURCE_JDBC_URL valueFrom: configMapKeyRef: name: kogito-configs - key: quarkus.infinispan.client.username - - name: QUARKUS_INFINISPAN_CLIENT_PASSWORD + key: quarkus.datasource.jdbc.url + - name: QUARKUS_DATASOURCE_REACTIVE_URL valueFrom: - secretKeyRef: - name: infinispan-generated-secret - key: password + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.reactive.url + - name: QUARKUS_DATASOURCE_DB_KIND + valueFrom: + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.db-kind + - name: QUARKUS_DATASOURCE_USERNAME + valueFrom: + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.username + - name: QUARKUS_DATASOURCE_PASSWORD + valueFrom: + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.password resources: limits: cpu: '1' diff --git a/kogito-quarkus-examples/ocp-tryout/kogito-data-index/kogito-data-index.sh b/kogito-quarkus-examples/ocp-tryout/kogito-data-index/kogito-data-index.sh index 62c9b9027d..dcdaecf8a0 100755 --- a/kogito-quarkus-examples/ocp-tryout/kogito-data-index/kogito-data-index.sh +++ b/kogito-quarkus-examples/ocp-tryout/kogito-data-index/kogito-data-index.sh @@ -37,7 +37,7 @@ elif [ "${action}" == "install" ]; then oc create configmap data-index-config --from-file=../testapp/protobuf -o yaml --dry-run=client | \ oc label -f- --dry-run=client -o yaml --local=true app=kogito-data-index-"${type}" | \ oc apply -f- -n $(getProjectName) $(dryRun) - oc new-app quay.io/kiegroup/kogito-data-index-"${type}":"${KOGITO_VERSION}" -n $(getProjectName) $(dryRun "NewApp") + oc new-app docker.io/apache/incubator-kie-kogito-data-index-"${type}":"${KOGITO_VERSION}" -n $(getProjectName) $(dryRun "NewApp") waitForPod kogito-data-index oc patch deployment kogito-data-index-"${type}" --patch "$(cat deployment-patch-"${type}".yaml)" -n $(getProjectName) $(dryRun) waitForPod kogito-data-index diff --git a/kogito-quarkus-examples/ocp-tryout/kogito-jobs-service/deployment-patch.yaml b/kogito-quarkus-examples/ocp-tryout/kogito-jobs-service/deployment-patch.yaml index 9e45d677d5..9532db241c 100644 --- a/kogito-quarkus-examples/ocp-tryout/kogito-jobs-service/deployment-patch.yaml +++ b/kogito-quarkus-examples/ocp-tryout/kogito-jobs-service/deployment-patch.yaml @@ -21,7 +21,7 @@ spec: template: spec: containers: - - name: kogito-jobs-service-infinispan + - name: kogito-jobs-service-postgresql env: - name: ENABLE_EVENTS value: 'true' @@ -30,23 +30,41 @@ spec: configMapKeyRef: name: kogito-configs key: kogito.jobsservice.props - - name: QUARKUS_INFINISPAN_CLIENT_HOSTS + - name: KOGITO_DATA_INDEX_PROPS valueFrom: configMapKeyRef: name: kogito-configs - key: quarkus.infinispan.client.hosts - - name: QUARKUS_INFINISPAN_CLIENT_USE_AUTH - value: 'true' - - name: QUARKUS_INFINISPAN_CLIENT_USERNAME + key: kogito.dataindex.props + - name: KOGITO_PERSISTENCE_TYPE + valueFrom: + configMapKeyRef: + name: kogito-configs + key: kogito.persistence.type + - name: QUARKUS_DATASOURCE_JDBC_URL valueFrom: configMapKeyRef: name: kogito-configs - key: quarkus.infinispan.client.username - - name: QUARKUS_INFINISPAN_CLIENT_PASSWORD + key: quarkus.datasource.jdbc.url + - name: QUARKUS_DATASOURCE_REACTIVE_URL valueFrom: - secretKeyRef: - name: infinispan-generated-secret - key: password + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.reactive.url + - name: QUARKUS_DATASOURCE_DB_KIND + valueFrom: + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.db-kind + - name: QUARKUS_DATASOURCE_USERNAME + valueFrom: + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.username + - name: QUARKUS_DATASOURCE_PASSWORD + valueFrom: + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.password resources: limits: cpu: '1' diff --git a/kogito-quarkus-examples/ocp-tryout/kogito-jobs-service/kogito-jobs-service.sh b/kogito-quarkus-examples/ocp-tryout/kogito-jobs-service/kogito-jobs-service.sh index 903c7d81cc..10cf71ec1f 100755 --- a/kogito-quarkus-examples/ocp-tryout/kogito-jobs-service/kogito-jobs-service.sh +++ b/kogito-quarkus-examples/ocp-tryout/kogito-jobs-service/kogito-jobs-service.sh @@ -28,7 +28,7 @@ if [ "${action}" == "uninstall" ]; then elif [ "${action}" == "install" ]; then echo "*** installing jobs service" - oc new-app quay.io/kiegroup/kogito-jobs-service-${type}:${KOGITO_VERSION} -n $(getProjectName) $(dryRun "NewApp") + oc new-app docker.io/apache/incubator-kie-kogito-jobs-service-${type}:${KOGITO_VERSION} -n $(getProjectName) $(dryRun "NewApp") waitForPod kogito-jobs-service oc patch deployment kogito-jobs-service-${type} --patch "$(cat deployment-patch.yaml)" -n $(getProjectName) $(dryRun) waitForPod kogito-jobs-service diff --git a/kogito-quarkus-examples/ocp-tryout/kogito-shared/README.md b/kogito-quarkus-examples/ocp-tryout/kogito-shared/README.md index b1392decb5..bf2a5e3f47 100644 --- a/kogito-quarkus-examples/ocp-tryout/kogito-shared/README.md +++ b/kogito-quarkus-examples/ocp-tryout/kogito-shared/README.md @@ -11,9 +11,13 @@ There is one config map per infrastructure component. - `keycloak.admin.password` - the administration consoles' users' password - `keycloak.realm.json` - Keycloak initialization file for the Kogito realm creating clients, users, etc. used in Kogito examples - `keycloak.db.vendor` - Keycloak persistence -#### Infinispan Config -- `quarkus.infinispan.client.hosts` - the infinispan url used by the Kogito application; can be internal service url -- `quarkus.infinispan.client.username` - the user used by the Kogito application to access the infinispan service +#### PostgreSQL Config +- `kogito.persistence.type` +- `quarkus.datasource.db-kind` +- `quarkus.datasource.username` +- `quarkus.datasource.password` +- `quarkus.datasource.jdbc.url` +- `quarkus.datasource.reactive.url` #### Kafka Config - `kafka.bootstrap.servers` - the kafka url used by the Kogito application; can be internal service url #### Kogito Dataindex Config diff --git a/kogito-quarkus-examples/ocp-tryout/kogito-shared/kogito-configs.yaml b/kogito-quarkus-examples/ocp-tryout/kogito-shared/kogito-configs.yaml index a3841d6cc5..ac0a8dbdf5 100644 --- a/kogito-quarkus-examples/ocp-tryout/kogito-shared/kogito-configs.yaml +++ b/kogito-quarkus-examples/ocp-tryout/kogito-shared/kogito-configs.yaml @@ -28,12 +28,16 @@ data: keycloak.admin.password: 'admin' keycloak.realm.json: '/tmp/kogito-realm.json' keycloak.db.vendor: 'h2' - quarkus.infinispan.client.username: 'developer' - quarkus.infinispan.client.hosts: 'infinispan.${project_name}.svc.cluster.local:11222' + kogito.persistence.type: jdbc + quarkus.datasource.db-kind: postgresql + quarkus.datasource.username: kogito-user + quarkus.datasource.password: kogito-pass + quarkus.datasource.jdbc.url: jdbc:postgresql://postgresql.${project_name}.svc.cluster.local:5432/kogito} + quarkus.datasource.reactive.url: postgresql://postgresql.${project_name}.svc.cluster.local:5432/kogito} kafka.bootstrap.servers: 'kafka.${project_name}.svc.cluster.local:9092' kogito.dataindex.props: '-Dkogito.protobuf.folder=/home/kogito/data/protobufs' - kogito.dataindex.httpurl: 'http://kogito-data-index-infinispan-${project_name}.${apps_cluster_host}' - kogito.dataindex.httpurl.with.graphql: 'http://kogito-data-index-infinispan-${project_name}.${apps_cluster_host}/graphql' - kogito.dataindex.wsurl: 'ws://kogito-data-index-infinispan-${project_name}.${apps_cluster_host}' + kogito.dataindex.httpurl: 'http://kogito-data-index-postgresql-${project_name}.${apps_cluster_host}' + kogito.dataindex.httpurl.with.graphql: 'http://kogito-data-index-postgresql-${project_name}.${apps_cluster_host}/graphql' + kogito.dataindex.wsurl: 'ws://kogito-data-index-postgresql-${project_name}.${apps_cluster_host}' kogito.managementconsole.props: '-Dkogito.svg.folder.path=/home/kogito/data/svg -Dkogito.consoles.keycloak.config.url=http://keycloak-${project_name}.${apps_cluster_host}/auth/ -Dkogito.consoles.keycloak.config.health-check-url=http://keycloak-${project_name}.${apps_cluster_host}/auth/realms/kogito/.well-known/openid-configuration' kogito.jobsservice.props: '-Dquarkus-profile=events-support -D%events-support.kafka.bootstrap.servers=kafka.${project_name}.svc.cluster.local:9092 -D%events-support.mp.messaging.outgoing.kogito-job-service-job-status-events.bootstrap.servers=kafka.${project_name}.svc.cluster.local:9092' \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/expose-on-minikube.sh b/kogito-quarkus-examples/ocp-tryout/postgresql/postgresql-values.yaml old mode 100755 new mode 100644 similarity index 77% rename from serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/expose-on-minikube.sh rename to kogito-quarkus-examples/ocp-tryout/postgresql/postgresql-values.yaml index 01ffcaf9ee..ab42bba3c5 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/expose-on-minikube.sh +++ b/kogito-quarkus-examples/ocp-tryout/postgresql/postgresql-values.yaml @@ -1,4 +1,3 @@ -#!/bin/bash # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file @@ -18,6 +17,13 @@ # under the License. # -CURR_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -# shellcheck source=../scripts/add-route-to-hosts.sh -source "${CURR_DIR}/../scripts/add-route-to-hosts.sh" notification-service +database_service_name: postgresql +memory_limit: 512Mi +volume_capacity: 1Gi +config: + postgresql_database: kogito + postgresql_password: kogito-pass + postgresql_user: kogito-user + port: 5432 +image: + tag: "postgres:16.1-alpine3.19" diff --git a/kogito-quarkus-examples/ocp-tryout/infinispan/infinispan.sh b/kogito-quarkus-examples/ocp-tryout/postgresql/postgresql.sh similarity index 74% rename from kogito-quarkus-examples/ocp-tryout/infinispan/infinispan.sh rename to kogito-quarkus-examples/ocp-tryout/postgresql/postgresql.sh index 8492afb942..c79b3efaea 100755 --- a/kogito-quarkus-examples/ocp-tryout/infinispan/infinispan.sh +++ b/kogito-quarkus-examples/ocp-tryout/postgresql/postgresql.sh @@ -22,14 +22,14 @@ action=$1 if [ "${action}" == "uninstall" ]; then - echo "*** uninstalling infinispan" - helm uninstall infinispan -n $(getProjectName) - oc delete pvc,secret --selector clusterName=infinispan -n $(getProjectName) + echo "*** uninstalling postgresql" + helm uninstall postgresql -n $(getProjectName) + oc delete pvc,secret --selector clusterName=postgresql -n $(getProjectName) elif [ "${action}" == "install" ]; then - echo "*** installing infinispan" + echo "*** installing postgresql" helm repo add openshift-helm-charts https://charts.openshift.io/ - helm install infinispan openshift-helm-charts/infinispan-infinispan --version "0.2.0" -f infinispan-values.yaml -n $(getProjectName) $(dryRun "Helm") + helm install postgresql openshift-helm-charts/redhat-postgresql-persistent --version "0.0.3" -f postgresql-values.yaml -n $(getProjectName) $(dryRun "Helm") else echo "*** no such action: $action" diff --git a/kogito-quarkus-examples/ocp-tryout/testapp/example/apps/travels.yaml b/kogito-quarkus-examples/ocp-tryout/testapp/example/apps/travels.yaml index df59efcf2b..47196df44d 100644 --- a/kogito-quarkus-examples/ocp-tryout/testapp/example/apps/travels.yaml +++ b/kogito-quarkus-examples/ocp-tryout/testapp/example/apps/travels.yaml @@ -18,7 +18,7 @@ # image: - repository: quay.io/kiegroup/examples-travels - tag: "1.16.0.final" + repository: quay.io//examples-travels + tag: "latest" applicationPort: 8080 \ No newline at end of file diff --git a/kogito-quarkus-examples/ocp-tryout/testapp/example/apps/visas.yaml b/kogito-quarkus-examples/ocp-tryout/testapp/example/apps/visas.yaml index 6b3cf39658..8ae000c5a2 100644 --- a/kogito-quarkus-examples/ocp-tryout/testapp/example/apps/visas.yaml +++ b/kogito-quarkus-examples/ocp-tryout/testapp/example/apps/visas.yaml @@ -18,7 +18,7 @@ # image: - repository: quay.io/kiegroup/examples-visas - tag: "1.16.0.final" + repository: quay.io//examples-visas + tag: "latest" applicationPort: 8080 diff --git a/kogito-quarkus-examples/ocp-tryout/tryout-kogito-app/Chart.yaml b/kogito-quarkus-examples/ocp-tryout/tryout-kogito-app/Chart.yaml index e64ebe5abd..380ae363c5 100644 --- a/kogito-quarkus-examples/ocp-tryout/tryout-kogito-app/Chart.yaml +++ b/kogito-quarkus-examples/ocp-tryout/tryout-kogito-app/Chart.yaml @@ -40,4 +40,4 @@ version: 0.1.0 # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +appVersion: "10.0.0" diff --git a/kogito-quarkus-examples/ocp-tryout/tryout-kogito-app/templates/deployment.yaml b/kogito-quarkus-examples/ocp-tryout/tryout-kogito-app/templates/deployment.yaml index 8411a6ff88..2d3b8a78d0 100644 --- a/kogito-quarkus-examples/ocp-tryout/tryout-kogito-app/templates/deployment.yaml +++ b/kogito-quarkus-examples/ocp-tryout/tryout-kogito-app/templates/deployment.yaml @@ -80,23 +80,41 @@ spec: configMapKeyRef: name: kogito-configs key: kogito.dataindex.wsurl - - name: QUARKUS_INFINISPAN_CLIENT_HOSTS + - name: KOGITO_DATA_INDEX_PROPS valueFrom: configMapKeyRef: name: kogito-configs - key: quarkus.infinispan.client.hosts - - name: QUARKUS_INFINISPAN_CLIENT_USE_AUTH - value: 'true' - - name: QUARKUS_INFINISPAN_CLIENT_USERNAME + key: kogito.dataindex.props + - name: KOGITO_PERSISTENCE_TYPE valueFrom: configMapKeyRef: name: kogito-configs - key: quarkus.infinispan.client.username - - name: QUARKUS_INFINISPAN_CLIENT_PASSWORD + key: kogito.persistence.type + - name: QUARKUS_DATASOURCE_JDBC_URL valueFrom: - secretKeyRef: - name: infinispan-generated-secret - key: password + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.jdbc.url + - name: QUARKUS_DATASOURCE_REACTIVE_URL + valueFrom: + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.reactive.url + - name: QUARKUS_DATASOURCE_DB_KIND + valueFrom: + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.db-kind + - name: QUARKUS_DATASOURCE_USERNAME + valueFrom: + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.username + - name: QUARKUS_DATASOURCE_PASSWORD + valueFrom: + configMapKeyRef: + name: kogito-configs + key: quarkus.datasource.password ports: - name: http containerPort: {{ .Values.applicationPort }} diff --git a/kogito-quarkus-examples/ocp-tryout/uninstaller.sh b/kogito-quarkus-examples/ocp-tryout/uninstaller.sh index 93061c9ea6..9858268222 100755 --- a/kogito-quarkus-examples/ocp-tryout/uninstaller.sh +++ b/kogito-quarkus-examples/ocp-tryout/uninstaller.sh @@ -24,7 +24,7 @@ source common-functions.sh action=uninstall -components=(SHARED_CONFIG INFINISPAN KAFKA KEYCLOAK \ +components=(SHARED_CONFIG KAFKA KEYCLOAK \ KOGITO_DATA_INDEX KOGITO_JOBS_SERVICE \ TEST_APP) # override the installer properties configuration if needed @@ -68,14 +68,14 @@ function uninstall(){ componentAction "${TEST_APP}" "testapp" dbType="" - if [ "${INFINISPAN}" == "Y" ]; then - dbType="infinispan" + if [ "${POSTGRESQL}" == "Y" ]; then + dbType="postgresql" fi componentAction "${KOGITO_DATA_INDEX}" "kogito-data-index" "${dbType}" componentAction "${KOGITO_JOBS_SERVICE}" "kogito-jobs-service" "${dbType}" - componentAction "${INFINISPAN}" "infinispan" + componentAction "${POSTGRESQL}" "postgresql" componentAction "${KAFKA}" "kafka" componentAction "${KEYCLOAK}" "keycloak" diff --git a/kogito-quarkus-examples/process-usertasks-timer-quarkus/README.md b/kogito-quarkus-examples/process-usertasks-timer-quarkus/README.md index 5463ddf89d..8978991b58 100644 --- a/kogito-quarkus-examples/process-usertasks-timer-quarkus/README.md +++ b/kogito-quarkus-examples/process-usertasks-timer-quarkus/README.md @@ -11,7 +11,7 @@ after some reasonable time.(configured for test purposes to 40 seconds) The required *Kogito and Infrastructure Services* for this example are: -- Infinispan / Postgresql +- Postgresql - Kafka - Kogito Data Index - Kogito Jobs Service diff --git a/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/README.md b/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/README.md index f724f574be..c27c8e2974 100644 --- a/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/README.md +++ b/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/README.md @@ -1,7 +1,7 @@ ## Kogito and Infrastructure services To allow a quick setup of all services required to run this demo, we provide a docker compose template that starts the following services: -- Postgresql / Infinispan +- Postgresql - (PgAdmin, only for postgres deployment) - Kafka - Kogito Data Index @@ -13,7 +13,7 @@ in [here](https://docs.docker.com/compose/install/). ### Starting required services Once all services bootstrap, the following ports will be assigned on your local machine: -- PostgresQL: 5432 or Infinispan: 11222 +- PostgresQL: 5432 - PgAdmin: 8055 (only for postgres deployment) - Kafka: 9092 - Data Index: 8180 @@ -35,28 +35,3 @@ docker-compose -f docker-compose-postgresql.yml stop It is also recomended to remove any of stopped containers by running: docker-compose -f docker-compose-postgresql.yml rm - -### Infinispan deployment: - -####Start services - - ./startServices.sh infinispan - -#### Stopping and removing volume data - -To stop all services, simply run: - -docker-compose -f docker-compose-infinispan.yml stop - -It is also recomended to remove any of stopped containers by running: - -docker-compose -f docker-compose-infinispan.yml rm - - -NOTE: All the running containers can be stopped running `docker stop $(docker ps -a -q)` - -NOTE: All the running containers can be removed running `docker rm $(docker ps -a -q)` - -For more details please check the Docker Compose documentation. - - docker-compose --help diff --git a/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/docker-compose-infinispan.yml b/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/docker-compose-infinispan.yml deleted file mode 100755 index 52c330e4b2..0000000000 --- a/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/docker-compose-infinispan.yml +++ /dev/null @@ -1,107 +0,0 @@ -# -# 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. -# - -version: '2.1' - -services: - - infinispan: - image: infinispan/server:14.0.4.Final - container_name: infinispan - ports: - - "11222:11222" - command: "-c infinispan-demo.xml" - volumes: - - ./infinispan/infinispan.xml:/opt/infinispan/server/conf/infinispan-demo.xml:z - healthcheck: - test: [ "CMD", "curl", "-f", "http://localhost:11222/rest/v2/cache-managers/default/health/status" ] - interval: 1s - timeout: 30s - retries: 50 - - zookeeper: - container_name: zookeeper - image: strimzi/kafka:0.20.1-kafka-2.6.0 - command: [ - "sh", "-c", - "bin/zookeeper-server-start.sh config/zookeeper.properties" - ] - ports: - - "2181:2181" - environment: - LOG_DIR: "/tmp/logs" - - kafka: - image: strimzi/kafka:0.20.1-kafka-2.6.0 - container_name: kafka - command: [ - "sh", "-c", - "bin/kafka-server-start.sh config/server.properties --override inter.broker.listener.name=$${KAFKA_INTER_BROKER_LISTENER_NAME} --override listener.security.protocol.map=$${KAFKA_LISTENER_SECURITY_PROTOCOL_MAP} --override listeners=$${KAFKA_LISTENERS} --override advertised.listeners=$${KAFKA_ADVERTISED_LISTENERS} --override zookeeper.connect=$${KAFKA_ZOOKEEPER_CONNECT}" - ] - depends_on: - - zookeeper - ports: - - "9092:9092" - environment: - KAFKA_BROKER_ID: 0 - KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 - KAFKA_LISTENERS: INTERNAL://kafka:29092,EXTERNAL://kafka:9092 - KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka:29092,EXTERNAL://localhost:9092 - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT - KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL - KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true" - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 - LOG_DIR: "/tmp/logs" - - data-index: - container_name: data-index - image: quay.io/kiegroup/kogito-data-index-infinispan:${KOGITO_VERSION} - ports: - - "8180:8080" - depends_on: - kafka: - condition: service_started - infinispan: - condition: service_healthy - volumes: - - ./persistence/:/home/kogito/data/protobufs/ - environment: - QUARKUS_INFINISPAN_CLIENT_HOSTS: infinispan:11222 - QUARKUS_INFINISPAN_CLIENT_USE_AUTH: "false" - KAFKA_BOOTSTRAP_SERVERS: kafka:29092 - QUARKUS_HTTP_CORS_ORIGINS: "/.*/" - KOGITO_DATA_INDEX_PROPS: -Dkogito.protobuf.folder=/home/kogito/data/protobufs/ - - jobs-service: - container_name: jobs-service - image: quay.io/kiegroup/kogito-jobs-service-infinispan:${KOGITO_VERSION} - ports: - - "8580:8080" - depends_on: - kafka: - condition: service_started - infinispan: - condition: service_healthy - environment: - KAFKA_BOOTSTRAP_SERVERS: kafka:29092 - QUARKUS_PROFILE: events-support - QUARKUS_HTTP_PORT: 8580 - QUARKUS_INFINISPAN_CLIENT_USE_AUTH: "false" - QUARKUS_INFINISPAN_CLIENT_HOSTS: infinispan:11222 - QUARKUS_HTTP_CORS_ORIGINS: "/.*/" diff --git a/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/docker-compose-postgresql.yml b/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/docker-compose-postgresql.yml index f0db4764d3..887aac000a 100755 --- a/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/docker-compose-postgresql.yml +++ b/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/docker-compose-postgresql.yml @@ -135,3 +135,40 @@ services: QUARKUS_PROFILE: events-support QUARKUS_HTTP_PORT: 8580 QUARKUS_HTTP_CORS_ORIGINS: "/.*/" + + management-console: + container_name: management-console + image: docker.io/apache/incubator-kie-kogito-management-console:${KOGITO_VERSION} + ports: + - "8280:8080" + depends_on: + data-index: + condition: service_started + jobs-service: + condition: service_started + keycloak: + condition: service_healthy + volumes: + - ../target/classes/META-INF/processSVG/:/home/kogito/data/svg/ + environment: + KOGITO_DATAINDEX_HTTP_URL: http://${DOCKER_GATEWAY_HOST:-host.docker.internal}:8180/graphql + QUARKUS_HTTP_CORS_ORIGINS: "/.*/" + KOGITO_MANAGEMENT_CONSOLE_PROPS: -Dkogito.consoles.keycloak.config.url=http://localhost:8480/auth + -Dkogito.consoles.keycloak.config.health-check-url=http://localhost:8480/auth/realms/kogito/.well-known/openid-configuration + -Dkogito.svg.folder.path=/home/kogito/data/svg + + task-console: + container_name: task-console + image: docker.io/apache/incubator-kie-kogito-task-console:${KOGITO_VERSION} + ports: + - "8380:8080" + depends_on: + data-index: + condition: service_started + keycloak: + condition: service_healthy + environment: + KOGITO_DATAINDEX_HTTP_URL: http://${DOCKER_GATEWAY_HOST:-host.docker.internal}:8180/graphql + QUARKUS_HTTP_CORS_ORIGINS: "/.*/" + KOGITO_TASK_CONSOLE_PROPS: -Dkogito.consoles.keycloak.config.url=http://localhost:8480/auth + -Dkogito.consoles.keycloak.config.health-check-url=http://localhost:8480/auth/realms/kogito/.well-known/openid-configuration diff --git a/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/infinispan/infinispan.xml b/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/infinispan/infinispan.xml deleted file mode 100755 index a466561b9f..0000000000 --- a/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/infinispan/infinispan.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/startServices.sh b/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/startServices.sh index ad8e9bfb6b..1169ce7791 100755 --- a/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/startServices.sh +++ b/kogito-quarkus-examples/process-usertasks-timer-quarkus/docker-compose/startServices.sh @@ -36,38 +36,7 @@ echo "Kogito Image version: ${KOGITO_VERSION}" echo "KOGITO_VERSION=${KOGITO_VERSION}" > ".env" echo "DOCKER_GATEWAY_HOST=172.17.0.1" >> ".env" -DB="postgresql" - -if [ -n "$1" ]; then - if [[ "$1" == "postgresql" || "$1" == "infinispan" ]]; - then - DB="$1" - else - echo "Usage: By default postgresql environments is started if no argument is provided" - echo " start POSTGRESQL docker-compose running: ./startServices.sh postgresql or just ./startServices.sh " - echo " start INFINISPAN docker-compose running: ./startServices.sh infinispan " - exit 1 - fi -fi -echo "Have you compiled the project before with the right profile: ../mvn clean install -DskipTests -P$DB" - -if [ "$1" == "infinispan" ]; -then - PERSISTENCE_FOLDER=./persistence - KOGITO_EXAMPLE_PERSISTENCE=../target/classes/META-INF/resources/persistence/protobuf - - rm -rf $PERSISTENCE_FOLDER - - mkdir -p $PERSISTENCE_FOLDER - - if [ -d "$KOGITO_EXAMPLE_PERSISTENCE" ] - then - cp $KOGITO_EXAMPLE_PERSISTENCE/*.proto $PERSISTENCE_FOLDER/ - else - echo "$KOGITO_EXAMPLE_PERSISTENCE does not exist. Have you compiled the project? mvn clean install -DskipTests -P$DB" - exit 1 - fi -fi +echo "Have you compiled the project before with the right profile: ../mvn clean install -DskipTests -Ppostgresql" SVG_FOLDER=./svg @@ -83,4 +52,4 @@ else exit 1 fi -docker-compose -f docker-compose-$DB.yml up +docker-compose -f docker-compose-postgresql.yml up diff --git a/kogito-quarkus-examples/process-usertasks-timer-quarkus/pom.xml b/kogito-quarkus-examples/process-usertasks-timer-quarkus/pom.xml index 2e28a070fa..c01f2cb331 100644 --- a/kogito-quarkus-examples/process-usertasks-timer-quarkus/pom.xml +++ b/kogito-quarkus-examples/process-usertasks-timer-quarkus/pom.xml @@ -152,50 +152,6 @@ true - - - org.kie - kie-addons-quarkus-persistence-infinispan - - - - - infinispan - - infinispan - true - - - - org.kie - kie-addons-quarkus-persistence-infinispan - - - - - - maven-antrun-plugin - - - package - - run - - - - - - - - - - - - - - - - postgresql diff --git a/kogito-quarkus-examples/process-usertasks-timer-quarkus/src/main/resources/application.properties b/kogito-quarkus-examples/process-usertasks-timer-quarkus/src/main/resources/application.properties index 0fb8c5fa1e..5460e661aa 100644 --- a/kogito-quarkus-examples/process-usertasks-timer-quarkus/src/main/resources/application.properties +++ b/kogito-quarkus-examples/process-usertasks-timer-quarkus/src/main/resources/application.properties @@ -64,8 +64,4 @@ kogito.jobs-service.url=http://localhost:8580 %postgresql.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/kogito %postgresql.kie.flyway.enabled=true %postgresql.quarkus.kogito.devservices.enabled=false - -%infinispan.kogito.persistence.type=infinispan -%infinispan.quarkus.infinispan-client.hosts=localhost:11222 -%infinispan.quarkus.infinispan-client.use-auth=false -%infinispan.quarkus.kogito.devservices.enabled=false \ No newline at end of file +%postgresql.quarkus.flyway.migrate-at-start=true diff --git a/kogito-springboot-examples/dmn-15-springboot-example/src/main/resources/application.properties b/kogito-springboot-examples/dmn-15-springboot-example/src/main/resources/application.properties index fcbf5c6501..df5f5d2678 100644 --- a/kogito-springboot-examples/dmn-15-springboot-example/src/main/resources/application.properties +++ b/kogito-springboot-examples/dmn-15-springboot-example/src/main/resources/application.properties @@ -19,4 +19,20 @@ # Packaging -server.address=0.0.0.0 \ No newline at end of file +server.address=0.0.0.0 +action=$1 + +if [ "${action}" == "uninstall" ]; then + echo "*** uninstalling task console" + oc delete all,configmap --selector app=kogito-task-console -n $(getProjectName) + +elif [ "${action}" == "install" ]; then + echo "*** installing task console" + oc new-app docker.io/apache/incubator-kie-kogito-task-console:${KOGITO_VERSION} -n $(getProjectName) $(dryRun "NewApp") + waitForPod kogito-task-console + oc patch deployment kogito-task-console --patch "$(cat deployment-patch.yaml)" -n $(getProjectName) $(dryRun) + waitForPod kogito-task-console + oc expose service/kogito-task-console -n $(getProjectName) $(dryRun) +else + echo "*** no such action: $action" +fi diff --git a/kogito-springboot-examples/dmn-tracing-springboot/README.md b/kogito-springboot-examples/dmn-tracing-springboot/README.md index 508b4df195..7e992a4f17 100644 --- a/kogito-springboot-examples/dmn-tracing-springboot/README.md +++ b/kogito-springboot-examples/dmn-tracing-springboot/README.md @@ -109,5 +109,3 @@ Example response: ## Integration example with Trusty Service When the tracing addon is enabled, the tracing events are emitted and pushed to a Kafka broker. The [Trusty Service](https://github.com/apache/incubator-kie-kogito-apps/tree/main/trusty) can consume such events and store them on a storage. The Trusty Service exposes then some api to consume the information that has been collected. -A `docker-compose` example is provided in the current folder. In particular, when `docker-compose up` is run, a Kafka broker, an Infinispan container and the nightly build of the trusty service are deployed. -Once the services are up and running, after a decision has been evaluated, you can access the trusty service swagger at `localhost:8081/swagger-ui.html` and try to query what are the evaluations of the last day at `localhost:8081/v1/executions` for example. diff --git a/kogito-springboot-examples/dmn-tracing-springboot/docker-compose.yml b/kogito-springboot-examples/dmn-tracing-springboot/docker-compose.yml deleted file mode 100644 index 9edd2032e0..0000000000 --- a/kogito-springboot-examples/dmn-tracing-springboot/docker-compose.yml +++ /dev/null @@ -1,76 +0,0 @@ -# -# 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. -# - -version: '2' - -services: - - zookeeper: - image: wurstmeister/zookeeper:3.4.6 - ports: - - "2181:2181" - environment: - LOG_DIR: "/tmp/logs" - - kafka: - image: wurstmeister/kafka:2.12-2.2.1 - depends_on: - - zookeeper - ports: - - "9092:9092" - expose: - - "9093" - environment: - KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9093,OUTSIDE://localhost:9092 - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT - KAFKA_LISTENERS: INSIDE://0.0.0.0:9093,OUTSIDE://0.0.0.0:9092 - KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 - KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE - LOG_DIR: "/tmp/logs" - - kafdrop: - image: obsidiandynamics/kafdrop - depends_on: - - kafka - ports: - - "9000:9000" - environment: - KAFKA_BROKERCONNECT: "kafka:9093" - JVM_OPTS: "-Xms32M -Xmx64M" - SERVER_SERVLET_CONTEXTPATH: "/" - - infinispan: - image: infinispan/server:14.0.4.Final - expose: - - "11222" - command: "-c infinispan-demo.xml" - volumes: - - ./docker-compose/infinispan/infinispan.xml:/opt/infinispan/server/conf/infinispan-demo.xml:z - - trusty: - image: quay.io/kiegroup/kogito-trusty-nightly:latest - depends_on: - - kafka - - infinispan - ports: - - "8081:8080" - environment: - QUARKUS_INFINISPAN_CLIENT_HOSTS: infinispan:11222 - QUARKUS_INFINISPAN_CLIENT_USE_AUTH: "false" - KAFKA_BOOTSTRAP_SERVERS: kafka:9093 diff --git a/kogito-springboot-examples/dmn-tracing-springboot/docker-compose/infinispan/infinispan.xml b/kogito-springboot-examples/dmn-tracing-springboot/docker-compose/infinispan/infinispan.xml deleted file mode 100644 index 49b57f7d93..0000000000 --- a/kogito-springboot-examples/dmn-tracing-springboot/docker-compose/infinispan/infinispan.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/kogito-springboot-examples/process-monitoring-springboot/Dockerfile b/kogito-springboot-examples/process-monitoring-springboot/Dockerfile index 423ef68398..56589a34ed 100644 --- a/kogito-springboot-examples/process-monitoring-springboot/Dockerfile +++ b/kogito-springboot-examples/process-monitoring-springboot/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 registry.access.redhat.com/ubi9/openjdk-17:1.20 +FROM --platform=linux/amd64 registry.access.redhat.com/ubi9/openjdk-17:latest ENV RUNTIME_TYPE springboot diff --git a/serverless-workflow-examples/serverless-workflow-callback-quarkus/docker-compose/docker-compose.yml b/serverless-workflow-examples/serverless-workflow-callback-quarkus/docker-compose/docker-compose.yml index 14e0bdd7e9..cc16677656 100644 --- a/serverless-workflow-examples/serverless-workflow-callback-quarkus/docker-compose/docker-compose.yml +++ b/serverless-workflow-examples/serverless-workflow-callback-quarkus/docker-compose/docker-compose.yml @@ -83,7 +83,7 @@ services: data-index: container_name: data-index - image: quay.io/kiegroup/kogito-data-index-postgresql-nightly:latest + image: docker.io/apache/incubator-kie-kogito-data-index-postgresql:main ports: - "8180:8080" depends_on: diff --git a/serverless-workflow-examples/serverless-workflow-data-index-persistence-addon-quarkus/docker-compose/docker-compose.yml b/serverless-workflow-examples/serverless-workflow-data-index-persistence-addon-quarkus/docker-compose/docker-compose.yml index f6e0697dfd..1dcda58c89 100644 --- a/serverless-workflow-examples/serverless-workflow-data-index-persistence-addon-quarkus/docker-compose/docker-compose.yml +++ b/serverless-workflow-examples/serverless-workflow-data-index-persistence-addon-quarkus/docker-compose/docker-compose.yml @@ -30,7 +30,7 @@ services: data-index: container_name: data-index - image: quay.io/kiegroup/kogito-data-index-postgresql-nightly:latest + image: docker.io/apache/incubator-kie-kogito-data-index-postgresql:main ports: - "8180:8080" depends_on: diff --git a/serverless-workflow-examples/serverless-workflow-data-index-quarkus/docker-compose/docker-compose-with-data-index.yml b/serverless-workflow-examples/serverless-workflow-data-index-quarkus/docker-compose/docker-compose-with-data-index.yml index accb9a8cbb..43b4876520 100644 --- a/serverless-workflow-examples/serverless-workflow-data-index-quarkus/docker-compose/docker-compose-with-data-index.yml +++ b/serverless-workflow-examples/serverless-workflow-data-index-quarkus/docker-compose/docker-compose-with-data-index.yml @@ -49,7 +49,7 @@ services: data-index: container_name: data-index - image: quay.io/kiegroup/kogito-data-index-postgresql-nightly:latest + image: docker.io/apache/incubator-kie-kogito-data-index-postgresql:main ports: - "8180:8080" depends_on: diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/.gitignore b/serverless-workflow-examples/serverless-workflow-github-showcase/.gitignore deleted file mode 100644 index 09204ba263..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# we don't want sensible information to get exposed -*.der -*.pem \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/README.md b/serverless-workflow-examples/serverless-workflow-github-showcase/README.md deleted file mode 100644 index 177d40b34f..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/README.md +++ /dev/null @@ -1,84 +0,0 @@ -**DEPRECATION NOTICE** - -> This example has a few old concepts from architecture and integration perspective. [We are working on an updated version of this example](https://issues.redhat.com/browse/KOGITO-8169). Until there, please try our other examples in this directory. -> In case you still need to run it, latest Kogito version which worked was KOGITO 1.29.0.Final. - -## Serverless Workflow GitHub Showcase - -In this example we will deploy a GitHub "bot" application that will -react upon a new PR being opened in a given GitHub project. -The "bot" is implemented via service and event orchestration approach with Kogito -implementation of the [Serverless Workflow specification](https://github.com/serverlessworkflow/specification). - -The image below illustrates an overview of the architecture: - -![](docs/github-showcase-architecture-overview.png) - -The implementation relies on three services included in this repository: - -1. [**Pull Request Checker Workflow**](pr-checker-workflow): it will coordinate the changes in the PR -opened in a given GitHub repository. Depending on the files changed in the project, -different labels and reviewers will be automatically added in the PR. In the end of -the workflow, the service will broadcast a "PR Verified" event to the cluster. -2. [**GitHub API Wrapper Service**](github-service): calling the GitHub API as a GitHub Application -requires a token to be generated on a small timeframe. This service generates a valid -token each 5 minutes to make calls to the API. Besides token management, it wraps -the API and simplifies its interface just for the sake of this example. -3. [**Notification Service**](notification-service): a simple Camel service to interact with the Slack API to -notify a given channel. - -### Prerequisites - -> **IMPORTANT!** Before proceeding, please make sure you have everything listed in this section ready. - -You may use CRC or Minikube if you don't have a cluster available with cluster admin rights. -Or you can ask an administrator to install the prerequisites for you. - -To deploy this example in your Kubernetes/OpenShift cluster, you will need: - -1. A [Quay.io](https://quay.io/repository/) account -2. A Kubernetes/OpenShift namespace to deploy the example: `kubectl create ns kogito-github` or `oc new-project kogito-github -3. [**Istio**](https://istio.io/docs/setup/install/istioctl/) installed because it's [required by Knative platform](https://knative.dev/docs/install/). -You can follow the [Knative documentation](https://knative.dev/docs/install/serving/installing-istio/) for a very basic and simple installation. -4. **Knative** Serving and Eventing components installed. -We recommend [installing the Knative Operator](https://knative.dev/docs/install/knative-with-operators/) and install the rest of the components -through it as described in their documentation. -5. **Kogito Operator** installed in the namespace `kogito-github`. [Download the latest release](https://github.com/apache/incubator-kie-kogito-operator/releases), and run: `NAMESPACE=kogito-github ./hack/install.sh`. -Alternatively, you can also install it via [OperatorHub](https://operatorhub.io/operator/kogito-operator). - -In your local machine you will need: - -1. To clone this repository and go to `serverless-workflow-github-showcase` directory (`git clone https://github.com/apache/incubator-kie-kogito-examples.git && cd serverless-workflow-github-showcase`) -2. [Java 17 SDK](https://openjdk.java.net/install/) -3. [Maven 3.8.1+](https://maven.apache.org/install.html) -4. [Podman](https://podman.io/getting-started/installation.html) or Docker to build the images -5. `kubectl` or `oc` client - -### Deploying the examples - -Follow the instructions for each service to try them locally as standalone services -and deploy them in your Kubernetes or OpenShift cluster: - -1. [GitHub Service](github-service/README.md) -2. [Notification Service](notification-service/README.md) -3. [PR Checker SW Service](pr-checker-workflow/README.md) - -Knative and Kogito will bind them together. :heart: - -In case of any problems, please file an issue or reach out to us at the [Kogito Dev Mailing list](https://groups.google.com/forum/?authuser=0#!aboutgroup/kogito-development). - -### Cleaning up - -You can easily clean up the demo by deleting the namespace: - -```shell script -kubectl delete ns kogito-github -``` - -To clean up your `/etc/hosts` file, run the following script: - -```shell script -./scripts/cleanup-hosts-file.sh -``` - -It will remove all the lines added by the `expose-on-minikube.sh` script while deploying the services. \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/docs/github-showcase-architecture-overview.png b/serverless-workflow-examples/serverless-workflow-github-showcase/docs/github-showcase-architecture-overview.png deleted file mode 100644 index 83541f10bb03504b35548cb8e36e8482dfcb9370..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72050 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 IEz5KN0}6vCCIA2c diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/.gitignore b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/.gitignore deleted file mode 100644 index 90ea0d2b0c..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -kubernetes/apply_image_ns.yaml -kubernetes/github-app.env \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/Dockerfile b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/Dockerfile deleted file mode 100644 index 543e03ca3d..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/Dockerfile +++ /dev/null @@ -1,32 +0,0 @@ -FROM registry.access.redhat.com/ubi8/ubi-minimal:latest - -ARG JAVA_PACKAGE=java-11-openjdk-headless -ARG RUN_JAVA_VERSION=1.3.5 - -ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' - -# Install java and the run-java script -# Also set up permissions for user `1001` -RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \ - && microdnf update \ - && microdnf clean all \ - && mkdir /deployments \ - && chown 1001 /deployments \ - && chmod "g+rwX" /deployments \ - && chown 1001:root /deployments \ - && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \ - && chown 1001 /deployments/run-java.sh \ - && chmod 540 /deployments/run-java.sh \ - && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security - -# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size. -ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" - -COPY target/lib/* /deployments/lib/ -COPY target/*-runner.jar /deployments/app.jar - -EXPOSE 8080 -EXPOSE 3000 -USER 1001 - -ENTRYPOINT [ "/deployments/run-java.sh" ] \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/README.md b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/README.md deleted file mode 100644 index 6b0b880f3a..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/README.md +++ /dev/null @@ -1,196 +0,0 @@ -## GitHub API Wrapper Service - -This service's responsibility is to manage GitHub API calls and to provide authentication -tokens every 5 minutes to make valid calls to the App API. It exposes three REST functions to interact with -the GitHub API. The table below lists the provided endpoints: - -| Function | Endpoint | Description | -|----------|----------|-------------| -| Add Labels | POST `/repo/{user}/{repository}/pr/{id}/labels` | Adds a list of labels to the given Pull Request | -| Add Reviewers | POST `/repo/{user}/{repository}/pr/{id}/reviewers` | Adds a list of reviewers the the given Pull Request | -| Get changed files | GET `/repo/{user}/{repository}/pr/{id}/files` | Fetches for the changed files in a given Pull Request | - -### Configuring your GitHub App - -For this service to work, you will need to create a new GitHub App and install it -in one or more repositories to be able to make changes to its PRs or Issues. - -By creating a GitHub App, it will provide a private key which can be used by this -service to interact with the GitHub API. - -#### Creating a new GitHub App - -[Follow the GitHub documentation](https://docs.github.com/en/developers/apps/setting-up-your-development-environment-to-create-a-github-app) to create a new GitHub App and -a private key. - -When asked to set permissions, choose "Access: Read & Write" for **Issues** and **Pull Requests**. Then, in "Subscribe to Events" section set "Pull request". -This way you will be able to make changes in the repositories' PRs where you've installed the GitHub App. - -After creating the private key, download it locally in somewhere safe. - -#### Converting the generated private key - -Convert the downloaded private key from PEM to DER format with the following command: - -```shell-script -openssl pkcs8 -topk8 -inform PEM -outform DER -in ~/github-api-app.private-key.pem -out ~/github-api-app.private-key.der -nocrypt -``` - -Replace the file `~/github-api-app.private-key.pem` with your local path. - -This will generate a private key in DER format which we will use to generate the GitHub -API tokens on demand. - -#### Installing the App in one or more repositories - -It's recommended to install the GitHub App in a test repository to not mess with -your account or organizations. - -Create a new repository, then go to your [Developer Settings](https://github.com/settings/apps), -click on "Edit" button next to your GitHub App, then click on "Install App", choose your account and install it in the test repository you just created. - -### Trying the service locally - -Now you have the GitHub App, a test repository and a private key. It's time to try -the application locally. - -Clone this repo if you haven't yet, edit the file [`src/main/resources/application.properties`](src/main/resources/application.properties) -and add the following data: - -```properties -org.kogito.examples.sw.github.service.key= -org.kogito.examples.sw.github.service.installation_id= -org.kogito.examples.sw.github.service.app_id= -``` - -Replace `` with the absolute path of the converted private key file (DER format). - -`` can be grabbed in the [Installations Dashboard](https://github.com/settings/installations/). -Just click in "Configure" button next to the app name, and you will be redirected to the Installation page. -The installation id is in the end of the URL, e.g.: `https://github.com/settings/installations/12345`. - -The `` is the number displayed in the App Dashboard. -Click in the "App settings" link to be redirected to the dashboard. - -Having everything in place, start the Quarkus application with the following command: - -```shell script -mvn clean quarkus:dev -``` - -Then access the Swagger UI to play around with the API: http://localhost:8080/swagger-ui - -:warning: **Important**: - -1. Open a test PR to have some data to play with -2. Invite a friend to be a contributor to your repo, so you can make the service request for their review in the PRs :kissing: - -### Deploying on Kubernetes - -> **IMPORTANT! :warning:** we assume you have read the prerequisites section in the main -> [README file](../README.md). Please follow those instructions before continuing. - -**Heads up!** This service will be deployed as a Knative Service instead of a regular Kubernetes -Deployment. - -To make things easier there is a [script in this directory](deploy-kubernetes.sh) to generate the template -files, build the application and the image, and then deploy it to your Kubernetes cluster. - -**IMPORTANT!** You **must** be authenticated to the target Kubernetes cluster as a **cluster administrator** for this script -to work. - -You can run the script once and all the required files will be generated in the `kubernetes` directory, -and the image will be published to your Quay.io account. - -Fill the value for the variables as shown below and run the script: - -```shell script -# the script accepts positional arguments as following: -QUAY_NAMESPACE= -APP_ID= -INSTALLATION_ID= -DER_FILE= - -./deploy-kubernetes.sh $QUAY_NAMESPACE $APP_ID $INSTALLATION_ID $DER_FILE -``` - -You should see a similar output like this: - -

Build logs -``` -// build logs surpressed ----> Building and pushing image using tag quay.io/ricardozanini/github-service:latest -STEP 1: FROM adoptopenjdk:11-jre-hotspot -STEP 2: RUN mkdir -p /opt/app/lib ---> Using cache 26183c5ad8a51a030030a250db0c99e649fdd9668ef4766d0b66782d0dad7573 -STEP 3: COPY target/github-service-999-SNAPSHOT-runner.jar /opt/app ---> 31bc2627d32 -STEP 4: COPY target/lib/*.jar /opt/app/lib ---> 62eae5cdde7 -STEP 5: CMD ["java", "-jar", "/opt/app/github-service-999-SNAPSHOT-runner.jar"] -STEP 6: COMMIT quay.io/ricardozanini/github-service:latest ---> 7c555a3060c -7c555a3060c666582824552d8824f2787b59b67b506fb933b171764bde894730 -Getting image source signatures -Copying config 7c555a3060 [--------------------------------------] 0.0b / 6.2KiB -Writing manifest to image destination -Writing manifest to image destination -Storing signatures ----> Applying objects to the cluster in the namespace kogito-github. -configmap/github-service-properties unchanged -secret/github-app-ids unchanged -secret/github-app-key unchanged -service.serving.knative.dev/github-service configured -``` -
- -To verify if the service have been correctly deployed run: - -``` -$ kubectl get ksvc github-service -n kogito-github - -NAME URL LATESTCREATED LATESTREADY READY REASON -github-service http://github-service.kogito-github.example.com github-service-7frvw github-service-7frvw True -``` - -The `READY` column should be true. - -#### Exposing the service on Minikube - -If you're running on another cluster than Minikube, the service's route exposed by Knative Serving probably is accessible to you. -On Minikube there are some additional steps to be made. - -Run a new terminal window: - -```shell script -minikube tunnel -``` - -Leave the process executing and then execute: - -```shell script -./expose-on-minikube.sh -``` - -This script will fetch the Minikube IP exposed by the `tunnel` command and add the route to your local `/etc/hosts` file. - -You can then access the service via the service URL: - -``` -$ kubectl get ksvc github-service -n kogito-github --output jsonpath="{.status.url}" - -http://github-service.kogito-github.example.com -``` - -As we did when running through the `jar` file, we can access the Swagger UI and play around with the API: - -http://github-service.kogito-github.example.com/swagger-ui - -The first query may take a little time to return since Knative will start the service's pod on demand. -After some time the pod will just terminate. - -Congratulations! The GitHub functions is now available in the cluster ready to be consumed by the Kogito Workflow. - -### Cleaning up! - -See the project root's [README](./README.md) documentation. \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/configure.sh b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/configure.sh deleted file mode 100755 index cc56960a8b..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/configure.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/bash -# -# 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. -# - -QUAY_NAMESPACE=$1 -APP_ID=$2 -INSTALLATION_ID=$3 -DER_FILE=$4 - -CURR_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -# shellcheck source=../scripts/common.sh -source "${CURR_DIR}/../scripts/common.sh" - -function print_usage() { - echo "---> Script to deploy the GitHub service to the Kubernetes cluster. Usage:" - echo "---> ./deploy-kubernetes.sh QUAY_NAMESPACE GITHUB_APP_ID INSTALLATION_ID PATH_FOR_DER_FILE" - echo "---> Example: " - echo "---> ./deploy-kubernetes.sh namespace 12345 56788 /path/to/the/private_key.der" -} - -function verify_input() { - local return_code=0 - if [ -z "${QUAY_NAMESPACE}" ]; then - echo "---> Quay namespace not set" - return_code=1 - fi - - if [ -z "${APP_ID}" ]; then - echo "---> GitHub Application ID not set" - return_code=1 - fi - - if [ -z "${INSTALLATION_ID}" ]; then - echo "---> GitHub Application Installation ID not set" - return_code=1 - fi - - if [ -z "${DER_FILE}" ]; then - echo "---> DER file not set" - return_code=1 - elif [ ! -f "${DER_FILE}" ]; then - echo "---> DER file ${DER_FILE} does not exist, make sure that the file informed is correct" - return_code=1 - fi - - return ${return_code} -} - -function apply_vars() { - cp ./kubernetes/apply_image_ns.yaml.tpl ./kubernetes/apply_image_ns.yaml - cp ./kubernetes/github-app.env.tpl ./kubernetes/github-app.env - - sed -i "s/{QUAY_NAMESPACE}/${QUAY_NAMESPACE}/g" ./kubernetes/apply_image_ns.yaml - sed -i "s/{APP_ID}/${APP_ID}/g" ./kubernetes/github-app.env - sed -i "s/{INSTALLATION_ID}/${INSTALLATION_ID}/g" ./kubernetes/github-app.env -} - -if ! verify_input; then - print_usage - exit -fi - -if ! check_binaries; then - echo "---> exiting installation script, not all required binaries have been found in your system" - exit -fi - -apply_vars - -# copy DER file -cp "${DER_FILE}" ./kubernetes/github-app-key.der diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/deploy-kubernetes.sh b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/deploy-kubernetes.sh deleted file mode 100755 index f1f9170ae8..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/deploy-kubernetes.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# -# 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. -# - -source ./configure.sh - -echo "---> Building application" -mvn clean install -DskipTests - -build_push_image "${QUAY_NAMESPACE}" "github-service" - -echo "---> Applying objects to the cluster in the namespace kogito-github." -kubectl apply -k ./kubernetes diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/expose-on-minikube.sh b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/expose-on-minikube.sh deleted file mode 100755 index a83f22f628..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/expose-on-minikube.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# -# 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. -# - -CURR_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -# shellcheck source=../scripts/add-route-to-hosts.sh -source "${CURR_DIR}/../scripts/add-route-to-hosts.sh" github-service diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/00-deployment.yaml b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/00-deployment.yaml deleted file mode 100644 index 024e999500..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/00-deployment.yaml +++ /dev/null @@ -1,53 +0,0 @@ -# -# 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. -# - -apiVersion: serving.knative.dev/v1 # Current version of Knative (0.17.x) -kind: Service -metadata: - name: github-service -spec: - template: - spec: - containers: - - env: - - name: APP_ID - valueFrom: - secretKeyRef: - key: githubAppId - name: github-app-ids - - name: INSTALLATION_ID - valueFrom: - secretKeyRef: - key: githubInstallationId - name: github-app-ids - image: image_placeholder - volumeMounts: - - name: github-app-key - mountPath: "/opt/data" - readOnly: true - - name: properties - mountPath: "/config/application.properties" - subPath: application.properties - volumes: - - name: github-app-key - secret: - secretName: github-app-key - - name: properties - configMap: - name: github-service-properties \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/application.properties b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/application.properties deleted file mode 100644 index 774b09b106..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/application.properties +++ /dev/null @@ -1,22 +0,0 @@ -# -# 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. -# - -org.kogito.examples.sw.github.service.key=/opt/data/github-app-key.der -org.kogito.examples.sw.github.service.installation_id=${INSTALLATION_ID} -org.kogito.examples.sw.github.service.app_id=${APP_ID} \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/apply_image_ns.yaml.tpl b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/apply_image_ns.yaml.tpl deleted file mode 100644 index 6b432c037f..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/apply_image_ns.yaml.tpl +++ /dev/null @@ -1,3 +0,0 @@ -- op: replace - path: /spec/template/spec/containers/0/image - value: quay.io/{QUAY_NAMESPACE}/github-service:latest \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/github-app.env.tpl b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/github-app.env.tpl deleted file mode 100644 index 972a4ed45e..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/github-app.env.tpl +++ /dev/null @@ -1,2 +0,0 @@ -githubAppId={APP_ID} -githubInstallationId={INSTALLATION_ID} \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/kustomization.yaml b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/kustomization.yaml deleted file mode 100644 index d805e98a60..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/kubernetes/kustomization.yaml +++ /dev/null @@ -1,45 +0,0 @@ -# -# 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. -# - -namespace: kogito-github -resources: - - 00-deployment.yaml -patchesJson6902: - - path: apply_image_ns.yaml - target: - kind: Service - name: github-service - version: v1 - group: serving.knative.dev -generatorOptions: - disableNameSuffixHash: true - labels: - app: github-service -configMapGenerator: - - files: - - application.properties - name: github-service-properties -secretGenerator: - - env: github-app.env - name: github-app-ids - type: Opaque - - files: - - github-app-key.der - name: github-app-key - type: Opaque \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/pom.xml b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/pom.xml deleted file mode 100644 index fa3f5adca9..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/pom.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - - 4.0.0 - - org.kie.kogito.examples - serverless-workflow-github-showcase - 1.0-SNAPSHOT - - github-service - Kogito Example :: Serverless Workflow Github Showcase :: GitHub Service - - true - 2.13.1.Final - quarkus-bom - io.quarkus - 2.13.1.Final - 3.8.1 - 17 - - - - - ${quarkus.platform.group-id} - ${quarkus.platform.artifact-id} - ${quarkus.platform.version} - pom - import - - - - - - io.quarkus - quarkus-resteasy - - - io.quarkus - quarkus-resteasy-jackson - - - io.quarkus - quarkus-cache - - - io.quarkus - quarkus-smallrye-openapi - - - - io.jsonwebtoken - jjwt-api - ${version.io.jjwt} - - - io.jsonwebtoken - jjwt-impl - ${version.io.jjwt} - - - io.jsonwebtoken - jjwt-jackson - ${version.io.jjwt} - - - org.kohsuke - github-api - ${version.kohsuke.github} - - - io.quarkus - quarkus-junit5 - test - - - io.rest-assured - rest-assured - test - - - io.quarkus - quarkus-smallrye-health - - - - - - maven-compiler-plugin - ${version.compiler.plugin} - - ${maven.compiler.release} - - - - maven-surefire-plugin - ${version.surefire.plugin} - - - org.jboss.logmanager.LogManager - ${maven.home} - - - - - io.smallrye - jandex-maven-plugin - ${jandex-plugin.version} - - - make-index - - jandex - - - - - - ${quarkus.platform.group-id} - quarkus-maven-plugin - ${quarkus-plugin.version} - - - - build - - - - - - - - - - container - - - container - - - - container - - - - io.quarkus - quarkus-container-image-jib - - - - - diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/GitHubResource.java b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/GitHubResource.java deleted file mode 100644 index cfdec8f5fb..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/GitHubResource.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.service; - -import java.util.List; - -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -@Path("/repo") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class GitHubResource { - - @Inject - GitHubWrapperService gitHubService; - - @POST - @Path("/{user}/{name}/pr/{number}/labels") - public Response addLabels(@PathParam("user") String user, - @PathParam("name") String repoName, - @PathParam("number") Integer prNumber, - List labels) { - try { - gitHubService.addLabels(user, repoName, prNumber, labels); - return Response.ok().build(); - } catch (final Exception e) { - return Response.serverError().entity(e.getMessage()).build(); - } - } - - @POST - @Path("/{user}/{name}/pr/{number}/reviewers") - public Response addReviewers(@PathParam("user") String user, - @PathParam("name") String repoName, - @PathParam("number") Integer prNumber, - List reviewers) { - try { - gitHubService.addReviewers(user, repoName, prNumber, reviewers); - return Response.ok().build(); - } catch (final Exception e) { - return Response.serverError().entity(e.getMessage()).build(); - } - } - - @GET - @Path("/{user}/{name}/pr/{number}/files") - public Response fetchFiles(@PathParam("user") String user, - @PathParam("name") String repoName, - @PathParam("number") Integer prNumber) { - try { - return Response.ok().entity(gitHubService.fetchChangedFilesPath(user, repoName, prNumber)).build(); - } catch (final Exception e) { - return Response.serverError().entity(e.getMessage()).build(); - } - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/GitHubWrapperService.java b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/GitHubWrapperService.java deleted file mode 100644 index 3f54d5bc21..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/GitHubWrapperService.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.service; - -import java.util.List; - -public interface GitHubWrapperService { - - /** - * Adds labels to the given issue (can also be a PR in GitHub context) - * - * @param user owner of the repository - * @param repository name of the repository - * @param issueId identification of the issue - * @param labels list with the labels to add - * @throws Exception in case something goes wrong - */ - void addLabels(String user, String repository, int issueId, List labels) throws Exception; - - /** - * Adds reviewers to the given PR - * - * @param user owner of the repository - * @param repository name of the repository - * @param prId identification of the PR - * @param reviewers list with the reviewers to be added - * @throws Exception in case something goes wrong - */ - void addReviewers(String user, String repository, int prId, List reviewers) throws Exception; - - /** - * Fetches the files changed in a given PR - * - * @param user owner of the repository - * @param repository name of the repository - * @param prId identification of the PR - * @return list of files changed in this PR - * @throws Exception in case something goes wrong - */ - List fetchChangedFilesPath(String user, String repository, int prId) throws Exception; -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/GitHubWrapperServiceImpl.java b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/GitHubWrapperServiceImpl.java deleted file mode 100644 index a4cc3de7c4..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/GitHubWrapperServiceImpl.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.service; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; - -import org.kohsuke.github.GHPullRequestFileDetail; -import org.kohsuke.github.GHUser; -import org.kohsuke.github.GitHub; -import org.kohsuke.github.GitHubBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@ApplicationScoped -public class GitHubWrapperServiceImpl implements GitHubWrapperService { - - private static final Logger LOGGER = LoggerFactory.getLogger(GitHubWrapperServiceImpl.class); - - @Inject - TokenProvider tokenProvider; - - public GitHubWrapperServiceImpl() { - } - - public void addLabels(String user, String repository, int issueId, List labels) throws Exception { - LOGGER.info("Adding labels for the repo {}/{} issue {} labels {}", user, repository, issueId, labels); - final GitHub gitHub = new GitHubBuilder().withAppInstallationToken(tokenProvider.getToken()).build(); - gitHub.getRepository(toRepositoryName(user, repository)).getIssue(issueId).addLabels(labels.toArray(new String[] {})); - LOGGER.info("Labels {} added to the Issue/PR {}", labels, issueId); - } - - public void addReviewers(String user, String repository, int prId, List reviewers) throws Exception { - LOGGER.info("Adding reviewers for the repo {}/{} PR {} labels {}", user, repository, prId, reviewers); - final GitHub gitHub = new GitHubBuilder().withAppInstallationToken(tokenProvider.getToken()).build(); - gitHub - .getRepository(toRepositoryName(user, repository)) - .getPullRequest(prId) - .requestReviewers(toUsers(gitHub, reviewers)); - LOGGER.info("Reviewers {} added to the PR {}", reviewers, prId); - } - - public List fetchChangedFilesPath(String user, String repository, int prId) throws Exception { - LOGGER.info("Fetching files for the repo {}/{} PR {}", user, repository, prId); - final List filesPath = new ArrayList<>(); - final GitHub gitHub = new GitHubBuilder().withAppInstallationToken(tokenProvider.getToken()).build(); - for (GHPullRequestFileDetail ghPullRequestFileDetail : gitHub - .getRepository(toRepositoryName(user, repository)) - .getPullRequest(prId) - .listFiles()) { - filesPath.add(ghPullRequestFileDetail.getFilename()); - } - LOGGER.info("Fetched files {} for PR {}", filesPath, prId); - return filesPath; - } - - private String toRepositoryName(String user, String repository) { - return user.concat("/").concat(repository); - } - - private List toUsers(final GitHub gitHub, final List userIds) throws IOException { - final List users = new ArrayList<>(); - if (userIds != null) { - for (String u : userIds) { - users.add(gitHub.getUser(u)); - } - } - return users; - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/TokenProvider.java b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/TokenProvider.java deleted file mode 100644 index 663770bdf8..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/java/org/kogito/examples/sw/github/service/TokenProvider.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.service; - -import java.io.File; -import java.io.IOException; -import java.security.Key; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import javax.enterprise.context.ApplicationScoped; - -import org.apache.commons.io.FileUtils; -import org.eclipse.microprofile.config.inject.ConfigProperty; -import org.kohsuke.github.GHAppInstallation; -import org.kohsuke.github.GHPermissionType; -import org.kohsuke.github.GitHub; -import org.kohsuke.github.GitHubBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.jsonwebtoken.JwtBuilder; -import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.impl.DefaultJwtBuilder; -import io.jsonwebtoken.jackson.io.JacksonSerializer; -import io.quarkus.cache.CacheResult; - -/** - * Provides the installation token to interact with the GitHub API via GitHub App Installation - * - * @see GitHub App Authentication via JWT token - */ -@ApplicationScoped -public class TokenProvider { - - private static final Logger LOGGER = LoggerFactory.getLogger(TokenProvider.class); - - private static final int expirationMillis = 600000; - private static final int cacheExpirationMillis = 300000; - - @ConfigProperty(name = "org.kogito.examples.sw.github.service.app_id") - String appId; - - @ConfigProperty(name = "org.kogito.examples.sw.github.service.key") - String privateKeyPath; - - @ConfigProperty(name = "org.kogito.examples.sw.github.service.installation_id") - Long installationId; - - public TokenProvider() { - - } - - private PrivateKey getPrivateKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { - byte[] keyBytes = FileUtils.readFileToByteArray(new File(privateKeyPath)); - - PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); - KeyFactory kf = KeyFactory.getInstance("RSA"); - return kf.generatePrivate(spec); - } - - public String createJWT() throws NoSuchAlgorithmException, IOException, InvalidKeySpecException { - //The JWT signature algorithm we will be using to sign the token - SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RS256; - - long nowMillis = System.currentTimeMillis(); - Date now = new Date(nowMillis); - - //We will sign our JWT with our private key - Key signingKey = getPrivateKey(); - - // creating builder and serializer directly instead of relying on reflection for native use cases - //Let's set the JWT Claims - JwtBuilder builder = new DefaultJwtBuilder() - .setIssuedAt(now) - .setIssuer(appId) - .signWith(signingKey, signatureAlgorithm); - builder.serializeToJsonWith(new JacksonSerializer<>()); - - long expMillis = nowMillis + expirationMillis; - Date exp = new Date(expMillis); - builder.setExpiration(exp); - - //Builds the JWT and serializes it to a compact, URL-safe string - final String token = builder.compact(); - LOGGER.info("JWT token generated and signed successfully"); - return token; - } - - @CacheResult(cacheName = "access_token", lockTimeout = cacheExpirationMillis) - public String getToken() throws Exception { - final GitHub gitHubApp = new GitHubBuilder().withJwtToken(createJWT()).build(); - final GHAppInstallation appInstall = gitHubApp.getApp().getInstallationById(installationId); - LOGGER.info("Attempt to generate token to GH Account {}", appInstall.getAccount().getName()); - final String token = appInstall.createToken(getPermissions()).create().getToken(); - LOGGER.info("Final token generated successfully"); - return token; - } - - private Map getPermissions() { - final Map permissions = new HashMap<>(); - permissions.put("pull_requests", GHPermissionType.WRITE); - permissions.put("issues", GHPermissionType.WRITE); - return permissions; - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/resources/application.properties b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/resources/application.properties deleted file mode 100644 index 0abadfa507..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/main/resources/application.properties +++ /dev/null @@ -1,34 +0,0 @@ -# -# 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. -# - -# Packaging -# quarkus.package.type=fast-jar - -quarkus.swagger-ui.always-include=true -# for future reference, unfortunately the GitHub Client API library used in this -# project is not compatible with native builds out of the box -quarkus.native.enable-all-security-services=true -quarkus.native.enable-https-url-handler=true - -# profile to pack this example into a container, to use it execute activate the maven container profile, -Dcontainer -%container.quarkus.container-image.build=true -%container.quarkus.container-image.push=false -%container.quarkus.container-image.group=${USER} -%container.quarkus.container-image.registry=dev.local -%container.quarkus.container-image.tag=1.0-SNAPSHOT \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/java/org/kogito/examples/sw/github/service/GitHubResourceTest.java b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/java/org/kogito/examples/sw/github/service/GitHubResourceTest.java deleted file mode 100644 index 29aa76e014..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/java/org/kogito/examples/sw/github/service/GitHubResourceTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.service; - -import org.junit.jupiter.api.Test; - -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.http.ContentType; - -import static io.restassured.RestAssured.given; -import static org.hamcrest.Matchers.is; - -@QuarkusTest -class GitHubResourceTest { - - @Test - void addLabels() { - given().when() - .body("[ \"bug\", \"documentation\" ]") - .contentType(ContentType.JSON) - .post("/repo/john/amazing-repo/pr/1/labels") - .then() - .statusCode(200); - } - - @Test - void addReviewers() { - given().when() - .body("[ \"john\", \"jane\" ]") - .contentType(ContentType.JSON) - .post("/repo/john/amazing-repo/pr/1/reviewers") - .then() - .statusCode(200); - } - - @Test - void fetchFiles() { - given().when() - .get("/repo/john/amazing-repo/pr/1/files") - .then() - .statusCode(200) - .body(is("[\"myfile\"]")); - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/java/org/kogito/examples/sw/github/service/GitHubWrapperServiceIT.java b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/java/org/kogito/examples/sw/github/service/GitHubWrapperServiceIT.java deleted file mode 100644 index 91dcfae71d..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/java/org/kogito/examples/sw/github/service/GitHubWrapperServiceIT.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.service; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import javax.inject.Inject; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import io.quarkus.test.junit.QuarkusTest; - -import static org.junit.jupiter.api.Assertions.assertFalse; - -// This test is just to perform quick and dirty smoke tests against the API -// change the constants to your real repos if you need to give it a try -@Disabled -@QuarkusTest -class GitHubWrapperServiceIT { - - private static final String REPO_USER = ""; - private static final String REPO_NAME = ""; - private static final String REVIEWER = ""; - private static final int ISSUE_ID = 1; - private static final int PR_ID = 2; - - @Inject - GitHubWrapperServiceImpl service; - - @Test - void simpleAddLabelsCheck() throws Exception { - service.addLabels(REPO_USER, REPO_NAME, ISSUE_ID, Arrays.asList("bug", "documentation")); - } - - @Test - void simpleAddReviewersCheck() throws Exception { - service.addReviewers(REPO_USER, REPO_NAME, PR_ID, Collections.singletonList(REVIEWER)); - service.addLabels(REPO_USER, REPO_NAME, ISSUE_ID, Collections.singletonList("bug")); - } - - @Test - void simpleFetchChangedFilesCheck() throws Exception { - final List files = service.fetchChangedFilesPath(REPO_USER, REPO_NAME, PR_ID); - assertFalse(files.isEmpty()); - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/java/org/kogito/examples/sw/github/service/MockedGitHubWrapperService.java b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/java/org/kogito/examples/sw/github/service/MockedGitHubWrapperService.java deleted file mode 100644 index e92410095f..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/java/org/kogito/examples/sw/github/service/MockedGitHubWrapperService.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.service; - -import java.util.Collections; -import java.util.List; - -import javax.enterprise.context.ApplicationScoped; - -import io.quarkus.test.Mock; - -@Mock -@ApplicationScoped -public class MockedGitHubWrapperService extends GitHubWrapperServiceImpl { - - @Override - public void addLabels(String user, String repository, int issueId, List labels) { - - } - - @Override - public void addReviewers(String user, String repository, int prId, List reviewers) { - - } - - @Override - public List fetchChangedFilesPath(String user, String repository, int prId) { - return Collections.singletonList("myfile"); - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/resources/application.properties b/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/resources/application.properties deleted file mode 100644 index 7f88e44ff5..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/github-service/src/test/resources/application.properties +++ /dev/null @@ -1,25 +0,0 @@ -# -# 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. -# - -# see: https://github-api.kohsuke.org/githubappjwtauth.html -# if you wish, replace with your own data and enable the GitHubWrapperServiceIT test to verify if everything is working as expected in your environment -org.kogito.examples.sw.github.service.key=replace_with_your_key -org.kogito.examples.sw.github.service.installation_id=12345 -org.kogito.examples.sw.github.service.app_id=replace_with_app_id -quarkus.http.test-port=0 diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/.gitignore b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/.gitignore deleted file mode 100644 index 1d04a411ef..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# we don't want sensible information to get exposed -kubernetes/apply_image_ns.yaml -kubernetes/slack.env \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/Dockerfile b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/Dockerfile deleted file mode 100644 index 543e03ca3d..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/Dockerfile +++ /dev/null @@ -1,32 +0,0 @@ -FROM registry.access.redhat.com/ubi8/ubi-minimal:latest - -ARG JAVA_PACKAGE=java-11-openjdk-headless -ARG RUN_JAVA_VERSION=1.3.5 - -ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' - -# Install java and the run-java script -# Also set up permissions for user `1001` -RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \ - && microdnf update \ - && microdnf clean all \ - && mkdir /deployments \ - && chown 1001 /deployments \ - && chmod "g+rwX" /deployments \ - && chown 1001:root /deployments \ - && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \ - && chown 1001 /deployments/run-java.sh \ - && chmod 540 /deployments/run-java.sh \ - && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security - -# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size. -ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" - -COPY target/lib/* /deployments/lib/ -COPY target/*-runner.jar /deployments/app.jar - -EXPOSE 8080 -EXPOSE 3000 -USER 1001 - -ENTRYPOINT [ "/deployments/run-java.sh" ] \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/README.md b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/README.md deleted file mode 100644 index d9bed2ebf9..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/README.md +++ /dev/null @@ -1,162 +0,0 @@ -## Notification Service - -This service will listen to specific [CloudEvents](https://github.com/cloudevents/spec) published by our workflow and post -messages in a specific Slack channel using the event data as input. - -### Creating a new Slack App - -Like in the GitHub service procedure, we are going to need an API key from a third party -service. - -Go to [Slack API](https://api.slack.com/apps) page and create a new app -(or you can reuse one you already have instead). - -Once you create the app, go to the "Incoming WebHooks" menu and copy the "WebHook URL". - -Install the app in one of the Workspaces you have and create a "github-showcase" channel -there for the service to send some messages. Since it's a demo, you don't want to annoy people with lame -bot messages. :) - -### Trying the service locally - -Once you have the Slack App created and the WebHook, it's time to try the application locally. - -This service is just a plain Quarkus application with the [Camel Slack component](https://camel.apache.org/components/latest/slack-component.html) to communicate -with the Slack API. - -Copy the WebHook URL in the `src/main/resources/application.properties` file: - -```properties -# URL details not shown -org.kogito.examples.sw.notification.slack.incoming=https://hooks.slack.com/services/(...) -``` - -Run the application with: - -```shell script -$ mvn clean quarkus:dev -``` - -This service listens to the `/` (root) path for messages in [CloudEvents format](https://github.com/cloudevents/spec/blob/v1.0/spec.md#example), but -we added the `/plain` endpoint as well for testing purposes. Sending a request to this -endpoint will post a message in the `github-showcase` channel: - -```shell script -curl -X POST "http://localhost:8080/plain" -H "Content-Type: text/plain" -d "this is a test message" -``` - -As always, we included the Swagger UI in the service, access it at http:localhost:8080/swagger-ui/. - -### Deploying on Kubernetes - -> **HEADS UP!** delete the Slack WebHook from the `application.properties` file. -> We're going to build an image from the source, you don't want your credentials to be exposed to the world!! - -> **IMPORTANT! :warning:** we assume you have read the prerequisites section in the main -> [README file](../README.md). Please follow those instructions before continuing. - -**Heads up!** This service will be deployed as a Knative Service instead of a regular Kubernetes -Deployment. - -To make things easier there is a [script in this directory](deploy-kubernetes.sh) to generate the template -files, build the application and the image, and then deploy it to your Kubernetes cluster. - -**IMPORTANT!** You **must** be authenticated to the target Kubernetes cluster as a **cluster administrator** for this script -to work. - -You can run the script once and all the required files will be generated in the `kubernetes` directory, -and the image will be published to your Quay.io account. - -Fill the value for the variables as shown below and run the script: - -```shell script -# the script accepts positional arguments as following: -QUAY_NAMESPACE= -SLACK_WEBHOOK= - -./deploy-kubernetes.sh $QUAY_NAMESPACE $SLACK_WEBHOOK -``` - -You should see a similar output like this: - -
Build logs -``` -// build logs surpressed ----> Building and pushing image using tag quay.io/your_namespace/notification-service:latest -STEP 1: FROM adoptopenjdk:11-jre-hotspot -STEP 2: RUN mkdir -p /opt/app/lib ---> Using cache 26183c5ad8a51a030030a250db0c99e649fdd9668ef4766d0b66782d0dad7573 -STEP 3: COPY target/notification-service-999-SNAPSHOT-runner.jar /opt/app ---> 2a5b658411b -STEP 4: COPY target/lib/*.jar /opt/app/lib ---> 5fedac21977 -STEP 5: CMD ["java", "-jar", "/opt/app/notification-service-999-SNAPSHOT-runner.jar"] -STEP 6: COMMIT quay.io/your_namespace/notification-service:latest ---> afe502d1940 -afe502d1940d65f151c051008bb2057344607408c192787a726399d23d90c2d3 -Getting image source signatures -Copying config afe502d194 done -Writing manifest to image destination -Copying config afe502d194 [--------------------------------------] 0.0b / 6.2KiB -Writing manifest to image destination -Writing manifest to image destination -Storing signatures ----> Applying objects to the cluster in the namespace kogito-github. -configmap/notification-service-properties unchanged -secret/slack-ids configured -service.serving.knative.dev/notification-service configured -broker.eventing.knative.dev/default unchanged -trigger.eventing.knative.dev/notification-trigger unchanged -``` -
- -To verify if the service have been correctly deployed run: - -``` -$ kubectl get ksvc notification-service -n kogito-github - -NAME URL LATESTCREATED LATESTREADY READY REASON -notification-service http://notification-service.kogito-github.example.com notification-service-9mgww notification-service-9mgww True -``` - -The `READY` column should be true. - -#### Exposing the service on Minikube - -If you're running on another cluster than Minikube, the service's route exposed by Knative Serving probably is accessible to you. -On Minikube there are some additional steps to be made. - -Run a new terminal window: - -```shell script -minikube tunnel -``` - -Leave the process executing and then execute: - -```shell script -./expose-on-minikube.sh -``` - -This script will fetch the Minikube IP exposed by the `tunnel` command and add the route to your local `/etc/hosts` file. - -You can then access the service via the service URL: - -``` -$ kubectl get ksvc notification-service -n kogito-github --output jsonpath="{.status.url}" - -http://notification-service.kogito-github.example.com -``` - -As we did when running through the `jar` file, we can access the Swagger UI and play around with the API: - -http://notification-service.kogito-github.example.com/swagger-ui - -The first query may take a little time to return since Knative will start the service's pod on demand. -After some time the pod will just terminate. - -Congratulations! The Notification service is now available in the cluster ready to be consumed by the Kogito Workflow. - -### Cleaning up! - -See the project root's [README](./README.md) documentation. diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/configure.sh b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/configure.sh deleted file mode 100755 index e97ac0021a..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/configure.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash -# -# 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. -# - -QUAY_NAMESPACE=$1 -SLACK_WEBHOOK=$2 - -CURR_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -# shellcheck source=../scripts/common.sh -source "${CURR_DIR}/../scripts/common.sh" - -function print_usage() { - echo "---> Script to deploy the Notification service to the Kubernetes cluster. Usage:" - echo "---> ./deploy-kubernetes.sh QUAY_NAMESPACE SLACK_WEBHOOK" - echo "---> Example: " - echo "---> ./deploy-kubernetes.sh namespace " -} - -function verify_input() { - local return_code=0 - if [ -z "${QUAY_NAMESPACE}" ]; then - echo "---> Quay namespace not set" - return_code=1 - fi - - if [ -z "${SLACK_WEBHOOK}" ]; then - echo "---> Slack WebHook ID not set" - return_code=1 - fi - - return ${return_code} -} - -function apply_vars() { - cp ./kubernetes/apply_image_ns.yaml.tpl ./kubernetes/apply_image_ns.yaml - cp ./kubernetes/slack.env.tpl ./kubernetes/slack.env - - sed -i "s/{QUAY_NAMESPACE}/${QUAY_NAMESPACE}/g" ./kubernetes/apply_image_ns.yaml - sed -i "s,{SLACK_WEBHOOK},${SLACK_WEBHOOK},g" ./kubernetes/slack.env -} - -if ! verify_input; then - print_usage - exit -fi - -if ! check_binaries; then - echo "---> exiting installation script, not all required binaries have been found in your system" - exit -fi - -apply_vars \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/deploy-kubernetes.sh b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/deploy-kubernetes.sh deleted file mode 100755 index 442075b3e0..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/deploy-kubernetes.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -# -# 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. -# - -# imports.. - -source ./configure.sh - -echo "---> Building application" -mvn clean install -DskipTests - -build_push_image "${QUAY_NAMESPACE}" "notification-service" - -echo "---> Applying objects to the cluster in the namespace kogito-github." -kubectl apply -k ./kubernetes diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/00-broker.yaml b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/00-broker.yaml deleted file mode 100644 index bf70b4d2f1..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/00-broker.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# -# 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. -# - -# this is where all the messages coming to the cluster will pass -# we can use triggers and sinkbinding to route/filter the messages as we pleased -apiVersion: eventing.knative.dev/v1 -kind: Broker -metadata: - name: default diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/01-deployment.yaml b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/01-deployment.yaml deleted file mode 100644 index 2fd46a4b2e..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/01-deployment.yaml +++ /dev/null @@ -1,42 +0,0 @@ -# -# 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. -# - -apiVersion: serving.knative.dev/v1 # Current version of Knative (0.17.x) -kind: Service -metadata: - name: notification-service -spec: - template: - spec: - containers: - - env: - - name: SLACK_WEBHOOK - valueFrom: - secretKeyRef: - key: slackWebHook - name: slack-ids - image: image_placeholder - volumeMounts: - - name: properties - mountPath: "/config/application.properties" - subPath: application.properties - volumes: - - name: properties - configMap: - name: notification-service-properties \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/02-trigger.yaml b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/02-trigger.yaml deleted file mode 100644 index fef444bdf3..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/02-trigger.yaml +++ /dev/null @@ -1,36 +0,0 @@ -# -# 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. -# - -apiVersion: eventing.knative.dev/v1 -kind: Trigger -metadata: - name: notification-trigger -spec: - # the default broker has been enabled in the cluster since the namespace is labeled with knative-eventing-injection=enabled - broker: default - filter: - attributes: - # this message is produced by the pr-checker-workflow - type: process.handle_backend.checker_workflow_backend - # the subscriber is the knative service we just deployed - subscriber: - ref: - apiVersion: serving.knative.dev/v1 - kind: Service - name: notification-service \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/application.properties b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/application.properties deleted file mode 100644 index 9c461e32e2..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/application.properties +++ /dev/null @@ -1,20 +0,0 @@ -# -# 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. -# - -org.kogito.examples.sw.notification.slack.incoming=${SLACK_WEBHOOK} \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/apply_image_ns.yaml.tpl b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/apply_image_ns.yaml.tpl deleted file mode 100644 index c28fcf8d88..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/apply_image_ns.yaml.tpl +++ /dev/null @@ -1,3 +0,0 @@ -- op: replace - path: /spec/template/spec/containers/0/image - value: quay.io/{QUAY_NAMESPACE}/notification-service:latest \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/kustomization.yaml b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/kustomization.yaml deleted file mode 100644 index 8d72a3e150..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/kustomization.yaml +++ /dev/null @@ -1,43 +0,0 @@ -# -# 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. -# - -namespace: kogito-github -resources: - - 00-broker.yaml - - 01-deployment.yaml - - 02-trigger.yaml -generatorOptions: - disableNameSuffixHash: true - labels: - app: notification-service -patchesJson6902: - - path: apply_image_ns.yaml - target: - kind: Service - name: notification-service - version: v1 - group: serving.knative.dev -configMapGenerator: - - files: - - application.properties - name: notification-service-properties -secretGenerator: - - env: slack.env - name: slack-ids - type: Opaque diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/slack.env.tpl b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/slack.env.tpl deleted file mode 100644 index 8a6367cd88..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/kubernetes/slack.env.tpl +++ /dev/null @@ -1 +0,0 @@ -slackWebHook={SLACK_WEBHOOK} \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/pom.xml b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/pom.xml deleted file mode 100644 index 47d49f7164..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/pom.xml +++ /dev/null @@ -1,162 +0,0 @@ - - - - 4.0.0 - - org.kie.kogito.examples - serverless-workflow-github-showcase - 1.0-SNAPSHOT - - notification-service - Kogito Example :: Serverless Workflow Github Showcase :: Notification Service - - true - 2.13.1.Final - quarkus-bom - io.quarkus - 2.13.1.Final - 2.3.0 - 3.8.1 - 17 - - - - - ${quarkus.platform.group-id} - ${quarkus.platform.artifact-id} - ${quarkus.platform.version} - pom - import - - - - - - io.cloudevents - cloudevents-core - ${version.io.cloudevents} - - - io.cloudevents - cloudevents-http-restful-ws - ${version.io.cloudevents} - - - io.quarkus - quarkus-resteasy - - - io.quarkus - quarkus-resteasy-jackson - - - io.quarkus - quarkus-smallrye-openapi - - - org.apache.camel.quarkus - camel-quarkus-slack - ${version.org.camel} - - - io.quarkus - quarkus-junit5 - test - - - io.rest-assured - rest-assured - test - - - io.quarkus - quarkus-smallrye-health - - - - - - maven-compiler-plugin - ${version.compiler.plugin} - - ${maven.compiler.release} - - - - maven-surefire-plugin - ${version.surefire.plugin} - - - org.jboss.logmanager.LogManager - ${maven.home} - - - - - io.smallrye - jandex-maven-plugin - ${jandex-plugin.version} - - - make-index - - jandex - - - - - - ${quarkus.platform.group-id} - quarkus-maven-plugin - ${quarkus-plugin.version} - - - - build - - - - - - - - - - container - - - container - - - - container - - - - io.quarkus - quarkus-container-image-jib - - - - - diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/java/org/kogito/examples/sw/notification/service/NotificationResource.java b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/java/org/kogito/examples/sw/notification/service/NotificationResource.java deleted file mode 100644 index 9d825280d7..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/java/org/kogito/examples/sw/notification/service/NotificationResource.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.notification.service; - -import java.io.IOException; - -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.apache.camel.ProducerTemplate; -import org.eclipse.microprofile.config.inject.ConfigProperty; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -import io.cloudevents.CloudEvent; - -@Path("") -@ApplicationScoped -public class NotificationResource { - - @Inject - ObjectMapper mapper; - - @Inject - ProducerTemplate producerTemplate; - - @ConfigProperty(name = "org.kogito.examples.sw.notification.slack.channel") - String channel; - - @ConfigProperty(name = "org.kogito.examples.sw.notification.slack.incoming") - String webHookUrl; - - @POST - @Consumes(MediaType.TEXT_PLAIN) - @Produces(MediaType.TEXT_PLAIN) - @Path("/plain") - public Response createSlackMessage(String message) { - producerTemplate.requestBody("slack:#" + channel + "?webhookUrl=" + webHookUrl, message); - return Response - .ok() - .build(); - } - - @POST - //Knative sends the message to the root path - public Response createSlackMessage(CloudEvent message) throws IOException { - producerTemplate.requestBody("slack:#" + channel + "?webhookUrl=" + webHookUrl, formatMessageFromCE(message)); - return Response - .ok() - .build(); - } - - private String formatMessageFromCE(CloudEvent message) throws IOException { - final JsonNode jsonNode = mapper.readTree(message.getData().toBytes()); - return String.format("Heads Up! *%s* event on PR *#%s*, named *%s*", message.getType(), jsonNode.get("number").asText(), jsonNode.get("pull_request").get("title").asText()); - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/META-INF/javax.ws.rs.client.ClientRequestFilter b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/META-INF/javax.ws.rs.client.ClientRequestFilter deleted file mode 100644 index 457a19065f..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/META-INF/javax.ws.rs.client.ClientRequestFilter +++ /dev/null @@ -1 +0,0 @@ -io.cloudevents.http.restful.ws.CloudEventsProvider \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/META-INF/javax.ws.rs.ext.MessageBodyReader b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/META-INF/javax.ws.rs.ext.MessageBodyReader deleted file mode 100644 index 457a19065f..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/META-INF/javax.ws.rs.ext.MessageBodyReader +++ /dev/null @@ -1 +0,0 @@ -io.cloudevents.http.restful.ws.CloudEventsProvider \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/META-INF/javax.ws.rs.ext.MessageBodyWriter b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/META-INF/javax.ws.rs.ext.MessageBodyWriter deleted file mode 100644 index 457a19065f..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/META-INF/javax.ws.rs.ext.MessageBodyWriter +++ /dev/null @@ -1 +0,0 @@ -io.cloudevents.http.restful.ws.CloudEventsProvider \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/application.properties b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/application.properties deleted file mode 100644 index 80d5cb9819..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/main/resources/application.properties +++ /dev/null @@ -1,31 +0,0 @@ -# -# 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. -# - -quarkus.swagger-ui.always-include=true -org.kogito.examples.sw.notification.slack.channel=github-showcase - -quarkus.index-dependency.cloudevents.group-id=io.cloudevents -quarkus.index-dependency.cloudevents.artifact-id=cloudevents-http-restful-ws - -# profile to pack this example into a container, to use it execute activate the maven container profile, -Dcontainer -%container.quarkus.container-image.build=true -%container.quarkus.container-image.push=false -%container.quarkus.container-image.group=${USER} -%container.quarkus.container-image.registry=dev.local -%container.quarkus.container-image.tag=1.0-SNAPSHOT diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/test/java/org/kogito/examples/sw/notification/service/NotificationResourceIT.java b/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/test/java/org/kogito/examples/sw/notification/service/NotificationResourceIT.java deleted file mode 100644 index dca26ad23c..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/notification-service/src/test/java/org/kogito/examples/sw/notification/service/NotificationResourceIT.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.notification.service; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.RestAssured; -import io.restassured.http.ContentType; - -import static io.restassured.RestAssured.given; - -// Those are simple tests to verify if the integration is running. -// Edit the application.properties file with the right credentials, disabled this test and run. -// Check yr slack channel -@Disabled -@QuarkusTest -class NotificationResourceIT { - - @Test - void simpleCheckSendSlackMessage() { - given().when() - .body("Hello World from silly integration test") - .post("/plain") - .then() - .statusCode(200); - } - - @Test - void simpleCheckSendSlackMessageCloudEvent() { - given().config(RestAssured.config().encoderConfig(RestAssured.config().getEncoderConfig().encodeContentTypeAs("application/cloudevents", ContentType.TEXT))) - .when() - .body("{ \"number\": 1000, \"pull_request\": { \"title\": \"Hello from cloud events! :cloud:\" } }") - .header("ce-specversion", "1.0") - .header("ce-id", "000") - .header("ce-type", "notification") - .header("ce-source", "http://github.com") - .contentType("application/cloudevents") - .post("/") - .then() - .statusCode(200); - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pom.xml b/serverless-workflow-examples/serverless-workflow-github-showcase/pom.xml deleted file mode 100644 index 029e36a5d3..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pom.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - 4.0.0 - - - org.kie.kogito.examples - serverless-workflow-examples-parent - 999-SNAPSHOT - ../serverless-workflow-examples-parent/pom.xml - - - org.kie.kogito.examples - serverless-workflow-github-showcase - 1.0-SNAPSHOT - - pom - Kogito Example :: Serverless Workflow Github Showcase - - pr-checker-workflow - github-service - notification-service - - - 3.1.6 - 3.0.0-M7 - 0.11.2 - 1.116 - 3.9.0 - 2.33.2 - - diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/.gitignore b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/.gitignore deleted file mode 100644 index 02bbc8e605..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -kubernetes/base/apply_image_ns.yaml -kubernetes/base/patch_repository.yaml -kubernetes/base/patch_trigger.yaml -kubernetes/local/patch-virtual-service.yaml diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/Dockerfile b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/Dockerfile deleted file mode 100644 index 7ab9a1990f..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM --platform=linux/amd64 registry.access.redhat.com/ubi9/openjdk-17:1.20 - -ENV RUNTIME_TYPE quarkus - -COPY target/*-runner.jar $KOGITO_HOME/bin -COPY target/lib $KOGITO_HOME/bin/lib diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/README.md b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/README.md deleted file mode 100644 index afe6d4b680..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/README.md +++ /dev/null @@ -1,180 +0,0 @@ -## Pull Request Checker Workflow - -Before going further, please make sure you have deployed the [GitHub](../github-service) and [Notification](../notification-service) -services since the workflow depends on them. - -This is the main service of this example, it's responsible to orchestrate the services in -order to verify an opened PR. The service will add labels and reviewers according -to the files that have been modified. - -The image below illustrates the workflow: - -![](docs/pr-checker-workflow.png) - -Once a new PR is opened or changed in a given GitHub repository, the Knative platform will generate -a new CloudEvent containing the pull request context. The Broker will deliver this -event to the workflow service, thus starting a new instance. - -When the workflow starts, it will call the GitHub service to fetch the files changed in the PR. -Then, the workflow will verify what kind of changes have been made in the PR: -based on the files' path, a specific label and reviewer will be added to it. - -![](docs/handle-backend.png) -![](docs/handle-frontend.png) - -In the end of the workflow, a new event will be created and sent to the Knative broker. -This event will be consumed by the [Notification service](../notification-service) -to post a new message to a given Slack channel. - -### Review the sub-flows Labels and Reviewers - -Open the files `src/main/resources/handle-backend.sw.json` and `src/main/resources/handle-frontend.sw.json` -to review the labels and reviewers you wish to add to your PRs. Modify the `Inject` state -and save the workflow files. - -_**Note**: You can modify the workflow to call a function and set the labels and reviewers -in the context based on a configuration file instead. Are you up to the challenge?_ - -### Review GitHub App WebHook Secret - -> **HEADS UP!** we assume you already have the GitHub App created for this demo when -> you deployed the GitHub service - -Go to your [GitHub Apps dashboard](https://github.com/settings/apps) and click on "Edit" button -in the application you created when deploying the [GitHub Service](../github-service). - -Edit the field "Webhook secret (optional)" and add the value `super-kogito-demo-secret` -in the text field. This secret will be used by the Knative platform to identify the incoming events. - -_**Note:** In the "Webhook" section you should have a link to the [smee.io](https://smee.io/) service -if you chose to run the demo locally or in a cluster that is not accessible from the external world. -Just make sure that the Webhook link is correct._ - -### Install Knative GitHub Source - -Install the GitHub source from [eventing-contrib](https://github.com/knative/eventing-contrib/releases) releases that match your Knative Eventing -platform. To know the Knative eventing version run: - -```shell script -$ kubectl get KnativeEventing knative-eventing -n knative-eventing - -NAME VERSION READY REASON -knative-eventing 0.17.3 True -``` - -Then run: - -```shell script -$ kubectl apply -f https://github.com/knative/eventing-contrib/releases/download/v/github.yaml -``` - -**Note:** replace `` with the correct Knative Eventing version. - -### Deploying on Kubernetes - -> **IMPORTANT! :warning:** we assume you have read the prerequisites section in the main -> [README file](../README.md). Please follow those instructions before continuing. - -**Please do not proceed any further if you haven't deployed the [GitHub](../github-service) and [Notification](../notification-service) services.** - -To make things easier there is a [script in this directory](deploy-kubernetes.sh) to generate the template -files, build the application and the image, and then deploy it to your Kubernetes cluster. - -**IMPORTANT!** You **must** be authenticated to the target Kubernetes cluster as a **cluster administrator** for this script -to work. - -You can run the script once and all the required files will be generated in the `kubernetes/base` directory, -and the image will be published to your Quay.io account. - -Fill the value for the variables as shown below and run the script: - -```shell script -# the script accepts positional arguments as following: -QUAY_NAMESPACE= -GITHUB_REPO= - -./deploy-kubernetes.sh $QUAY_NAMESPACE $GITHUB_REPO -``` - -You should see a similar output like this: - -
Build logs -``` ----> Building and pushing image using tag quay.io/your_namespace/pr-checker-workflow:latest -STEP 1: FROM --platform=linux/amd64 registry.access.redhat.com/ubi9/openjdk-17:1.20 -STEP 2: ENV RUNTIME_TYPE quarkus -STEP 3: COPY target/*-runner.jar $KOGITO_HOME/bin ---> 58760d128d8 -STEP 4: COPY target/lib $KOGITO_HOME/bin/lib -STEP 5: COMMIT quay.io/your_namespace/pr-checker-workflow:latest ---> 7bea1f647bc -Writing manifest to image destination -Writing manifest to image destination -Storing signatures ----> Applying objects to the cluster in the namespace kogito-github. -secret/github-webhook-secret unchanged -service/pr-checker-workflow-default-http unchanged -kogitoruntime.app.kiegroup.org/pr-checker-workflow configured -broker.eventing.knative.dev/default unchanged -trigger.eventing.knative.dev/pr-checker-listener unchanged -githubsource.sources.knative.dev/github-event-listener unchanged -sinkbinding.sources.knative.dev/pr-checker-sink unchanged -``` -
- -If your cluster is already ready to receive GitHub Webhooks calls, just create -a new PR in your repository with a file named "backend", and you should see the PR -being labeled as "backend", also your chosen friend will be notified to review the PR. - -If you're running on Minikube locally, proceed to the next section before trying the demo. - -### Setting up your cluster to be publicly available - -Skip this section if your cluster is already publicly available and capable -to receive events from GitHub Webhooks. - -#### Minikube - -If you reach this point, you probably have tested and deployed the other services. -Just make sure you have a terminal window opened with: - -``` -$ minikube tunnel -``` - -Now run: - -``` -$ ./expose-on-minikube.sh -``` - -This command will create a new Istio `VirtualService` to access the Knative GitHub Source -from the Smee CLI tool. Since this tool adds a `Host: smee.io` in the request before redirecting -it to the cluster, Istio will reply with a 404 (Not Found) status code because it uses the -HTTP header `Host` to route requests within the cluster. - -Our just created `github-event-listener-smee` will take care of redirecting any requests -with `Host: smee.io` to the right service. - -Now on a new terminal window run: - -``` -$ SMEE_WEBHOOK= -$ ROUTE=$(kubectl get routes -l receive-adapter=github -o jsonpath="{.items[*].status.url}" -n kogito-github) - -$ smee -u $SMEE_WEBHOOK -t $ROUTE -``` - -Replace `` with the Smee URL generated for you while creating a new GitHub App. - -The Smee CLI will capture all events coming from your repository and redirect -to your local cluster, you should see the Knative pods starting on demand and in the end -a message in the Slack channel. :) - -#### Kubernetes or OpenShift 4.x - -Talk to the cluster administrator to understand how your cluster and Istio Ingress can be exposed to the world. - -### Cleaning up! - -See the project root's [README](./README.md) documentation. diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/configure.sh b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/configure.sh deleted file mode 100755 index fa69a529d6..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/configure.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash -# -# 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. -# - -QUAY_NAMESPACE=$1 -GITHUB_REPO=$2 - -CURR_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -# shellcheck source=../scripts/common.sh -source "${CURR_DIR}/../scripts/common.sh" - -function print_usage() { - echo "---> Script to deploy the GitHub service to the Kubernetes cluster. Usage:" - echo "---> ./deploy-kubernetes.sh QUAY_NAMESPACE GITHUB_REPO" - echo "---> Example: " - echo "---> ./deploy-kubernetes.sh namespace user/repo" -} - -function verify_input() { - local return_code=0 - if [ -z "${QUAY_NAMESPACE}" ]; then - echo "---> Quay namespace not set" - return_code=1 - fi - - if [ -z "${GITHUB_REPO}" ]; then - echo "---> GitHub owner and repository not set" - return_code=1 - fi - - return ${return_code} -} - -function apply_vars() { - cp ./kubernetes/base/apply_image_ns.yaml.tpl ./kubernetes/base/apply_image_ns.yaml - cp ./kubernetes/base/patch_repository.yaml.tpl ./kubernetes/base/patch_repository.yaml - cp ./kubernetes/base/patch_trigger.yaml.tpl ./kubernetes/base/patch_trigger.yaml - - sed -i "s/{QUAY_NAMESPACE}/${QUAY_NAMESPACE}/g" ./kubernetes/base/apply_image_ns.yaml - sed -i "s,{GITHUB_REPO},${GITHUB_REPO},g" ./kubernetes/base/patch_repository.yaml - sed -i "s,{GITHUB_REPO},${GITHUB_REPO},g" ./kubernetes/base/patch_trigger.yaml -} - -if ! verify_input; then - print_usage - exit -fi - -if ! check_binaries; then - echo "---> exiting installation script, not all required binaries have been found in your system" - exit -fi - -apply_vars \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/deploy-kubernetes.sh b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/deploy-kubernetes.sh deleted file mode 100755 index ecad798bb2..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/deploy-kubernetes.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -# -# 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. -# - -# imports.. - -source ./configure.sh - -echo "---> Building application" -mvn clean install -DskipTests - -build_push_image "${QUAY_NAMESPACE}" "pr-checker-workflow" - -echo "---> Applying objects to the cluster in the namespace kogito-github." -kubectl apply -k ./kubernetes/base diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/docs/handle-backend.png b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/docs/handle-backend.png deleted file mode 100644 index d206cd75ddaa76af179e273da262376359bd5caf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51943 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

_b(@3b$9S0Dd*!E7}!9VkKyVVq&*euZ% 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 diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/docs/pr-checker-workflow.png b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/docs/pr-checker-workflow.png deleted file mode 100644 index 9ee4621bba18bd28a5934f4354bdccd0a69cc86e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54907 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°mU}Mn7*|cp@Kl@MK! zZhPaj1uctVLy#S3oEZe*OYI{gRO9VkNs|eDF4tRMJEJ;%K>bsx z%cf~FlXh}wUG6FAjHKZ~!Y1{Wt*~HGEzJ_Vxi%l+=;U&M_IA;tEw+G=5DBYk)jZ#K z(KE|qS_D+pVJTY7p`;p(5cS8)HfU??Np$90S`XJpzOD`3<#v@MpJ4~#cJPjp62U}y zUi)B1!Yi9)nHqD5Z7r=qV`r;r_%|vf=98n(I5>VL7JlO&Xs z&#+9!(UG#kQou30{bjr)02?X?3rjff*ikVX3Q8uv)oTA^P_B|wb=PdA6}`A^miEih zF~oFTk({nMx*=a=RN4b?U)Q~Z8Z)0@$*;dYtbcjBaKB8-x;F`IQYqg|z5X&xAt926 zWn%c+bsA*a((@{1R*&A~I-w6yN72xgY>_=J1T+FFC)r*?oMv&IrN$_Ta20PVgvJB4 z3EKs*3HekJ^6kzt<|G@jhK*WzFaG34{v!C3lf)#SoT zEQZ6$pI=%HN*bIt%MJiG&j;Hr22!b^d5u4bCu|O+(AWEY8VMYBDmC_;5NF|FTOgRy zK@X>Z8cBm*rw~G_X}CTo_Ef9bF41n3Q8b6fT47sTOfon2h>H_4=m+jTKXRc{Sa*wI z3To)4rpbQygI{(0CcL zIol9dP_Nn?Ca|r2ei-fTBl>S^s})GH-o_{ww0mFsgpvqwd&Ewg1K*01yt!|?IZ^gl zA=f@bmRu`G!KFQCi$LqJxu@sN$##m>O0O_4FB`PvbJ_1)bBlVRyBs=(fgltv;2~_# z`=llPZQa0HqS3&|=MLMv&}iO;D0BE{@VIYZZGP?Q0UhDL12?DWGFwxN?V1!L( z9P-~^YyOlX{%+5jrzPM;E^HuI@9H8Xlsvz-CMGNU7&;+yH6tFsD&#}xMrEcag$_HM zcueazgDYbGW6^D6V`Di7JO99*z4&*N+vD2(k9ak(6`WxT6H$eDGY zv|Tm+Uv(d`vzKxbW@0pEoS`jqxxuj zZIKNB`;qMbrS*ugY1BGm<#D{evVXf*0P^4W5mX!^qL|SP%4~oqw^8kp7LV{KG7#>S z25%UZAqOyTjBdRhac*j&fSOG9c}an#H0!raJ2du>|g%_O%v0ph45PbP?bzDg` zWeJOWE_JNItH4r2wfsq{^nR4GS{?@i_Czs`f1#6)!6mtpG#Bu={zjSN(%`Ozw7Zr` z2A!DwO6RrSj`AJf#Ut`T^VeJHy<=YiCmWd*OcB8jGOqsazf+lXu`~vS+!(15BDoyk zO;8W$-sW&Pk?iE}1!V!SA01rdsF0BjwkA3BbFakin`DuCopTVY?(##zzn`IeR(L+2 z?`@8p%!>|(2Nw{mYABPX$a+a6S9fQ!!atGA+(U+!?*)o%t>d-QwJTy!kAOX_9&zXH z2)?OQ{<(3qpY!K$(ddu)l0JM@H{rA}8FOk$<(A){hiElxA9LA^es?{yM@TQ`(B&oy zK)WL{6F)zH2Tp`x#4t~z{f2;LG;WOs5MzE>F=B6_p~wZ@Wo&fe6!ushSdzsXS5A1a=GHrbYq|D4qvY&?U z|93AyXM71N#DHKPhwCf%K&YS|^zxWLNfv;G3P={{zAXUlm!6aly%usL)&f zv*RBWltMKCS`rZ4PM8cp@T~ll7b|xI@y!E+B%A;gvqD--SSw^vuM`6u%u0mPnN))h zfUYompt~E3EaeG8EtwU-9?6Z>UFt#y(!IA3#`Dm81IP;qCa()LnIH|FoX+`eLDWx*Tnm|jT+kyU$|N~aH4G1~oW955EWZp9E7w_4pyr&FGHM;6#5=G%fXR-5H_^a}U> zU7n@D>D#=@8pBlaFm#gyAm>F;CV*m1@6|;OA#dd~2(CInurSGHeCC>K!e8dn0G2&H z9J1gDD*|H3fBA_Q1+{cxdzu8~Zs%hCgLH$QFp%QvRmE)&U;LC(YitX7QRQs+ushbH zt<;#|Z>cdE5=d`7zE}oCk36J9^@!HxcWVHLt;>&-;dK1quJRyZb*=hIq7>?O5?4%=z^=sX%O5Lev65WrJg2B!EBYmF|P~a+-@75YKH#w^OH-1mJjKZcglM zpGu|9`QA%YRMj$K)>H;WArFd7YvTuQ!D0l`Ddjg?Y4`wIz60xe#j}xDO}5DzF9~Z# ze6VsOaln<9tVJ*i=jC+%9}#?`cVMxSHw<8O80$@b7MMY^p!nmwW!N9>_*e1%Ao$NAs5)7e1b;*&H7njOJK45tlME`r%bRw&%o8 zdg7_h9NYJ@lXJ&)$Hl?XG444L7WBzS_+pvvF2xG)m`d%GITPBO?#G{R#nue&ozTsG)Q`4-My`A9iYaioJ8#GK)wB!2J9 zH(#(D?GlC%jVzw62xniromJ}xMeqZ_BGQ^FMqq-xqZ4frls}M zNh@3KgzPX*QR&!=xl6ZVa_6ElST6gG4UZXzTF#2QER%lsd5P(m41~>Z4L3856Jw4q{tD_lTo(lFRla;CZ zG&B_0#I|_Fl&R*~Zl2=1ySJXs2XTUgnH{55Wlax9(4<~ANXCDCoTVX}CiZf?((2eP zwzGGPo(X*{^{eS#%>T zox}R!J2N4oY47FpRGr|4eH#T1zzV8@3HPXU+wXULsDPh;7(=;nSID`oTQZIyV@DeT z%ZVOKT~f7me2FL$^44Y>pHXPkm*Mc=eP}yq4ku?ZtmOBE8Z7{y*D*0yTNN_dY84F6 z#NAsnQ|gmV&fZ0L8PGmShtmVvPy)QOw};M*yu3Ls5yi9-CYIJY3bTKI_r{IP#c77~ zgYbl)f`1}45YPO*?8vD+7xSYcKh-|nFa_<_z`Wl4ZNLtNCL;pzs(vXcEE+ZZ&F~X2 zeZE*VP(U`=o@yX`u6-*Yp!3;{6!o)#0ajpoKC7#7A2u8}^0pD|S<6GiXFL&(1adxp z_34&qkTbMbyvUAeND&Kh9xU510=d$6+G1t7=MBiJLZ3d-tq}AhEPwgW?2EDxW8W@Z0yt+c$s}Se<}Y?) zKV2M?T%WBx<#Vo$H5rqT&Q<4%TN@IG--Hm@-zdl}wwt!B9f&@4e1U>034HYpBR&Qk zR|#Do;n{fpR6iu@oqY4`o6}unG*xHcJ z7#As@Z4?wFA{sPs4SH0gvbQ9H6mypf8tT)9d|ng1T=%KDh%B|dp(f$sSja7yv1dM6 zPMC&5d&Y;H;n3Y(Q~1RjUl{?CCUG)1@oc%CwW%}nYI`@|w~@Ylwo>sU8Qm{Hz)gnU zhK%(&C&Eq?!c1$B)nShJ$x_;ai8&+T(8{a!9KFS|uACa0f`<-!925H){?FqR4@i&& zzkHGXM*sYIf3mfhqvQ7VM;sroX^VD)lA=`CyYo$!{ri7i92NhljuqkD8Myv|@ruid z$s$R(a^M%6D)d)3dO{r)j$Fe5n}w~d5IF7*WE*}K1dO)7@&P$pE}RIJEpa}<`b_E^3ug>LbRf{ygC&0T?E1m zm$dUQox*p|c%qrb(OSoUaa=nY<8##9sjv^JG=E+htn}&j9dS#cuKuTuf{TdOFQx1c z^y}BB{6w73YO1e(Cke+!GrvU>C2`b6elXehqX7R;w2LzVoO^)L=P4%8L)-WyKq2)E zx$NC6(1q5Ti^iGE+^&gX?hG0+IDxNT=swJ>*9>bbpe?V*+9Af5`#*;GlCI``P=&Eb z)tDCLaTAl`2w`8y5zV01XPi47$$|nUhQDR9BrR6&mOX7Ul6-{!U*{-bailYC){MjZ zpIRq?dFIM-_zUjXrZu_ny$uZ16&_;wd$VjwDb_-#k&45$zT6i1EBk=l@Td7}`C7D} z56mky2cIb@_ir2#V)}mgENK50Eu%vxnnG#Z?0;kLt-`7dyRK0bMNkwKL_wsx8)-!v zq@|==x;vzil1DI57=*7kk;Y9Fmo zk=&Nw{6JQHx^Ccr_5cVlP;uzg1L7(&kUe>Ld955A+IxE+dN=+Z>?RbH65S{gM@%$l zU%OVBs+goCDG`w;w0 z14URTugus+onkHa#4llC6!i3=0J?hZksR=$CSbzFtMc9axUT+lp+0NZ%jH;Oslk|i zA*CwT1Zqz;r|JIX&5)CAKM>-vK|vAe_k#B`Vy#a4A?EyCP)eMJu|t|Yd}I4cXc_e} zdtyl3?}arD^Wbzdb<@2)M?qno5YgZG(VyAo=ekL6T(ZR4pHT>nwq8}@Z!I>i5n#ww zN8N@yMw=zR$YrfkLvY7Bb!Cp>Jc>fs+UM?n%Qx_1ed>=x(+EXGQL_MIT_qKr(Ku{e zHoj#aOQp|YRxA82Lx~txPq{$Ru&7AFr~}(MGxSt$cKmw`;_=-B9od^7M4bf4MU+J+ zYW}WiTL!BDOJlH<5R1a|EoIw)5to3su141xtRIw^baaTZgIdX0k@~(8l?Z1kW)7|Y z){=n-ZN1fQWHN8mV*IbbDS!v<#I3LVb@pyLD?p-{KKc6n5)OWejuH_O zF^G;Hnt~F}_67GLMB5Gw3|SIXyMxv2Ep-%z*0pnXT*-&D0X!n`yTf(qLxMa5CPQy+Mc?&r~QuXlTXR#6HlJvEk0YCd_r6Zd>X7+X4Y?ZYSp@% z0;)A6dKE3r;6ubof(@u5EKq+MYK0#9`KzML*CN9G`>~~7UsL{TQ3#Oiu;IV9;LSOTlV4noe zZMpjPM!SlnJ9opM!#X-ib)g*1Y7xFAa^ZBgI&^kBe-LCExzC$2+90qbgm{X*#k=#g zG(sX`lcnlAoEvY6-rV-;kOq_EDug??8C&vE4V7qHL=_EzH2H>Lm_Qn05TXkN4{sgN z#_;C=TlgjTvtTtq-r>*0>i^ABgwy|5B~CQMfNs0f)_Qa=zJaIxUZAl^!rFbCZZc z{rf~%ih!9_IQZuOHb9_-Hy6v3fj2}v=k8{UdbQZXmeG$rv~gNR>bj8+>rY`2P@yHd zA1`uV-khRmH(O2~ck7wP2QSKjZ{^m$Xhi#nBa6jMmN1;HT=$)7C0E9TO#y%QeQ|=% zV!#r%x#b-HBGUA3KRRl}#ljRDZSMrzN>wu*>SEB8}+pB(zriVsM1IJsUWfoNABu z;M0{RYF3sVJ_^DR1k_lDH1G5;OegW*vV3sZ*dW9v&MW^)-jXSptd{ZIiAoJfkk4JV zvC+nMo)#bADJkNuoPQ^IvtPwXT|43XTcbZ+F&|+NJmjSWD8;~4iOhJEs_!;*E6zf2 z;X@Yd2*2t3^>Vf-dWitj=oe4gi=`EwcxW;t3ti76tye>by%BmJeHT&) zA3od+a&k`<^PeU5f(sv;sU(;J%R$-XN)!07*H7y`Sdm#142%E!->t@1NiT1-V$67Op9@hs6CrtHdfUU3FYw(9HaI(J!B^OPAICMBs@u z-M=6gPEGoo%7_{h`~RVKvatR?-?E-Lva6}wUln%!ha!9A#`&t4ves6^eE24h1Ie(h zkA#bhtM?CK4TYcvP&$^VYg(Ir&Jx^~afngd6b;Zh@Pc3%GKBhG50Ewmu;s z*eNk-dV=dC6NvDteqNS^jN2%oZl7TZ;nQT=atbV=jqrc+AMFlF#x$f=en4j9C^ebBzVERBoC^Y;aPTJ1UGcXc66Zx{IM%$qF1V%SYqYO%1F)QYQr`2GGTz=%p5#WO)Y#SjTAAbZ9Vq+6kZZZ_kDB zA9Nh*<}08XKy-oxNdXYF=#8NR3lADvP6IG9lwQEn&$TgC6Ho+REq3mxtn)qq=!ydR8rNNf@AM(owetqH(#6oK{`T=n3t+U6z4T!XbT<35S^FSV{wU zECyV#2adOSg_F6|8F4pk_VxC06k_RTM2E7kC}oLz&UgUnzX~bFzV@1`5yR`tXLzqI zpO#f)&s2x>9Uk+Dii+-Q|1j)RyG=;c7_6!u#OKzQr3!KY^a^={d?T0sPjD0PNSm4q zD|`Ca%C9aD#J?+f+{!El;zsYGrEjRBKL$@C!uf6lqDv$ygapAF;LZQ>7FDCDDePbK|&!sg?FmR>A>_h z^3`~y6~@-&!`871R2n6z<+Xu1$as==$C!b52}e>`gY74>XqtPnkkv7tR_^}wX-Ci4 zWpELd!PC<{{`{q3EM$R@cRNUKwqm;0%0bv6gkF8Nac(Xak!AffWQs@t?9A!{a>OqF zC&WkYV>}`Zvk%w=lY~! z6=932T+dKI{x40rnD|CR{ta*?!w&XvX7KOT%xv#(@Q{-OHzt%xuOsJ02nq_iBT=H} zEv1uVbV1=+{h8`y^q0qXq0*LR*v}q6TMp8>&k7W~!}#4lr>5>Sgl#o`!CVE9iCj$e zI{)SF$BYaB{Lg>H_oyXCf}Er-;~H#OM!@z*0q5+XpZ^}x+E^jUty`Vi`L1V3h>z{< z84x-t1rNmGy$HfS>KlH6g5+IDv687&q*?%H9m18Qp*nx1E_1Z-DR8cqaN7$rqGnDe zsQ6}s#j_w#e2niNy}O&wYNFVGc6SLd8uAE1*$1ZAWP+Pj8|jmZWcQQMsah(CQ2&VPd;71L_FF!wBcsR^~%ng#+ zu%qYrHQ=c+){dlK=VS=IJUAS>LL@3drAxNX+4q8Pu6eR}@oTru#*ws4iJrXkp<^n_ zL;S^55BJ~g?KDGEa7;>yJC(U{Obv`)?!>35rh0fJ(HVJK~PnJ9=Noouyp7z4s*$YiHYH$%EY4Gln;QJF6)OU;y5qxa{TQj zOC+(K2v47qlx5pjEBj=}5I%^Z}abiAw#nE$ii8F_PkH0}@IPbuydc$3&!rs)> zwK_~XsHO%o=_yRQtgpDxL0^^%xP^?Xmp!J5{{EdfvvSoAmO2LIc}B7pfzMC0J0rwC z(OafC2%Ggk|G@cife^78!tbTsu{?Xt-v?{{NACi>b!T#~|Uf}3Bk=CaJs zD^*#}Cv-a#tVr-Kqb1-q&d(MhQhw~fV1(JF-6Ghq_8)G{QW131((7p3- zbSrSgSa%@fOBB6&Q`MyiK^<7z9KhtUay#I!H2LOVLW&-$>OGOt$ArYhPLEfh^z+Sn znGishO+QqE#%oSq*sNZ+zO--+jg94ols_C@LSC2hc{l=l^ZuorPRvPgaX=MU50Jc_ zyYn;hM~u_?Vv$^%vu?ovH?`WDq=RXc%2)JuI$KsmGM#b$3}7xoCxZnAYKqNG& zbNEz++V6dEFeu`ZGSY)&6YstTKUn|)UBXa zfw7;Nun;lN#qRsm6)6BV@V&Szv*saY;J0B$tr&L@v4M3n= zA;Gcm8ZFRVO|-za+#KfwkWfok^b}}h;y`_jh%k+GcaHwM?}HnIx%$O;t|hjtDDC-K z79Me#$KqerpAydj0}4-D+by}m&9xTwK6UFy3p>N#pP$QJIqwYTan8=-yB<$quv+ka zJw3exw7a$;=`r0#FX^P2X>)U7cJrj(wE=k?ZhI6cx1=lNEgc-MCUbOd6}@|BkJ z)T!?0TsyTxL68g|C|M>v&eh~y7nj^2rI$OALd|Lao& zll77kDVfUd$q8tv<~Uw#;Tx58_I?7%>(hh&_qE59Ij3jO7XLQhb#yi;$g8X1c}=f>mAX_+ z!4LMBHO#Sq_u<%yL`_k4QXWv z^`lGRcd>m2|2OS~AR~qEfaWnqqFLdfKB{b*7{>p1!U}|>IzCVnt_(vuuctop7MiS# z@?wv8EMbcqA`9B}DCyjqH>X~$(3VPI>HXji%|0cZ=&`f1@8Sd1Z^dJY1XFCBCxxGq z=tKkln-%e$zMFVsYtV%nwEQ%$fry?X`WXIilV_BK;MebiBZ+KzekcT?9<4^w9;Tk# z#TG&CNLi)Ls<~7&rB6pYxVJp>muEEa$HC;|9sYFNJo;>D&A9Kv-t%Z(u@=3*Juxd? z&-@0-?h^@?f5qhZ!jmo;|1^oGs>R8rKP9vFa8T5s=f!&?BlXqG-*5QIx+KPcZHjiE z`tBP60pfcYDLQZufNF3wi3qk1bCv$5I_#jk1&Vyx0;tO{w;h-OlU?q<_c{k$3nY+W z-$+_rRSJ$EOJvq*iBbr&7~g%Cz_xMkbE+nbaL9QAlpSTV#9hRrP&36MXYpR|&fP79 zI`RwNa}z{8C^GNXa(6{GA_S<#SywY?_M3q>Q?A_IvE4X1ILLysD=6Sa>@Oo5&G7}p zo$~}7pQ8;2WUbPP)4$#-3O}b2&ma@`*}FV=2MEC=8{Sd_x+X10FK~T9_SXikYs}99 z0hG=s_!9BVbP)eMdHg2=h6Ngdk@F3EfaG;LU%z&AV*3Ws1*nN8^It2+&bL1xy3YY? zIk&sZIFPUOvHr@Q31YOqGY}#+oGM2K*A@o}N@}s1*OCV-4`17xK6%dYv!%T~$e{P! z=EQvelY{@GF z`{w|S{(`|5*BV7-@dT$Tyw1ggoSxp3-E7v959n8sQF_{K!M;BHYY|K}6zWg^yO#~i4RtqY~4Rb;H0-VFq|M+8rScUe)!09qEPr3G;oF#I*b<;r z>2~qRWOVcI@fJ5w*uEC)-jm7c%gh}y21k#@YC#5J`T&mb`NusJxHF1%S6}ctBTDG7 z`jbfLc&E3Y)6?b%1yKNa0kN>=Gbzi%c@KaT#C>M*P4U*B3X6N+72SNmnYsn$pNHH2 zQZ$;n5qw4C;atJ)80iwHgIV+uR;PVw#MiABQ9wxCvoS5lWX#a%c*0LIeqTPjTzZN0 zWv+twb0Wb6z17?fwn<_Qq&N%1s|BvNZ?k~$!z7<`EncW$R;*e8s8wbSw<9vv8`~`D<+?2iA*2y2jF0ms#3Tcfr_p5g14@x1p$+A~de<;YwwM!>H z&DQdj8iq9v4ZZqYS$T)=R0|t0FAEUK*mBVo7w;jpv?r>MI#^t-_G{`-SK@3=Iou9v z1ue*x<1Na-X9s;UZs6WPyk-f9K5zTMBl_e#vuB*`t~A)uHE-9MeMJ9*kw6#Xy~Q}^ zTG@Q8;j*O<4NQ80IS~*Xj9|WjS*@nkEmq#CGP@Pwfce_JwNQ;S8Zt3F3UrSoVx`C# z{}71IlF5CKVgL~^{djtHVXN(FefP6vUE|Ro=)a};>2f|+4CIX(vi?iH2@9;2I9Nf> zRVu`tD(`LV?|=Rod^fG$ge{!!(glhGX^pz3Gh7r8K2lgiU6x|c06jsjUObi<<~kNq zbQ&MJku6vMEc>fUL$m>nJDMP@kLPt^VyGX#t*J>6s}BI=4eN{HydWfiooDE@mOz%o zew$~Z1XR~tV=%nY(GMLS_0fJD<^P}z*DJ&|LHN9?+|9Rt^WWe}I?UXAl(YclcHz*? zW%LJ78+*n5$gr{=){fKp@JFdgGr~NQl9A~<@)EBKzN+?_F&Ej;yb~?HoP?)Pk}p6h z38^(UE&>c5>N`)1m+@khZO$#viB=_F6$*)NRJ4ssqp}IS+6H< z9nw8duoYurXRePGB1e+<0{YDieh1-CfpKX^IBY~jRpke(g^c!_!3y&vG*Hxq&=de8 z7*9k?{a-a!1oY(s*G)4jDP+d0S5;h{lH#>ML-@OuCqMCz~F#956Idz?C8Go zLthur$?(0t;zxj+Aux<#m=g%WWneZLCBUe2TbNh>=!TADcP2-FKt>r*D}cxu);~1S zD*aeld_6Dq`*0zMjxjzMgh70{?C{^)c~qG9Tkh+<4&xb25Raa`Rpfd$)~9)mN%05- zHXotC*dPHtr6-x&PChyg}X4n&C%Z2g8H2Y|cG;PK3# zt!l1T%#D6KtNiz@|FMO1CBFQf1A0dw#gmyqVtZV6z39M@Zj=&3%IOYrMVh2B@XK z3BZ&6-|EH^^;}W4AUT5rq$xrB1w<#| zu(9HX9MYn;iYh#->KYj5J=fN(HBtCG8Tf8{Lp9*a<@tQ%^QRsQ88#|~-?R28HSu)C7|_XhWb+;zGteYXcumR_ zwG%&&F$->ZD%2EWWPW3VEpg}}f?UO`j_DGFJH0!YJ^66{^$7wE0B8r$Sp_{-OF%n- zLp-*j9vb(UIOp557x#~I6qm%P?%A)~ashk~>e(hnbmC(L0e0Qm85OU{4Ccf#!qmvm zJDSy9i1~{nYg2cLej=r;PRORW`6V~)`R3SjXy+cGCUkkqumqUQcD{X^EUb(uqlX9s z<^f<192^{mGNPRBZ=1aS16kU@3rU71T;>%(DNC+<1Xg!E=X*x}6Ca|VXvaQxYR%hp zLV{bd-JaKs+&^9_l&`7#>sp}Nr$ORA@aT}ui;>+$ZQa^Bc*cOleNXDga|>X+OEj=!*~J3XFUOtC)| zsc7HciM-a`XA&Vv+^>F2)n5vH)&JrKVv7jt9{jg}AHM%sLL@VOzurY87;g87s3@OS z9V+GY`EjziT0C3@fuX{?2~GR@jJ2;^FYleB1!+$Q{Z$fN542Y3VmNnc_99_~88pOb zzH0J%EFSSTOh7i2!7YE}ACEOL6H~a4&z)60_C(NyqW5exF5@Cd)NJ-TIwgB5+$(e- zD1>fN#;}XbwWBZn>no!({&D`37yLV4s`chkABGlv-Ooi8!2rGY#DkmAcU1D*fe5%x z5FQ!PJ}IO$@fr}w7jbcGlzacdT4YFIc(>|U(Wh!6zZ?7_F^$js&~5AfY48OB_4|1q z!M>EQ9b02Lx^>S&b~wBTqA26i=Vyb&ve40~-Zj@z7)KNlMu9NPl1eCpyNHqH9b^&5 zN)FoB&M!>a6A$*zgqk`f)Yi^$%-QhMdzRipMKw!8E{cxc^MMW*EtzbL=0U zU#Z&Zr+0??L;rqdru7Y$={qC$St zrS(-&w8NtAft4YB=|((kK6X8)E%3Ku7!O*%NXd2bWzzY)d3+LurcXt4F}B|^4*Kr80GteM7!gLsU1aDaiy zP-CvGYKrOs8J7h{mP8l(iJ#xad#c!H0#slW>LW+BBhRQPkyIec0=(_XvEfIqs>OrsQDBEUGTko5- zw)MOJp4&(<&jssk$-6OP9c1rK=AD&`to#?R(G3xBcu>z1*&lA-8Iayr^tH(R(h9lm z|Fkz|e&BGW5!V%!);Xt{&V(C9FBTv`Qt(^mHO4hIu|Jt`Yf*jYn@wyQ?Zj*e<&N7N z4LYnd%#l#+A3yAQsf-!@H& z6Zw36&^gWrg$N5on*&VszDQ{4mNt@32N0SLp-*4B!JN(6U{DJU(XmvO-jIG&#b`Dt zri3!GZv<5HOTMr*_GHJr1IV55cs5SlZE@mM_ybNd;RXTBWLhl?xC6 zRLq3^L2wu`Jk>8F~0YAgceFF@cO3`Rw-Vq*My-$m_Xoj3VL zw%k(jeeqZYBdk1)ls`vvmR60b_86yv>()M$ScrAHYhRQ6YNp-FsgqnlQ7YYNiyA(? zb~^lBGO|q5=Gwnu{N(((cr1yaCm^Q+Xvb$xNa(Mt{e-*8<%qv!4=!V=w*LE&x%ZEO zlf{Nfq|GfKipN++0J-V-#_P?$IDOLXXuOwm%H|@lZhgOQ;i1VNy`xyXtF?PlQr9Yo zQ55|We@-aqUg9wxn-pIjK;dx{C)dxDWy`ss3I5{a{V`JZGF-38w4BS&kHlk11wBb% z9Ozuk#~-C!nNm^sJ>JBZhrruUXX+`x!lge;>g{j%GMSdC)<626j}zCBg2?n@YX9Qy zxXSRwJnwC8{sMS9-{nX4zj<@~1`Z8jXg8m-2A3g21B*la3IL41JuB)n`hvsn*trO= zTMKfDS3F8@>?bH%jJ8r!t5igcn-M~a#~79dqdLd+T;Zykb)6(`lho>=9ciCK-`_f2 zU3QS&u!}N(m0>9)u;c*~QWngrA1i|8zi@;*0;!_V^D}M51eQJ` z9^RhS`f>u6T>;th$SHzsfsIlsK`uYbFiP`GQR{0@Osh(#=WQ}pu3iBT)k zFmxm7kbX`1YP|6Gc&qy3e-_vT#@yZ&JC9)f6b-mU?CzWD;}a>wZr!Enm%Z4ih@uzK zE8R!t(qf?~NuSVaVwY;qQPf9ZR5in!seO^mO()wChav4?XgHoz4&L%n-s!mn;AKLN z(vhod)_%cMhZn+B`_2|@`A-a6qh?L{$n5x^$mA)&l3B})IJoR}e17!9g6H$v;woZi zyTZ<<9Nxy`X>Bv`-ZRk%J3nYom+KbEV064(e0%4r@Yx3L(c<=c5Mrm+6BcAr{>lhT z)^&^Y#KOqyjC{Z^P%r>9+abh8fsrNI&Ip!_CLOjB_>1?mYI5j{=)dvvl~L~vFG$Op z=wDiBD;Q2ro$?=$Zr~o19bZ0!$tRWu-PrrdaV)XQ&j&I3so%1m+YsZ{Nx_tQ{p-UI zxnYqmDc9Cqpr4Vc#v|INMMKY!`BLMUZ1)~Ti+V$P@mb_RB@WmxO35s_y%q;xW2vZ* z`W}+Z|D!|9oiw1=?uVS_S0JAL&Wa%6@(Lg&9Plrv4$QeaiDHxym8o0;G!7EPd?3Jp zlvq#Ag-c-Isu-B*8x3z)wdJZw!`pL*jsNw(dKZrSOql{+Q2|W&Z3ZT4KRco;*-yhh z=1G3DQ?L&N@w4ReKkaV#J1U~SbZXI#NVD zIFAiCMfH$r`|UMiVOnxu{AbvR8Kjj^yZtipVVf&A!ay=%pUA@JrE|+vap|w{Dh69s z2)JYfydT4g-;Meo%UWaWo&C{ZVMR$2hQgOQuwhhrXmcpUqfEf{^;_I)c(i~l+*+Qx zrOM-%(}~l(PM+|29cp<2#OJdHHc(ag&TQjI z+5KV5nelnZ#pQ7|psE?>^dvU4$7z8J|CCq>=I?BB{>0Gwcq$7qMlif^Ze>M5I~R54 zbqL&&6O-MB&F6Q zxmieN&qwr=L9~Vwbn&=cpS+?RU-HpI`e z^6XjWdQANEbY-l1T^kLk!Ez#U103`WvmM9gJ40I6_Yg)CZjnmHXsWk}3%cC-Ud=sM z#GmxI5#y|^cBT2q9rA7VWar7B;yi>kAwNlzLwE|^9;V=X-p4~^x+{ydF#xQXo#1h` zlWh8lBZ+HBL-GH7&Qk zgnj$91mZCjWw21bWI(d8N)nSzkM6>*!hJ|hEBic{BbBr-;|5L>)SUu*~9V20xWmqL<$@xjinr{=c@MBc zt`olLeG#Y>&G#qjzk^cM^l`rQAlk~O|Kpb#<9E8l-r_kt(X{y3kH8wYxhVvi|+K^_FApvi@-B2N)@a*=MQ@pk>>)cp?>LU z{(*?4+TAeL=~r)brMZ7lKxz8ri+F4_&C{J}GPrVjIJS}gs!%=7)MWC_f9fRL#h$r_ z875b4wy4mp=a3k_=t-n=!X)KU_4PqRL0f`W-@db;_THTPbd%)9iq!81@1684U22UL zEYJROleceqEgb$5O1d%UtZ*OzggDO|zI((rtis5*UM0x7cRb)6HCR&Cs;sxC@NakR zE}*-(wVU_SM>FXAsqcrTHO)Kk&@c}9wpD0926&M%F~|69IEYo^wjPzWS5@ybIvi^t zr8$byQHTAL8u*$3X~|W8%>pU>)T9!oj<8S> z24fJPb2Ku^bE~6%?=(5tv*a7u?X8>i0VAmR(aXDUTEU_vhS2$2uKpFX)xcN4*<*d? z$11d#EpgKbea0cVwfr}?RZXRYK!KV%bW`~3$xLZMZ^!6wt@ol@Qx8b0N=#|mB7_`` ztvmup9`so<2?PwAoAEZsgbs<-;)l%HNXwe_ftWTOFm52ZW{SSO<=oRvY)_y&R0@f< zCt~Z5%A9l*m28C|ZX*-)v^1H*DYuK0YC19!FaIGDGC?9+Rl{$a7+&D1ZPH#*b$H<% z$VMsB+=|SE6+2KTpy%(CFKg=VP95&jOm(&ysgQ8Q4vBZptP#|u55=p6Mc-F$L<6h4 zVM^rAwqpL{LF)n!<$XbY*C;#5l+?8C>6MDwxf?HEnHQQmhXQ01COX!3-jA7YGJ4H;NuwjBPM8aFwT^5G2;cnAu;0yO@NOaYvS?!X`tKsczwJoFH|Z28 znqiXs>ChD=_6aTE{`Su zV`v#p{C)IT?1I(f*ti+nEX{K?EAn502iroMm7qYtk36j#v*#p4aoI|`~0ZRJN zNbfFJX(ZsPcy2BquWkWjQ7%jTLb9;EIGKu~p!`vNeY%hDkv@PfCsfKG1hskrzVa3_ zUr+IBNAUX4^9;o?os;cM`U8(Medu?O4$_p_YqoYw@whTo*4!u<*Kvs)B;-0q1OJN! zC_PleajRCQiKn?g$5Son6N+?N`E_f3-`ha-*_orc5S$gkyyqRFC zmq=OaD&@~U?_VYA{j*9>cLP}fkGTtn9lk&q4d9i|8JG1tVKnNqBp3(r-5oAgm!}q` zE|~kjEE=wm0Vz6FQIm4UqMw*P#_!oV{27W1&~VL%){T$lpjv;$uFJ&C&!J2X%j~h> zbUKR>F$oknY|zkE%vhLR7p`Hpbt@(*2Py?(*wc#EhH`ir>Y{jXd8j&@pilyI?puI= z0L2ynV=xm4-}f5GY%pl@*>ME)3N*HSae3wT<;xetgB3Rb!8*`t*893$xVKGl8-`V$ z0g*RPjdSb3SK)iqIb%j`hM*`Jv3(N7r*@SHf$wPpMoFuNmUtFhuf>99%#{vhx@o#^ zZv8Gi%M2X(O2D&L2cnu<^h(I`**%8yO$`&ZXEkab+rPez7__vJSKy?&GW+XyvzL0@ zFn~Hpa;Du<*%(!(xSs;C&J<@4cc1pBg%~Xpjb|rmt|5JDA%vuL*ge6zT4XV2#bxUlDVLR?3s7XjG%|(;o(L90dVnHN zZS~Q2sgz>NLe(FT$fWSkcYdzo83zdm2=Oj1J6x%7Vj@RCs%HxGPSjs%`SCddBsRlp zQ3Go5Edc!OO+Xa5GSDr88q-9wCXJfR-OxLd&#`lH(g_j^p}PP;pj7;U_CKg*hn-@zs)$RxIk$>C zFdpC%J2CL_is9+GCp8I8t@xKM^#M*=nI-qnd`P{G0)e$g_a#PG^ ze`#{YqGtd*r&cs==9r_kq+eZ8Oa&kw$lYJ4^SR*6WRt&l9x9rrF`csi?DtT!5ysvc z_LT@zxtjZTPJj0G!FKfokL=$ZamnaofG$75 z#Ef0hE1Oh{sRQ@|kkME6mlJ8#PI1~p>2$WI_wcxE6Tnz=KAAw(EdA897)E+`Y( zd&#++S$68D{0r;PThBZpI{jsS#g(sQVR(Khi^o^{RW{R^#c`LSrG@9TWD2xvg*HYD zL9$Ag-7KN^`lsh&WtbzzR2j@;7K(291w9rnvlk0!zeZV*i@J0q}eDpdBM4Lj_>Jc1{nty+9*opxW-A z#PDp`qK)B~PzoU0!&V1w<=@OfZ-U5-#oy-b%FG-5wA*7+E$tNFRFCUUvYCvB$Dny| zLNfPi34rZ29Md_G?@4JLZ?^U=>MhqHGE*K%e{2!Ea*fei*6!X9pZes1LY< z>)f1hS#ukMo{Plsx+vEli%CdC0>+ZX?w*64=;JcM8YfI)8Xo(@2(@9l1RD~mOskc zaZSy{0kYY8AT7pOU#Lc=W0VVO(3fBG@}9)R7<~Tm-J|2H6bvjik%K@607cQuu?z%- zsP~cY+3Pj=WZk)|u6?+MpTz4D0ve62!8q^MCP!W(y-Z|YTQeG{JxjyujtUP44IPQ% z3Wokvk3Jy@3HyDiWUjAZ@X9NjM0rJysgyLQ*I+?+0oFDC*Ne zhgN^pvf0_&NngK4=|<${q10 zPD*}-hWa{R6dmK${cp~8F1Q>&eH(66glwV;cW`X&?2HD8S0A~@e@g5~sr#Dp^^K}3 zZeCtqAfZf@@r%Lhi}?{&TID3DmA8$Lv-KZ@y%>lFl#OgbLbA@}H?gbJtqL>X1_Zlb zP3HH^IYaSRP@@W1U3&Ai&@duNc?n5UE!4-3Y(tSuCD|Bjck1y zY(ew5DMiO2t|1v1J3*hERQ+YT9U6~54Yt2ez{z^!Iz~LRtT6Ef5K=pq_r`zOHAD4g&+G+F&90Wf3CIlL_ zj>-B}wII+TPx` z3qA_U?+F#VdV^kt3o?CjetTC}g+e4d+h4Hs(lUQO0KewLtjk!j<7S*O%a=>#$nNzx z(?P+Qr4ExvOUyfA@$sAg4o32Sq{_ZM>FnuI4yUD*hIZGoco&?l!P)QUUa>qP(CBOV za>dBPVsP|t#?k3vTWgks=Z-j>_DoUiB{enUC(oWWgZz;~_UfujMEAx?B&WgYIm$q- zlN)sF1wF&nXYWbD`Wub@z!w%qIh&gZZVJM2`l;=x`HWgwAMKxYcJ_A?;S_F%WNbP= z;Ip(Ou*nydmkWU5H=DXFG0Pkr8|!6$D5Lj&V8H70roT|UpC5{_Feg7712r|u=V%&- zVuRi}>YYyhr5>|HP__N0!8=$1fApnBA7U#Hf`ryNrj6`t6l zR9ADUWFM^&nWTKIv_$VsB{M4}#q=(v zQeQ+3g~qnBLPOkZlV$mjv239qOPjumriOm#v%4WU1a#URVbD4%A|V0n z6aV)lN;I^)Ce0B9X@#01`I6F7Qk~X1RFM`n(y0*DL|*NdD=L!hEBKusy}G4xQ5LJz z%(IipBU9%Xe)0M)nM4BSi^@1qk{`$)Q=nEVZyPAqN#6-d^7Pb*>BsuJEHP4&os(m; zDn%Jh^D$rHsB?_TY?9FZ=86zhsgMbCblG`%lUrH<^|&k+T{2dv?`AG3sSr7kz(%uN z(_R`MZ&j|84_du}CvQiwbWA?RkcfCao70UXms(q2m&=iQ29Cw<;kv}&(9qtVRlgDr zR+N31Xb6Rf zm`(HQIWx_VxV?b{(tX5`e*I$o@KYf&B4VP}iGO$d$7}9=TE^GPb~0a^{k>s0F9{p;#Zp36?Fe3S#C#~YxJZ@Ncm>BBl(qA_)F0sE zALS|bh5|%8C@Tx+6<6>FH8QM~`i_xY?f!y~M72(t&ik*pu)gh|EVO#a6sU?sOBrog`okQIKdqo3n(RrX^|DlqvHDkaH0aMEqOWRMM0?gTJ(fi{J^jyeLs2xw z9Y-XrYn$)W^r;!6*-%@^=g(TMZr)&*3UZx~4o%;@dBb??mf@%IBH{8f;xi)tv*?>E zwWoKhlnV94(rbIw&AVgX35v91uN~ydzGLqT=5dPVwp}~qhJ?C}0CD(Z+;i6Mv#f#w zp(^XF64tx*7-vlJRWq8ins3hHdN7vzH{Wf__c4*kEbmO~v_ansr^7WIU~t^A4#gS! zIRlh`lO|{!G(!8Ttv{ts_{-C5>asU?qf-%g?bk6cCugq39flwryA3YN(JJ>jHA5N!DiFyfQk88ZIIdJ(0O1zJ3)g)R0GeR4;6~%ZBnONk~#Msms+H#ja(d ziVFla^?!ek2X0kVS{lviMXLTl#+;SadPqzRIrI;>t5?CpW~%J{&i{6m)gm7(KS1Qe ztQOt-te3$T_Vo3o@Q(>4iCI|#H0}JBWhg|5fSYnV1``c)$eBC8l#NEqK3Y)Lu zTjOj!kA9c({>9Ec*maMf@rLgDU;!kG{Go%vKDZ`CMAD*Soz4`pQuWu>Y+#r{k&dLk z{;gV_vwy0`Y*VB6j?|0It?r>hO&4tX%VeP-_tiO%ca=a3rBU2Wv)}qDnN)e`=Ah(z z8MisS?s6NM;b3=OzTDzO7rc}_*-Ype@(U~k9j#=g4Mo)7zb4c5SG(Sukvs;Vn2P1) zT?jCCJ7|&+nZ?jrqtgaw=TELI!#6p!QiEkY7W3)Keh9xl(047Z`opwpdhkLc77J*! zrVCA@`m!W$m~D+#1wM6k_n(l2;ar>;hTuG>pI-XgIOL1VGE1R>)k*#ZSQAfiar^d{ zry%g68~HxL^hu82)pZ*BD&RlBHeCY31g$0?k@UvUpFe;9Hf9CmUtyAn&=bV@g^=TYxe$e#~UcgNDD6YYFHo9cN-VXawTB>=bRttLw+p6Y)% z=pucWD&m3;Gd?vdW>}(YrCX69J(Lj-WM}fD)pz|TEz9`^wMk8WS0PNwHS@c(xXQ}> zUdN|_&%T5}zdVnwH9JeoZwE^+0AUb<1n}j$IxVCoU^M0qMu3DELhsDb-Wh5Lxva(u zQS0jeG6@L0^ZHv1ZB@y<{(exh+nnwM_n8P+(BXo-dUwoCBBWy3B_%2s{{}!AEwJ{? z>Y76>UB3qcew(r9jFpuba9<;^+^9K~*CK3jQYcnHii~XiV10x?F@A2MTJXb%58^(j z32r-gjjLIc&tz}X2v9{F95~(fj5}dVA}+DRy#O0!-spnrjxC^ zqv)dUO_cGtJ(D_1IX)oI6J{23|7U)F-1h9;bh#@S!!qm{A@N!| zBwUort$zGOybMfoB=;NLofN04^45R97SGOJfaT z)<^gtyF%Dh41Y(|P4?aXV*>+_D&CBPv-0#ySN#wxx^!jS(7ii_ z;`t&UAn@(h#tUvwK4gB=*h;D4&U@JZZI)nbcW{#{gx040%LWu8L?jcynd&>c|52GZ96b6wBBxx|b2|E5ck*cW$sn>GD`o8KHVq}snLugYWv>@ey=Gd#cHfRi?liI-v=u*s| z%;7p;ovU^|prR^k|D~O+sG!g}QOykpyyedCBJGmrp|bP~n-h&uk4_I9PO zG-ATT8F+aytk*VEQo`0=p=V}l6->r|_;BZukI!w8=7OBH#ccjtbcAPVsZwEy$CQ4J zJ%vR#hvn{{g;E0{Y)ni-J3!Xx#=J-Rpr?RZ9qDTs^TF}EBiQ&z_PGjoBDhga$$DIh>xG`^8O;aBVU7LVj# z8k^P~Xjm5v2QdTyFhMctVu=1Qw>rC+kcP86o_-LZ$g1*zXbV;qpa!icW5cmk5WH<~ z|28$9&(Zw1)WZ!8E0mG$V5Pi`)3E3|PlWcsaBB-qqgdMo3(K(3q!kTPUF6SxSH`Zc zX*x+1lGmi4G+8b$2U+vsM*Xd#@$gXG%+|bGpT8?K ztf#W*;bIgO)#V*ZVC!=!+dMgu3<5{i{ch_moK8_uSf8so`<8!Poh`+Pz@itV{Os>f zC+F8K;*hlJb>`rFsGSdB2)}u!5B$s{@LG?p5xxs%K=TY9i0as;*@_Zu#}FBM5M`eh9JnMT`InbRG!d`+ zbV{FQTwjT)=g3}%d~11qKlt0XJ~((nE>2DW5yYp-9Qo6Dl9I2ob#QuMhBR54D*faM z?VUSb&yt)*KS>S_M*nGP4qY2UULP+)HEOsF0GLj{)(vr{60%%taJT>rTWzPKs|cmc zAR5iV!^QVcLZfPxmE)a5{tEjxA z>;vfs&T`}Cz7TA0xICciSpiW4AeEAH7xj)a)Z5#=E?bjagK1NpkiHRFo&3Fe2VZSr zt(TON@(5y-46CzS$j=YfGDD$tIV7;twnYJN zz~gAh?c+PgjMdU&4I#ARn}1Sx;|?GJ+vG#uHJI+y(>4bw31l?GSyI?t4@i^sJ-i!{ zpx0hc3hzTeprbHJ9S=bQ6WTR&Y)^F{T5LmOI(8lV6oD6H7blsFke(n>QxD!SVTsfZ zMpK*&_*XEcqzVA!K?+V1F4)IFuJJU>w-i!L-Z@D*)&HLhVBw{n6HJbSQ}ZP4R}30% z`{`PyK|L2Jx3!u0Q>}*5oX>9?QmLq@P*UCJ^E^a?_}gXYw-Ib4x0;Rtt3fIsan!S=ZS||2b^5g` z%|*U`o&D#|!^_*=-=88M(|)VYlRvmbZ}0gAD>0=Hr?QHaBY^Y5ugs|y7Opvr&XIMB zpCVMD?8et+KMFF0#|-_p+~*P$)Fq>!V87;iHcClIC?hS?arE_aXF6M0_*YJLwpaBM zq^(uLH3};gRCRZM%n(mC`aYL8<(qhnJp6 z1*&Da)2(NI$Gd9Ks z2=E&ur2tqAPfoV?7NdZ*HvJStg==Ba+aU#Orr;zxCQ95#hGR#oOKN+?ZEbDY{rkkU zHa9kC6P1vJ{d_ogcU9kNGGk+7Z%&pyo@tnX&Ncjsia&hLR%+q+Nz|)|wo*J^86D%V zdeZj?g+5M!$cmfQbD&II_p9yFU~gj8JtN81FWbK=13>K115g7XDJkrv`n$m#8T1AwP3WQdI)& zB`XZtJ-9V~>-;!1X$RLo=nmlVBh2FBw~>5(jS~N9PyNfVe8%N6WzrG_H{c&@{QCpe z<$San#BuQo?m>4=$Uv8=%9@(R{RQaJ5Qtbi$e6KVXhE5or6SVQ0VvtRhx;${AHP!q zbUg;j%TS(aLPPOe3Gc-(8oehJ-Rt7n2PQ!4`0o*VAkc@fo%(Og!5Y@p3fJ~%zCJKAf- zooYN0#=uZ~VE+^upe>+tghTCT#FcG%T3(F|ba0hY`I4|Gg(JC)^es1@vc@Tp2|-J# zxDglu->XGUI4U;&OkoD_T6hsqeEjy=?8pN`s)Ph0NWpWx{;EO&h%(mbYAB^rX=O0H z-`=6`v%^Q4o!{^1XlW6f+Vk=h(58%~KJHc~28N*B8G~Eu%?%F$=g~?#h22zYbOE4j zV)8>~=IC(3uM^DBL)Bs>rboy09_||d`_pQYv9bV0AWF})y<#o zD3%xoz2C&sq_Z5h)#6hmtdw4B*^9N)EuNWB_57#w>Ashb$l4`|z zwLPPwQP)?~M`LOqg`Jlvq3Q*iPEorvEQ>o2wO?hwJYE+8bu~FVJG&aI&!2f#U_33? zUVNayL@MMYK`U-J>23oG(;WK8VkUkYZ;Fbx1vj7@6;w-O7Xw$sFBr$8xxsj1*0H2^QznE3;*Li@p zD8*0j1JH|H6+gefu!7JdovguLT~&bwg2*MhD)|;YtKX)BrDjEVKr>Di<&I;PEQS^W zd8)RfD$*@u2tpgmHmui7le|F#-BM)J(|xY5b}LFCc~YofjocA3V9_1b_HEj37|@A( zf~8Uu#WmwaW5kfTz>%w$w_RVPU344NBv+0%`kp?k&NA<+K}Zx@^yn^ap4X&Ts!+It zqlhf9Mwa_)0UHfkajy=1d@3$}IQPN;FX99B!$0;9ip`*w zO>0m~oo_pK{p;7)?hXrDD2*O2#pIrDRd_~tl5*aQY-!>B)`+_7$s>a z{`3}V%z#D{J2Cs$9O#soz-m^k`R@;hfgoHR|2Wce1zE(*`sfN8?4aJ=nMm!`ql37v zyWABa5w_qg>pTufR6dLoFSVhc(HE&_2Pz>Oz{1t=XV{4)6x2oZW*Y;5OVD~%;= zB1*}Ye-;kGNPHx(g`ciZZ;V;rOJuL+JpNnkZ6Km?ZHOvWu2t{~Y*xUe51bcApO)o> z8Ej>RJXKk_9~pyUrr(}GlbkcD8e(GNpyZ#XkY`D39Ib=68hix)$CDYkGkaqF_LorO z!u^NLj^197D-&Az^x2974?mr||JCah&}s&GJiZ#oE8(kenp#=_Xz3(raK2UhX!9Nr z1J>?k86%J&Ff+|cUbzAf+vUQ1SJ`x)IF83BM8c;1<;G|$X!hb-Sm>3OHj#-O_Hdy6 zn);#_ra@SAGGacq|ziQl$i&$Dlhztm8*Zk=YERNMN6!eApcFYpUAp^3+7T zM#N^={+{4v$V_95X04;Uy}iChi;r@?>XnL>0gxFWldy*O`&{eP7eOrM>?_d$4)c>v z$wJD91`E5*=y)w5-HO@7og;SV-0bYOe>;BKCI6Vbys$wb7FqJ9Np7Wc4oWuV<-R;Z zPJ!9knALW#%{oGw*|#8900O2-WsT$8a!2ItooPVE8-S#dlF~_Pf|YAGfdhqiG|O8> zCaoKY8m;NPG_<7!0STtg&Q7+Z63x7a&>b-t5=M>YbG-z%u|T_t7R#UI4D4In-`CiE z&fRvg03PNdBdargG5rBF+pI*mNVxu_t*wUa?_>^WXO^A?cwS8luE=|&X23ASzf3r9K`C!o9w z+H7~s?KV|^yr%|LrubjKPTiBZA<+Qh4I*tg{!5_&i8R#J7offwa$`*T8b1M+t!9=h-FGu@@&+9l!Txywjjt90Fkhm_}7~M*F{72(0lhXoUq{ zp}lQESt-#@_3HeguLG{%bRUkD`Gt-fP_`0&K4cu(+Pbar8A^zG-X|E4)diDs zN8?d8rGomZ%SvxLWuF^V93eNzQX;01md3%ue-&KsBELW5E_u|)?Z0wy_czA)gOc=Abi+UJI7^y=*`}>(5i$S@<`*#3@C@J z0w4v!9S2aRs=WSMf>aG5Owv%*KxZf8?^>EZkbMJU94C}~=|x0Pabw;fJn+WYR(QC` zz+k#0f&c|&foB^o6XtLnvjN%X#ZR~W<#2BB^BWT{?mEqO5}mpbOZeVgy2KBrxAs6p zK9q6hvN5V_+#Jz4v{%~e!^KsdBIux=5u%^Tw;}}cy=`L!e%o_5n9woEeDsr5#0kVV z9l$`bpKA#Krq-*~er6z1l#QZ2GBAj|IO+IRGmyO0^K*Z`?bh|B3l}6O>44H9;n8G1 ziX@SVQ(*j4R~auKg9Fe6G70zfRr(5ri1RH(xB`bhv*x?QK;UK+^9B%DWbhj)jZXgHVcTR(dc6$<|6M6-kuZv%h0v}f7cAU(1(bk10vgP^s- zSdQ0y7ac0VkD$s9*a|Ck661-W+4rkg{d0a70_Ekefnd@xJ&npzP;A)3aZx!kKE8ao zQU(!1tn-Rec5bf9SpMIaZf?uVKO)(;fRAfAl2f_9*{fRWwquF=qQU1(5DCbwUG41% zR0q6qC_r^UN}Ca@2u|jljtCE@izM}rOiks5^A)%}(vVA>A*6kdQ`sWHn{-7eYM0x; ztFOn9yd0(gk{I+!BnyCe%;WMD@5^)S4k-O1BR_l`wH_D}5@PP3n_~`SaTbVgvlQbS z;PjqfSm*~6TUgCM|8C-0wZExD)DvBnug!*u1U%axu)^?pdgA*@^6ZJ45H&;9&up%R z@K5Va4TBwECD4wCi69&$Toz=%34wo5@3N-xMp93TnMwB_4?|J8BbQ5Ya(?!9n$o)g zgEXY4wT`$zB;AfYWW-01FNx;*hgf2QLP(+okf4r4t)5r}dZd_z=~ zm2yr=iOkRPSr6~EOZ9@VFaV~$t2-4Y$$z|i|bFRZ4dm%gR zc-8c#&s9~jT3YeoVdppXLq~GGP3`T&fY$?z2@qMf1KO#M71hqPkWME$Cnu+m&xd`e z645i{Vp?TFHX2=BO^lSM^lW}rS03L#^P%?-P!vSuny871$Td0aXc+|ThR3E_DltDWNM*xhlp_ur1W<0E63?zKQmm)s=3#(+Ot_bM-opOD3cal zUhTEg9q*?9jV`pC*#6aG^qRJ`ANN92B6*-c>Psm@>xHFLriku3tHfArY(W6WEL-1Y z`rSR|7;?>}rkmYm<{^wA)gQGOGRBNdKU5p~eI1;=qU?>Ew#-Bk2qOSA!20YiH^SuQ zdp{8d=a%e2>3LHr8Z9rc$h4~To>xw~EPXccBFl|ut_NSQB_76XPCH~3IvRdmcZc+| z`~2@1B)`fB>-tnw)?Jr}z6xso?x6)eF_{b7+hJg3R~JK_Ki%uieGf}+!oqT&-L`&C zv-rPx^$W;T!U$?&mOtCec~oJjNYHU~Et8p&qP^bJ)fn9cC#d*CGz1!LGB@}6OZ=5b z83YIbm9Ba|q}^gbv1Idith^1y6zj2E`4ac?8{hTk4ORUcr{Cevp|Ky0VbYwh*U$46 zQt`91CvQug8@|W->!mKq8!w*~@|19HS>V0qb)r&Z*N)W@vf3>Khj=aecX=X?VNF3< z*<$w(euO2RghckEou$c1UC0x46deIqz`*c)zr-hC_sa!J;Kr@G%~f{+YxVJw#!+6` zhMP8kR~GT@?9TN3no30dHh07EcS~$ESN?ui%mr*#1w~JTRY15#hKJRQB2a~2&ND)a zt99vMp%p?U=4ZY)i_q&d01iNIuiq_bOfO?a1-A$yW~V%LVuy5M!!PCk5j|5pE1ft< zjlc7n1?PD+dmKT$g5mc*@c}1z2qYa{G2GwJ8E5Ja=7SRUpo|n8+Pd7h=f(COH2@&@ zGvnkYeWTfJX7{th)~NxUfZSXv*ncQ!CVhvq>0(oooOL{a-LMy5B^oul;mXT5+9!Q) zZ2!Xo_{$WR`-bLZ6{bjh50))zB*&grG`{CMa!*w&`O^vx zZ3tjlfJcs?F${bxmVyl-0=n&si(LkuoJuwJ4px$%pby<`%ZWLNAIJekZtq|KGQ`D> zq)~&%5%_w3>vCpjs0i^P7KNZmUhji1bTXn)l0wk3&CG@r)zny6*Y5&Yv=B<;_v7Rm zl0P21aW!%8fA1l70X^^TooU>Sv4R=@3j>6wK(Ho&29hS>8@@57r&;w$1OS$RQqkAn z0&p(Rw@g3?G~)Yr8$hTwX1qU`QzKzxPnpdFUl~%ej^EYZL=GQ-`=?P|j19FN#Cv=y zC_wN_(?#Fq%0<$hH6VYY%`Blkvb@n@{H-smQ-h*S7?cys$a??kt-Wc@=b7Zg2mU|H zIe~#{0rP`EK!J+$IL0_-CAv6^cB;(hOhudjzDWxaED5CqCDdlv5%5k%a}pY^r8@y@ zCPlsNST_|MPKezH_eP*kwiyInBEF()!nS5+N;lU#Adrpgf9)9-94sqGPD$13wf8h7 zUNQch@IUTc4ITx>&_^NO{*Sd8V0uS0?sLm8j1E^PfO`ORORd5SOW>u!0kA*qG>zch z7#iLNcna$CGxgjYtie~l7~wS}aXOYN(@>Z<^fQ;wAiNV^BbfI=jL>C`9G}Ix)vmUx zs&met2{1BYVIPE;20FHHZ{4eA?b~hB!E|d;;@l0cwr$_zX2|#~ahRDMkGDm_;}{zG ztp{H&E)rCJIa-(~DHJa&ahPUC5c455Hig7|EFT%J)CGMsph_&EwbCj6_44xc9sm(V z#?6EwA@5+t*nKZ*EDjc(j;gt#jsua03It(56hU%1%I7esNz7CB&+@%^jsyyT!QJm( zXh6QFlw>~$6`;@NU9t!m9w`4rwGTP-|+3xql)VSyMwIA5)H?VSaUdNZ@<*7-$}O(r-sk&&s~*O;|}u=-q0^oul3L zL-`%OqWC?5^1GzJClBl0aGBH^N2EU{uii(AGr}$L2GAnlz@fp(v47@-&<=zGAt=e` zYg*`fV93})F)R=;$tNl^2pmgPRDXNs0&Xp6uK;FbN=ZCjS!LQ}!J?AUVI*;9HnP+~uFonyN#7S)lH z%{dU%O=>9#tO%CY-!5Sd=ja{04j2`>_n@HS>gvkF!}IO?cXYsApbtC`AD=YzzI1SK zfFu5B2FHjD>I1;EW%+#N9!!JY=_%u6?bm}DfX4$3BHz}R{iJsr10*pZnV8Xe9b_Fu6U6yy>kEe%U-ns z%h`{N*9NxlP^*f!{X?$gM*DsR?u=Nk1FPz2c z(Z7}+J+e8Te!$oiMXi~4AN5R;+uus!Y(j-TZeG}*mRr?$aqvAu$|Ogq%3c~8KY{kn zT;@&mX!{x`C*9llvgG&sr^M%FX`cFRtZKXrlGX3e?B2(sG4wn`{(M}lwtN;!`JyK5 zQ&`F$QW6w8HG+=0m*Wm}PURulJKAwCGdCk#)Qmr70l7FSi3GBSXSV|ye)JXFI;wWe z91ZgcE*s9NTwW}hy(U$`lTcK|=cRON3HyG8YsH&uG(c$)($p#~W&XJ3BjYDcwhc`- z)h!nF_Ak^GgCX+Bc%M$$|-YSA^cYuK&9X0$1bS-=i5yPo?l|QgXx8oQi&3B+^LrSjU-06rjM` z9H$T$t9HlslfDp@pD$(ttQ}qyGH$|~udlCX6%>SKXVZ0ecSEkj<|VqdzFvrO>$MUX zHNYp!%a(9GTM-Lm%{-Z{Q_>?aDee|dd{fbbc4X{_BWY~tsQ4}yB6=-z17lZJyppc1 zg=$YO^dqKOzeJKhe*74Ueik-1VQ=2FiCH{$b5~pzGlR&8RzN@p9~~hj`Oq!yf?p_Z ze~xT^^{)f#%8r7q8d`r^Z?5gruQVwP=rjg)Pw3-FY4CU5N@OI?lstV#vtCLP$fSW^d0im5G-52_$6LG!AT1 zNp?axnqyKfh7^5DMZ;3^6H!Gu?FeR{3KF@m5}NqsWmQyEI3H4wk--ua)M>`Ln`;W4 zb;-e!0)PWc%KkniDs;&6t0l__3s-zb%BQNdR4vp8mDiYrAp$%U$Mh z_l(#>*1&`UZpBEVTGP9pOj5Tk_jf~|6YFX6%REpr$a>aIr1J6oCy|7u`XAFYvHeRN z-{Vow5(B|aWS%xOG}zeM7JZc`K|KtXs<)NScmV7U0#ee@!9;cF>%_#iEW)N{9D9#i z?r}cj;ut+$5LQID5F-)kVM?|}Hxc#=D2C3`cwcoX;BD6n&3HY8$yyy#a{qBnN`aOsYaKP8}9yw5y6 zw37o0pB$39qd&*pbjmLb-0|WhtSm^W6=BP7xR{t$(iLT1MG?O*$+o%j3Of!-RM?uv zDpNatN+J>6)Q=KXhJ-}ir6?<<-Ho*pEM;7>-$Ip(nZRR-gOWO@<>)>!ISI^?R4Dmr zYHAWS7s!p$HfhZ$S@v&+bZ@8IaEPMM)yf}+W8)=FgA?+HYh}dTp3}L}(b0>Og*p0- zNFqIVSEgGMPIRbQBoaT-E&USU(>Fh&?q_NfLexxu2yI_PXn{^c|CI^f01Yl<-J_R@hx=U zQ^yCaRLBf-IF#?wH`n&Z6b|k#C+l(dqUp!oe4P2h5Fxq}iM;YOo04Vurq@D2RVC%{ zFR>2!#)j;5U3zeU^3(pkP{*s@O|JL*7_2t^tn2#+G>m3Q6Q;D1Z7VFz;u`8WNPER* zc){DBSn}{h?J>e@X)GES&|G)=iW?Q)(ifDVuJFz!njCsY^oB*BC5qUpw|xJ8`F!|cR(Q$SrLp?^&WfK(Z@BcT zu*SHBoRT({kXJwbjtWP#fpwO_peEvLH0t4NTCfqC{m1=(oz#CBIrvID|MFx9Cn;HI9tYL z6Gop-@_jU|-E;ie!vhUhRSiYDA{JvgWaqFJ>`N+BCfu`TX~sr|M-a~)3J^8#Mr-Vo z7kL#++EC}JPY@w-alOOKp%;-=!5m9=p0@erPEn)69_LYv&8lrC{mNBBPsHMbLW9n5 zWt18U`M1=w zZ7JiQd;adxj0{iw@THUTz&+93UR*4cd+?ht@-Y2FNuzL}`g+w?hq@1U56XgM2yx%S zYcs-wn2cAQuW5fcbp{Ov>O15j9j12 z@l;`@WaE8Bc|xgrJb>54W#8U8q6)?k9HYvJ)y^VUoTs=%b@X|6>V3c+Uk~4fq=raF zA{UGyWBlRIG)NiNKeP3IOAjy+p!~%{jHtNzC6T}y_EO;mZ96V%QKPUlFR`~I){R#) zPx*7@u>dO=Kp_k#OAy$^63_n0h>osTJWJc%f0%860}~<5dvxB;d6|A;Iy3XJTWpnX zf&jOGM8XO2XMkb6Jv;ftFF;iZ0&rIy$bmjhFnL`-wX6@;f%-r1MPkauu0_cBCz6k&@)j9<;CFD z7p>-XRBLZCzJ9WNO{&Nm=-B_XFY%SKt(&C?e6@!AE0k;n#Jo=pbL$aQ%>QL@9Z~kNL@M?x|aI->4W0`jfDZm@+HU0PWDS~Yj$=;sDFnaqquk8E?ORP0nS~VI;UmQJ z23{#irukhZ<*IbTN8$_n-1jTyJ|0qi4CjR)I0o^cf2H1EKOGF7q4)_HW9=W4dr-fO zM*4Y6JCj#Es*)D{jCRyc3aPZ^W!q9Gd$czW1J^R!1oMdw>_Oc5gJ=enlMJa`N$c=w zW>mUNS?nO%%bunTWO%W;5QE9rYV0x;_Zflao{b4p+)c~^jqNhrJg!h$CbId!*Fay=m;Wg1k zhKEPGUk}}esT!%3nJ{9ci&^Y2#+(0xmi~U#JPK8cl@V+$*c~uh;fl<_t9fn=8(R2U zoY_Af0k9Sc$AzI=8L0o~lj4Pf_1v$M{kh>oi}b37jNkGkby{yec-{8{9t6VH_kY0F zpk0oG0oiyrEupjMzw7qgVJwc?DF=IPXOSPDz>t<;#oZ^mn8%3LItOFA{nC4cq z5w3av86hm65AEt-%6-w=H@PZz2v2wnvGx;iH`t2OHYDDDkE}fqZN*1^aUZ+}o`g5O z7e+gp<lP4h+JU6Hi9*aDCAIokJNU-XDKrb&Tc?!j`{tZ$889^1M0tBe~l zO5t6D!;m^fhh179A5&>M@(mx{0Gt~du%uGz^oU<7Am;SAkmZg?@Bb!iJqWDym9eDU z@n5`PdWE#azGkS0q?pfiNj)9K=}c z)E#o{0}3oMIwZDkWq=2hS6>US+c64*+1%ucrbXYQbu1x55vbf9A(+uzO|v_pQdMs4 zD0eb=O}dfWAZm+>JGq^GRy6V7rnvLpBR}zd8(Sh3R=qez^H5S#W;p#w-X!X6gzzL? zVF(U|Ks@fgtN#G?;NNt)$6gH$k;iSHx>=k@y@_~hWe_W`-X8`_8WAvL7EsU`rVw5C z-A?_#ZG8FPzoVZaso5TcXZ}G_t32u0ulPw}AusmF*B>9@8F?9DqFANBMq%09`}~CW zo0iWnOc-l(bIVIi|22tU{~T3vIr-!4Y!KTMHVI-IgvHs}`tc!)zoogmXcI3rer}60 zVU48?P9F|zgb~s!NPN>;88M37K~lq=++)};Ie0KDa`UCpN*hl?Zm~uQ6pbmnPo!IY z*bvhUuJozzLe4Jz%8$RcCH0N=Xw)paX2wHOGhO&7*?9lGMBU%Q)rx_V33)JNg#{E-v4?4FBq;EapJ0M5W9cOr1mfE)O5O4!dE59_Eq-6 z>Ce3&4dNFt)lym}CqWJ-cqo72P^2Z|Z%BF`aVsOb4yPX$zl=u6KXxZywrk&`2S3qP zBYAJ$q*aKx!3%NXED*9F7AOQPc_Wdt2t1RF9>w?hiK#7FqZY08>857O`x}aEHmPJt z`{MJI@_+7Vx?J^#Kw= zhlz9XjC-AZropGZ-*_n5`(e}UsM#su4L+d>Hy`L0sY7z%V2Qu?uSwYLRzTFUHucqt z+CaSw?`JkG)@iIMkAUOx2alxf?8WIQ{#hKUycmtw3KM>%!JFCgdP90TpB7y%5`h_# z_Yz9WMDFo?4cr&`<*+EFtJOJO(RZ9zje948_3$E(Gh{o z-V3L%JWkdBHZ!Ya*=mi>%;+#HGu}AuT}ziV?FmP>W=iIN5D>xMOtC+6=OL3lftas|7PoKo)m*S;YlgcT`&OFV2 zDXvm$q~NW}SEe|4bm?}m?CCS;qS~Jzvc{cBN;xQ^=Ipn&%-lM3c6}{^<$q#Uez~;x zhd9Vv9(lHE9jRz)bV7t^Ztje~;llrH?o38*Imy<^siHog4#Z0P)drhnPMq9EE`xB| z@ALoQTtvb%PF-+n^$MLD)po5{4=Bh8Od|Q!OyMlDzERZj?p@o}$r6`Iw97uN85uzc z9ihMYV1HM|t@tK+;fEdews-mYF~7MB&UQQuH7Uksr8mdcA(M5qNWSa8)|XA_bA3U_ ze53!(VIN~n^p*Pt)#bXouPcdaN5(@9)a=&G&n1`vFCA$@PiM)3ctb*J=eptcAZ6%& z^U0}A4_(XkF}JK)=RC&&@0VL8eho>JWs#kxpc((==~ATgW##pw=A&C$e0&sFN7!6xt31;@`_yI)2Pbb2sc?_m;P?b zm@LEH-?{KpkWuE3UYZvk0cqgkWa-8Ym*0TKv>_MS;t9dMfdBrtV=+(IuYC1@K~*v; zrtJ;Ic4Y{?kYzY9yBb@a>N;@4D9JOJt(#S>LNXmM0m9=X-v zk&%porgKkrI|tUfYyJmIw)(fIXk8uRMT3qOUyhm9)?H;4t{x#@-zSnsPmX=c4~L&} zRDEsyxREPg|JBh*=jpz$3A_d0T`c;V`-wSu@fH@rMn*bj*_uWBW!`&TV(yM@&!1;{ z1Uk)nAk&i9*!b;=@Pv$RRj?e9`pl`d2d#N3nyTC2)i>MH+`*s5#+LH-CLkGolMT#? z8&(b^4suG%jqm6!do0qtUhlq^2&~K`w5#fum!s}c5Q0_M3X4&O1EG-@3 z$n+P0AaeY-`3ng>L8lPs)OT~)_s(7ck@k66m+P} z@1oQH(}L$IqzuV$h4PE18S;0VI*V{oiMsl}!^YB<+}jJCon5wdb74jdkBuknX*Z>C zz(qUegM_|s6VbkIW6aMpeBBoAIEx7T)HO8l@F3+8FcXsz;mMMa!Y1lNnXZvCptz3Y zp1j=deNn;tkni^E8eh~Lv#_O}+#^==x3|S_#JB$_4*xN9j}EK}BB{)bt|h5dKVAJ; zM{aSq3@3>{_bC;!ouwFisZB1z;3H8vHMh8&%dPQbc-ggnh#d1|^p%@icR z26%C>@8Z(`gRNGnaH-PzerT!rg6ld6_x*hmw&rv8*s1=a0<@l^VmHT9O;%a6HnR1- z*46UpjlAT$nDlO=vB6luF1))<~1^ai1j1JHN_Pqq>e9#Jn_$NVjp@nXcpn2+me4n1h#JOzx4AiG);O@tT@hyFAXz7XSVz&#Kq0sMyqC6(s4iu>YyvLLzi*8?p zu;s&kDTAT%ZKzJao>@=$(O)xgqu<P(hDmbjLfRpf@mVg@{a+ zBXMWkqRnvS8<`9qif}Yx*@qPC#?!&X`FR*4eu^$ynB&u)juBpECYW*8=G%}u zi;CKUb{_)?>rkO8LMmbs+3f;&ZoR9Gg8Su>!)!uEiTd8_zkz}6fnithtt4+;Lw7xm z`F`-?;5?c!3-=-pu~&fY`iv6s%W&5oYFv#^C$>-5d5YlQ)$yJg+T8|T7ZFtOY8StR zeOJ+~h>xi-y3g~8=00oKF9$oj;@!U=1oQyP6}svO`(Boq9v_>Y8Jk{^rIIR35_9Gp zkleRotY`w9&Ik8(OHF}y_&`wbnp@&y*dOyFD%!kQ+A0sjCXcwdIQ)ORGkq(4$uInj zT}~6ifI*c677w@ZQDJ+9g?$f%A - - - 4.0.0 - - org.kie.kogito.examples - serverless-workflow-github-showcase - 1.0-SNAPSHOT - - pr-checker-workflow - Kogito Example :: Serverless Workflow Github Showcase :: PR Checker Workflow - - true - 2.13.1.Final - quarkus-bom - io.quarkus - 2.13.1.Final - org.kie.kogito - kogito-bom - 1.29.0.Final - 3.8.1 - 17 - - - - - ${quarkus.platform.group-id} - ${quarkus.platform.artifact-id} - ${quarkus.platform.version} - pom - import - - - ${kogito.bom.group-id} - ${kogito.bom.artifact-id} - ${kogito.bom.version} - pom - import - - - - - - org.apache.kie.sonataflow - sonataflow-quarkus - - - org.kie - kie-addons-quarkus-knative-eventing - - - io.quarkus - quarkus-resteasy - - - io.quarkus - quarkus-resteasy-jackson - - - io.quarkus - quarkus-smallrye-openapi - - - io.quarkus - quarkus-smallrye-health - - - io.quarkus - quarkus-junit5 - test - - - io.rest-assured - rest-assured - test - - - com.github.tomakehurst - wiremock-jre8 - ${version.com.github.tomakehurst.wiremock} - test - - - - ${project.artifactId} - - - maven-compiler-plugin - ${version.compiler.plugin} - - ${maven.compiler.release} - - - - org.codehaus.mojo - properties-maven-plugin - 1.0.0 - - - - set-system-properties - - - - - jbpm.enable.multi.con - true - - - - - - - - ${quarkus.platform.group-id} - quarkus-maven-plugin - ${quarkus-plugin.version} - - - - build - - - - - - maven-surefire-plugin - ${version.surefire.plugin} - - - org.jboss.logmanager.LogManager - ${maven.home} - - - - - - - - - container - - - container - - - - container - - - - io.quarkus - quarkus-container-image-jib - - - - - diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/java/org/kogito/examples/sw/github/workflow/GitHubClient.java b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/java/org/kogito/examples/sw/github/workflow/GitHubClient.java deleted file mode 100644 index 160445f471..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/java/org/kogito/examples/sw/github/workflow/GitHubClient.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.workflow; - -import java.util.List; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; - -import com.fasterxml.jackson.databind.JsonNode; - -@Path("/repo") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -@RegisterRestClient -public interface GitHubClient { - - @POST - @Path("/{user}/{name}/pr/{number}/labels") - Response addLabels(@PathParam("user") String user, - @PathParam("name") String repoName, - @PathParam("number") Integer prNumber, - List labels); - - @POST - @Path("/{user}/{name}/pr/{number}/reviewers") - Response addReviewers(@PathParam("user") String user, - @PathParam("name") String repoName, - @PathParam("number") Integer prNumber, - List reviewers); - - @GET - @Path("/{user}/{name}/pr/{number}/files") - JsonNode fetchFiles(@PathParam("user") String user, - @PathParam("name") String repoName, - @PathParam("number") Integer prNumber); -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/java/org/kogito/examples/sw/github/workflow/GitHubService.java b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/java/org/kogito/examples/sw/github/workflow/GitHubService.java deleted file mode 100644 index 99369f3b6f..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/java/org/kogito/examples/sw/github/workflow/GitHubService.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.workflow; - -import java.util.Collections; -import java.util.Objects; - -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; - -import org.eclipse.microprofile.rest.client.inject.RestClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - -/** - * Simple wrapper class to call the github-service. - */ -@ApplicationScoped -public class GitHubService { - - private static final Logger LOGGER = LoggerFactory.getLogger(GitHubService.class); - - @Inject - @RestClient - GitHubClient gitHubClient; - - public JsonNode addLabels(JsonNode pullRequest) { - LOGGER.info("Adding labels to PR"); - final String repoName = getRepoFullName(pullRequest); - if (repoName == null) { - return pullRequest; - } - if (pullRequest.get("labels") == null) { - LOGGER.error("Skipping adding labels. 'labels' attribute not found in the PR object: {}", pullRequest); - return pullRequest; - } - LOGGER.info("Calling GitHub Client to perform addLabels action"); - gitHubClient.addLabels( - repoName.split("/")[0], - repoName.split("/")[1], - Objects.requireNonNull(pullRequest.get("number")).asInt(), - Collections.singletonList(pullRequest.get("labels").asText())); - return pullRequest; - } - - public JsonNode addReviewers(JsonNode pullRequest) { - LOGGER.info("Adding reviewers to PR"); - final String repoName = getRepoFullName(pullRequest); - if (repoName == null) { - return pullRequest; - } - if (pullRequest.get("reviewers") == null) { - LOGGER.error("Skipping adding reviewers. 'reviewers' attribute not found in the PR object: {}", pullRequest); - return pullRequest; - } - LOGGER.info("Calling GitHub Client to perform addReviewers action"); - gitHubClient.addReviewers( - repoName.split("/")[0], - repoName.split("/")[1], - Objects.requireNonNull(pullRequest.get("number")).asInt(), - Collections.singletonList(pullRequest.get("reviewers").asText())); - return pullRequest; - } - - public JsonNode fetchPRFiles(JsonNode pullRequest) { - LOGGER.info("Fetching files for PR"); - final String repoName = getRepoFullName(pullRequest); - if (repoName == null) { - return pullRequest; - } - final JsonNode jsonNode = gitHubClient.fetchFiles( - repoName.split("/")[0], - repoName.split("/")[1], - Objects.requireNonNull(pullRequest.get("number")).asInt()); - if (pullRequest.isObject()) { - ((ObjectNode) pullRequest).replace("files", jsonNode); - } else { - LOGGER.error("Pull Request JsonNode is not an object: {}", pullRequest); - } - return pullRequest; - } - - private String getRepoFullName(JsonNode pullRequest) { - if (pullRequest.get("repository") == null) { - LOGGER.error("Impossible to resolve the repository name for {}, no 'repository' tag found.", pullRequest); - return null; - } - final String repoName = pullRequest.get("repository").get("full_name").asText(); - if ("".equals(repoName)) { - LOGGER.error("Impossible to resolve the repository name for {}", pullRequest); - return null; - } else if (!repoName.contains("/")) { - LOGGER.error("Wrong format for repository name {}", repoName); - return null; - } - LOGGER.info("Extracted repository name from PR: {}", repoName); - return repoName; - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/application.properties b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/application.properties deleted file mode 100644 index 1e456969aa..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/application.properties +++ /dev/null @@ -1,44 +0,0 @@ -# -# 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. -# - -quarkus.log.level=INFO -quarkus.swagger-ui.always-include=true - -org.kogito.examples.sw.github.workflow.GitHubClient/mp-rest/url=${GITHUB_SERVICE_URI} -org.kogito.examples.sw.github.workflow.GitHubClient/mp-rest/scope=javax.inject.Singleton - -mp.messaging.incoming.kogito_incoming_stream.connector=quarkus-http -mp.messaging.incoming.kogito_incoming_stream.path=/ - - -mp.messaging.outgoing.pr_verified.connector=quarkus-http -mp.messaging.outgoing.pr_verified.url=${K_SINK} - -mp.messaging.outgoing.checker_workflow_frontend.connector=quarkus-http -mp.messaging.outgoing.checker_workflow_frontend.url=${K_SINK} -mp.messaging.outgoing.checker_workflow_backend.connector=quarkus-http -mp.messaging.outgoing.checker_workflow_backend.url=${K_SINK} - -# profile to pack this example into a container, to use it execute activate the maven container profile, -Dcontainer -%container.quarkus.container-image.build=true -%container.quarkus.container-image.push=false -%container.quarkus.container-image.group=${USER} -%container.quarkus.container-image.registry=dev.local -%container.quarkus.container-image.tag=1.0-SNAPSHOT - diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-backend.sw.json b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-backend.sw.json deleted file mode 100644 index 66486568a9..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-backend.sw.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "id": "handle_backend", - "name": "HandleBackend", - "expressionLang": "jsonpath", - "version": "1.0", - "start": "CheckBackend", - "functions": [ - { - "name": "AddLabels", - "type": "custom", - "operation": "service:java:org.kogito.examples.sw.github.workflow.GitHubService::addLabels" - }, - { - "name": "AddReviewers", - "type": "custom", - "operation": "service:java:org.kogito.examples.sw.github.workflow.GitHubService::addReviewers" - } - ], - "events": [ - { - "name": "BackendNewChange", - "source": "checker_workflow_backend", - "type": "backend_changed", - "kind": "produced" - } - ], - "states": [ - { - "name": "CheckBackend", - "type": "switch", - "dataConditions": [ - { - "condition": "${ $.files[?(@ =~ /^.*backend.*$/i )] }", - "transition": { - "produceEvents": [ - { - "eventRef": "BackendNewChange" - } - ], - "nextState": "InjectBackendData" - } - }, - { - "condition": "${ $.files[?(@ =~ /^(?!.*backend).*$/i )] }", - "end": true - } - ] - }, - { - "name": "InjectBackendData", - "type": "inject", - "data": { - "labels": "backend", - "reviewers": "JaneDoe" - }, - "transition": "HandleBackend" - }, - { - "name": "HandleBackend", - "type": "operation", - "actions": [ - { - "name": "addBackendLabels", - "functionRef": "AddLabels" - }, - { - "name": "addBackendReviewers", - "functionRef": "AddReviewers" - } - ], - "end": true - } - ] -} \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-backend.sw.svg b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-backend.sw.svg deleted file mode 100644 index 9b8b118492..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-backend.sw.svg +++ /dev/null @@ -1 +0,0 @@ -HandleBackend v1.0CheckBackendType: Switch StateCondition type: data-basedNum. of conditions: 2InjectBackendDataType: Inject StateHandleBackendType: Operation StateAction mode: nullNum. of actions: 2Produced Events: BackendNewChangeState Types and Border Colors:EventOperationSwitchDelayParallelSubFlowInjectForEachCallBack \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-frontend.sw.json b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-frontend.sw.json deleted file mode 100644 index 690e4baf94..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-frontend.sw.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "id": "handle_frontend", - "name": "HandleFrontend", - "expressionLang": "jsonpath", - "version": "1.0", - "start": "CheckFrontend", - "functions": [ - { - "name": "AddLabels", - "type": "custom", - "operation": "service:org.kogito.examples.sw.github.workflow.GitHubService::addLabels" - }, - { - "name": "AddReviewers", - "type": "custom", - "operation": "service:org.kogito.examples.sw.github.workflow.GitHubService::addReviewers" - } - ], - "events": [ - { - "name": "FrontendNewChange", - "source": "checker_workflow_frontend", - "type": "frontend_changed", - "kind": "produced" - } - ], - "states": [ - { - "name": "CheckFrontend", - "type": "switch", - "dataConditions": [ - { - "condition": "{{ $.files[?(@ =~ /^.*frontend.*$/i )] }}", - "transition": { - "produceEvents": [ - { - "eventRef": "FrontendNewChange" - } - ], - "nextState": "InjectFrontendData" - } - }, - { - "condition": "{{ $.files[?(@ =~ /^(?!.*frontend).*$/i )] }}", - "end": true - } - ] - }, - { - "name": "InjectFrontendData", - "type": "inject", - "data": { - "labels": "frontend", - "reviewers": "JohnDoe" - }, - "transition": "HandleFrontend" - }, - { - "name": "HandleFrontend", - "type": "operation", - "actions": [ - { - "name": "addFrontendLabels", - "functionRef": "AddLabels" - }, - { - "name": "addFrontendReviewers", - "functionRef": "AddReviewers" - } - ], - "end": true - } - ] -} \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-frontend.sw.svg b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-frontend.sw.svg deleted file mode 100644 index 8762c3f417..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/handle-frontend.sw.svg +++ /dev/null @@ -1 +0,0 @@ -HandleFrontend v1.0CheckFrontendType: Switch StateCondition type: data-basedNum. of conditions: 2InjectFrontendDataType: Inject StateHandleFrontendType: Operation StateAction mode: nullNum. of actions: 2Produced Events: FrontendNewChangeState Types and Border Colors:EventOperationSwitchDelayParallelSubFlowInjectForEachCallBack \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/pr-checker.sw.json b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/pr-checker.sw.json deleted file mode 100644 index e0b21c11c2..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/pr-checker.sw.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "id": "prchecker", - "name": "Github PR Checker Workflow", - "expressionLang": "jsonpath", - "version": "1.0", - "start": "HandleOpenPR", - "functions": [ - { - "name": "FetchPRFiles", - "type": "custom", - "operation": "service:java:org.kogito.examples.sw.github.workflow.GitHubService::fetchPRFiles" - } - ], - "events": [ - { - "name": "PullRequest", - "source": "https://github.com/your-username/your-repository", - "type": "dev.knative.source.github.pull_request", - "kind": "consumed" - }, - { - "name": "PRVerified", - "source": "checker_pr_verified", - "type": "pr_verified", - "kind": "produced" - } - ], - "states": [ - { - "name": "HandleOpenPR", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "PullRequest" - ], - "actions": [ - { - "functionRef": "FetchPRFiles" - } - ] - } - ], - "transition": "DecoratePullRequest" - }, - { - "name": "DecoratePullRequest", - "type": "parallel", - "branches": [ - { - "name": "HandleBackendSubFlow", - "actions" : [{"subFlowRef":"handle_backend" }] - }, - { - "name": "HandleFrontendSubFlow", - "actions" : [{"subFlowRef":"handle_frontend" }] - } - ], - "end": { - "produceEvents": [ - { - "eventRef": "PRVerified" - } - ] - } - } - ] -} - diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/pr-checker.sw.svg b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/pr-checker.sw.svg deleted file mode 100644 index 3e22b974be..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/main/resources/pr-checker.sw.svg +++ /dev/null @@ -1 +0,0 @@ -Github PR Checker Workflow v1.0HandleOpenPRType: Event StateEvents: PullRequestDecoratePullRequestType: Parallel StateCompletion type: "and"Num. of branches: 2Produced Events: PRVerifiedState Types and Border Colors:EventOperationSwitchDelayParallelSubFlowInjectForEachCallBack \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/GitHubServiceMockServer.java b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/GitHubServiceMockServer.java deleted file mode 100644 index c00ca7790b..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/GitHubServiceMockServer.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.workflow; - -import java.util.Collections; -import java.util.Map; - -import com.github.tomakehurst.wiremock.WireMockServer; -import com.github.tomakehurst.wiremock.core.WireMockConfiguration; - -import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; - -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.post; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; - -public class GitHubServiceMockServer implements QuarkusTestResourceLifecycleManager { - - private WireMockServer wireMockServer; - - @Override - public Map start() { - wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().dynamicPort()); - wireMockServer.start(); - - wireMockServer.stubFor(post(urlEqualTo("/repo/your-username/your-repository/pr/2/labels")) - .willReturn(aResponse() - .withStatus(200) - .withHeader("Content-Type", "application/json"))); - wireMockServer.stubFor(post(urlEqualTo("/repo/your-username/your-repository/pr/2/reviewers")) - .willReturn(aResponse() - .withStatus(200) - .withHeader("Content-Type", "application/json"))); - wireMockServer.stubFor(get(urlEqualTo("/repo/your-username/your-repository/pr/2/files")) - .willReturn(aResponse() - .withStatus(200) - .withHeader("Content-Type", "application/json") - .withBody("[ \"src/main/java/Backend.java\", \"src/main/java/AnotherClass.java\" ]"))); - - return Collections.singletonMap("org.kogito.examples.sw.github.workflow.GitHubClient/mp-rest/url", wireMockServer.baseUrl()); - } - - @Override - public void stop() { - if (wireMockServer != null) { - wireMockServer.stop(); - } - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/GitHubServiceTest.java b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/GitHubServiceTest.java deleted file mode 100644 index 6cfae2d569..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/GitHubServiceTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.workflow; - -import java.io.IOException; - -import javax.inject.Inject; - -import org.junit.jupiter.api.Test; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.junit.QuarkusTest; - -import static org.junit.jupiter.api.Assertions.assertNotNull; - -@QuarkusTest -@QuarkusTestResource(GitHubServiceMockServer.class) -class GitHubServiceTest { - - final ObjectMapper objectMapper = new ObjectMapper(); - - @Inject - GitHubService gitHubServiceBackend; - - @Test - void addLabels() throws IOException { - final JsonNode jsonNode = objectMapper.readTree(this.getClass().getResource("/mock/addLabels.json")); - assertNotNull(jsonNode); - final JsonNode reply = gitHubServiceBackend.addLabels(jsonNode); - assertNotNull(reply); - assertNotNull(reply.get("labels")); - } - - @Test - void addReviewers() throws IOException { - final JsonNode jsonNode = objectMapper.readTree(this.getClass().getResource("/mock/addReviewers.json")); - assertNotNull(jsonNode); - final JsonNode reply = gitHubServiceBackend.addReviewers(jsonNode); - assertNotNull(reply); - assertNotNull(reply.get("reviewers")); - } - - @Test - void fetchPRFiles() throws IOException { - final JsonNode jsonNode = objectMapper.readTree(this.getClass().getResource("/mock/addReviewers.json")); - assertNotNull(jsonNode); - final JsonNode reply = gitHubServiceBackend.fetchPRFiles(jsonNode); - assertNotNull(reply); - assertNotNull(reply.get("reviewers")); - assertNotNull(reply.get("files")); - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/MessageSinkServer.java b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/MessageSinkServer.java deleted file mode 100644 index e17d643f7d..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/MessageSinkServer.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.workflow; - -import java.util.Map; - -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Produces; - -import com.github.tomakehurst.wiremock.WireMockServer; -import com.github.tomakehurst.wiremock.core.WireMockConfiguration; - -import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; - -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.post; - -/** - * Mocked server to receive the produced messages by our SW. - */ -@ApplicationScoped -public class MessageSinkServer implements QuarkusTestResourceLifecycleManager { - - WireMockServer sinkServer; - - @Produces - public WireMockServer getSinkServer() { - return sinkServer; - } - - @Override - public Map start() { - sinkServer = new WireMockServer(WireMockConfiguration.options().port(8181)); - sinkServer.start(); - sinkServer.stubFor(post("/").willReturn(aResponse().withBody("ok").withStatus(200))); - - return null; - } - - @Override - public void stop() { - if (sinkServer != null) { - sinkServer.stop(); - } - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/PRCheckerWorkflowTest.java b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/PRCheckerWorkflowTest.java deleted file mode 100644 index 927a4bf655..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/java/org/kogito/examples/sw/github/workflow/PRCheckerWorkflowTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - */ -package org.kogito.examples.sw.github.workflow; - -import java.io.IOException; -import java.nio.charset.Charset; - -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.github.jknack.handlebars.internal.Files; - -import io.cloudevents.jackson.JsonFormat; -import io.quarkus.test.common.QuarkusTestResource; -import io.quarkus.test.junit.QuarkusTest; - -import static io.restassured.RestAssured.given; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -@QuarkusTest -@QuarkusTestResource(GitHubServiceMockServer.class) // mock the GitHub API -@QuarkusTestResource(MessageSinkServer.class) // mock the Knative Eventing Broker -class PRCheckerWorkflowTest { - - final static Logger LOGGER = LoggerFactory.getLogger(PRCheckerWorkflowTest.class); - - @Test - void onPREdited() throws IOException { - final String pullRequestEvent = Files.read(this.getClass().getResourceAsStream("/mock/ce_pr_edited.json"), Charset.defaultCharset()); - assertNotNull(pullRequestEvent); - LOGGER.debug("CE read as {}", pullRequestEvent); - - given() - .contentType(JsonFormat.CONTENT_TYPE) - .body(pullRequestEvent).post("/").then().statusCode(202); - } -} diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/application.properties b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/application.properties deleted file mode 100644 index e3b8b85d1c..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/application.properties +++ /dev/null @@ -1,34 +0,0 @@ -# -# 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. -# - -quarkus.log.category."org.kogito".level=INFO -quarkus.log.category."org.kie.kogito.app".level=INFO - -org.kogito.examples.sw.github.workflow.GitHubClient/mp-rest/url= -mp.messaging.outgoing.kogito_outgoing_stream.url=http://localhost:9090/ - -# our sink server will sink these messages. See: org.kogito.examples.sw.github.workflow.MessageSinkServer -mp.messaging.outgoing.pr_verified.connector=quarkus-http -mp.messaging.outgoing.pr_verified.url=http://localhost:8181/ - -mp.messaging.outgoing.checker_workflow_frontend.connector=quarkus-http -mp.messaging.outgoing.checker_workflow_frontend.url=http://localhost:8181/ - -mp.messaging.outgoing.checker_workflow_backend.connector=quarkus-http -mp.messaging.outgoing.checker_workflow_backend.url=http://localhost:8181/ diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/addLabels.json b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/addLabels.json deleted file mode 100644 index 15794becb3..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/addLabels.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "number": 2, - "labels": "bug", - "repository": { - "id": 292004268, - "node_id": "MDEwOlJlcG9zaXRvcnkyOTIwMDQyNjg=", - "name": "kogito-sw-demo", - "full_name": "your-username/your-repository", - "owner": { - "login": "your-username", - "node_id": "MDQ6VXNlcjE1MzgwMDA=", - "id": 1538000, - "avatar_url": "https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/your-username", - "html_url": "https://github.com/your-username", - "followers_url": "https://api.github.com/users/your-username/followers", - "following_url": "https://api.github.com/users/your-username/following{/other_user}", - "gists_url": "https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url": "https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/your-username/subscriptions", - "organizations_url": "https://api.github.com/users/your-username/orgs", - "repos_url": "https://api.github.com/users/your-username/repos", - "events_url": "https://api.github.com/users/your-username/events{/privacy}", - "received_events_url": "https://api.github.com/users/your-username/received_events", - "type": "User", - "site_admin": false - }, - "private": false, - "html_url": "https://github.com/your-username/your-repository", - "description": "Kogito Serverless Workflow Demo App", - "fork": false, - "url": "https://api.github.com/repos/your-username/your-repository", - "forks_url": "https://api.github.com/repos/your-username/your-repository/forks", - "keys_url": "https://api.github.com/repos/your-username/your-repository/keys{/key_id}", - "collaborators_url": "https://api.github.com/repos/your-username/your-repository/collaborators{/collaborator}", - "teams_url": "https://api.github.com/repos/your-username/your-repository/teams", - "hooks_url": "https://api.github.com/repos/your-username/your-repository/hooks", - "issue_events_url": "https://api.github.com/repos/your-username/your-repository/issues/events{/number}", - "events_url": "https://api.github.com/repos/your-username/your-repository/events", - "assignees_url": "https://api.github.com/repos/your-username/your-repository/assignees{/user}", - "branches_url": "https://api.github.com/repos/your-username/your-repository/branches{/branch}", - "tags_url": "https://api.github.com/repos/your-username/your-repository/tags", - "blobs_url": "https://api.github.com/repos/your-username/your-repository/git/blobs{/sha}", - "git_tags_url": "https://api.github.com/repos/your-username/your-repository/git/tags{/sha}", - "git_refs_url": "https://api.github.com/repos/your-username/your-repository/git/refs{/sha}", - "trees_url": "https://api.github.com/repos/your-username/your-repository/git/trees{/sha}", - "statuses_url": "https://api.github.com/repos/your-username/your-repository/statuses/{sha}", - "languages_url": "https://api.github.com/repos/your-username/your-repository/languages", - "stargazers_url": "https://api.github.com/repos/your-username/your-repository/stargazers", - "contributors_url": "https://api.github.com/repos/your-username/your-repository/contributors", - "subscribers_url": "https://api.github.com/repos/your-username/your-repository/subscribers", - "subscription_url": "https://api.github.com/repos/your-username/your-repository/subscription", - "commits_url": "https://api.github.com/repos/your-username/your-repository/commits{/sha}", - "git_commits_url": "https://api.github.com/repos/your-username/your-repository/git/commits{/sha}", - "comments_url": "https://api.github.com/repos/your-username/your-repository/comments{/number}", - "issue_comment_url": "https://api.github.com/repos/your-username/your-repository/issues/comments{/number}", - "contents_url": "https://api.github.com/repos/your-username/your-repository/contents/{+path}", - "compare_url": "https://api.github.com/repos/your-username/your-repository/compare/{base}...{head}", - "merges_url": "https://api.github.com/repos/your-username/your-repository/merges", - "archive_url": "https://api.github.com/repos/your-username/your-repository/{archive_format}{/ref}", - "downloads_url": "https://api.github.com/repos/your-username/your-repository/downloads", - "issues_url": "https://api.github.com/repos/your-username/your-repository/issues{/number}", - "pulls_url": "https://api.github.com/repos/your-username/your-repository/pulls{/number}", - "milestones_url": "https://api.github.com/repos/your-username/your-repository/milestones{/number}", - "notifications_url": "https://api.github.com/repos/your-username/your-repository/notifications{?since,all,participating}", - "labels_url": "https://api.github.com/repos/your-username/your-repository/labels{/name}", - "releases_url": "https://api.github.com/repos/your-username/your-repository/releases{/id}", - "created_at": "2020-09-01T13:23:59Z", - "updated_at": "2020-09-01T13:24:04Z", - "pushed_at": "2020-09-01T21:23:46Z", - "git_url": "git://github.com/your-username/your-repository.git", - "ssh_url": "git@github.com:your-username/your-repository.git", - "clone_url": "https://github.com/your-username/your-repository.git", - "svn_url": "https://github.com/your-username/your-repository", - "homepage": null, - "size": 5, - "stargazers_count": 0, - "watchers_count": 0, - "language": null, - "has_issues": true, - "has_downloads": true, - "has_wiki": true, - "has_pages": false, - "forks_count": 0, - "mirror_url": null, - "open_issues_count": 2, - "forks": 0, - "open_issues": 2, - "watchers": 0, - "default_branch": "main" - } -} \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/addReviewers.json b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/addReviewers.json deleted file mode 100644 index ef1d2007fc..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/addReviewers.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "number": 2, - "reviewers": "Zeh", - "repository": { - "id": 292004268, - "node_id": "MDEwOlJlcG9zaXRvcnkyOTIwMDQyNjg=", - "name": "kogito-sw-demo", - "full_name": "your-username/your-repository", - "owner": { - "login": "your-username", - "node_id": "MDQ6VXNlcjE1MzgwMDA=", - "id": 1538000, - "avatar_url": "https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/your-username", - "html_url": "https://github.com/your-username", - "followers_url": "https://api.github.com/users/your-username/followers", - "following_url": "https://api.github.com/users/your-username/following{/other_user}", - "gists_url": "https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url": "https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/your-username/subscriptions", - "organizations_url": "https://api.github.com/users/your-username/orgs", - "repos_url": "https://api.github.com/users/your-username/repos", - "events_url": "https://api.github.com/users/your-username/events{/privacy}", - "received_events_url": "https://api.github.com/users/your-username/received_events", - "type": "User", - "site_admin": false - }, - "private": false, - "html_url": "https://github.com/your-username/your-repository", - "description": "Kogito Serverless Workflow Demo App", - "fork": false, - "url": "https://api.github.com/repos/your-username/your-repository", - "forks_url": "https://api.github.com/repos/your-username/your-repository/forks", - "keys_url": "https://api.github.com/repos/your-username/your-repository/keys{/key_id}", - "collaborators_url": "https://api.github.com/repos/your-username/your-repository/collaborators{/collaborator}", - "teams_url": "https://api.github.com/repos/your-username/your-repository/teams", - "hooks_url": "https://api.github.com/repos/your-username/your-repository/hooks", - "issue_events_url": "https://api.github.com/repos/your-username/your-repository/issues/events{/number}", - "events_url": "https://api.github.com/repos/your-username/your-repository/events", - "assignees_url": "https://api.github.com/repos/your-username/your-repository/assignees{/user}", - "branches_url": "https://api.github.com/repos/your-username/your-repository/branches{/branch}", - "tags_url": "https://api.github.com/repos/your-username/your-repository/tags", - "blobs_url": "https://api.github.com/repos/your-username/your-repository/git/blobs{/sha}", - "git_tags_url": "https://api.github.com/repos/your-username/your-repository/git/tags{/sha}", - "git_refs_url": "https://api.github.com/repos/your-username/your-repository/git/refs{/sha}", - "trees_url": "https://api.github.com/repos/your-username/your-repository/git/trees{/sha}", - "statuses_url": "https://api.github.com/repos/your-username/your-repository/statuses/{sha}", - "languages_url": "https://api.github.com/repos/your-username/your-repository/languages", - "stargazers_url": "https://api.github.com/repos/your-username/your-repository/stargazers", - "contributors_url": "https://api.github.com/repos/your-username/your-repository/contributors", - "subscribers_url": "https://api.github.com/repos/your-username/your-repository/subscribers", - "subscription_url": "https://api.github.com/repos/your-username/your-repository/subscription", - "commits_url": "https://api.github.com/repos/your-username/your-repository/commits{/sha}", - "git_commits_url": "https://api.github.com/repos/your-username/your-repository/git/commits{/sha}", - "comments_url": "https://api.github.com/repos/your-username/your-repository/comments{/number}", - "issue_comment_url": "https://api.github.com/repos/your-username/your-repository/issues/comments{/number}", - "contents_url": "https://api.github.com/repos/your-username/your-repository/contents/{+path}", - "compare_url": "https://api.github.com/repos/your-username/your-repository/compare/{base}...{head}", - "merges_url": "https://api.github.com/repos/your-username/your-repository/merges", - "archive_url": "https://api.github.com/repos/your-username/your-repository/{archive_format}{/ref}", - "downloads_url": "https://api.github.com/repos/your-username/your-repository/downloads", - "issues_url": "https://api.github.com/repos/your-username/your-repository/issues{/number}", - "pulls_url": "https://api.github.com/repos/your-username/your-repository/pulls{/number}", - "milestones_url": "https://api.github.com/repos/your-username/your-repository/milestones{/number}", - "notifications_url": "https://api.github.com/repos/your-username/your-repository/notifications{?since,all,participating}", - "labels_url": "https://api.github.com/repos/your-username/your-repository/labels{/name}", - "releases_url": "https://api.github.com/repos/your-username/your-repository/releases{/id}", - "created_at": "2020-09-01T13:23:59Z", - "updated_at": "2020-09-01T13:24:04Z", - "pushed_at": "2020-09-01T21:23:46Z", - "git_url": "git://github.com/your-username/your-repository.git", - "ssh_url": "git@github.com:your-username/your-repository.git", - "clone_url": "https://github.com/your-username/your-repository.git", - "svn_url": "https://github.com/your-username/your-repository", - "homepage": null, - "size": 5, - "stargazers_count": 0, - "watchers_count": 0, - "language": null, - "has_issues": true, - "has_downloads": true, - "has_wiki": true, - "has_pages": false, - "forks_count": 0, - "mirror_url": null, - "open_issues_count": 2, - "forks": 0, - "open_issues": 2, - "watchers": 0, - "default_branch": "main" - } -} \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/ce_pr_comment.json b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/ce_pr_comment.json deleted file mode 100644 index 5d73643f75..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/ce_pr_comment.json +++ /dev/null @@ -1,204 +0,0 @@ -{ - "specversion": "1.0", - "type": "dev.knative.source.github.issue_comment", - "source": "https://github.com/your-username/your-repository", - "subject": "2#issuecomment-697427391", - "id": "7f941b80-fda7-11ea-8714-11fe82275095", - "time": "2020-09-23T14:17:37.408032117Z", - "datacontenttype": "application/json", - "data": { - "action": "created", - "issue": { - "url": "https://api.github.com/repos/your-username/your-repository/issues/2", - "labels_url": "https://api.github.com/repos/your-username/your-repository/issues/2/labels{/name}", - "comments_url": "https://api.github.com/repos/your-username/your-repository/issues/2/comments", - "events_url": "https://api.github.com/repos/your-username/your-repository/issues/2/events", - "html_url": "https://github.com/your-username/your-repository/pull/2", - "id": 690459508, - "node_id": "MDExOlB1bGxSZXF1ZXN0NDc3MzQ0OTcy", - "number": 2, - "title": "Create test_file", - "user": { - "login": "your-username", - "id": 1538000, - "node_id": "MDQ6VXNlcjE1MzgwMDA=", - "avatar_url": "https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/your-username", - "html_url": "https://github.com/your-username", - "followers_url": "https://api.github.com/users/your-username/followers", - "following_url": "https://api.github.com/users/your-username/following{/other_user}", - "gists_url": "https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url": "https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/your-username/subscriptions", - "organizations_url": "https://api.github.com/users/your-username/orgs", - "repos_url": "https://api.github.com/users/your-username/repos", - "events_url": "https://api.github.com/users/your-username/events{/privacy}", - "received_events_url": "https://api.github.com/users/your-username/received_events", - "type": "User", - "site_admin": false - }, - "labels": [ - { - "id": 2316374125, - "node_id": "MDU6TGFiZWwyMzE2Mzc0MTI1", - "description": "Something isn't working", - "url": "https://api.github.com/repos/your-username/your-repository/labels/bug", - "name": "bug", - "color": "d73a4a", - "default": true - } - ], - "state": "open", - "locked": false, - "assignee": null, - "assignees": [], - "milestone": null, - "comments": 7, - "created_at": "2020-09-01T21:23:45Z", - "updated_at": "2020-09-23T14:17:23Z", - "closed_at": null, - "body": "" - }, - "comment": { - "url": "https://api.github.com/repos/your-username/your-repository/issues/comments/697427391", - "html_url": "https://github.com/your-username/your-repository/pull/2#issuecomment-697427391", - "issue_url": "https://api.github.com/repos/your-username/your-repository/issues/2", - "id": 697427391, - "node_id": "MDEyOklzc3VlQ29tbWVudDY5NzQyNzM5MQ==", - "user": { - "login": "your-username", - "id": 1538000, - "node_id": "MDQ6VXNlcjE1MzgwMDA=", - "avatar_url": "https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/your-username", - "html_url": "https://github.com/your-username", - "followers_url": "https://api.github.com/users/your-username/followers", - "following_url": "https://api.github.com/users/your-username/following{/other_user}", - "gists_url": "https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url": "https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/your-username/subscriptions", - "organizations_url": "https://api.github.com/users/your-username/orgs", - "repos_url": "https://api.github.com/users/your-username/repos", - "events_url": "https://api.github.com/users/your-username/events{/privacy}", - "received_events_url": "https://api.github.com/users/your-username/received_events", - "type": "User", - "site_admin": false - }, - "created_at": "2020-09-23T14:17:23Z", - "updated_at": "2020-09-23T14:17:23Z", - "body": "test", - "author_association": "OWNER" - }, - "repository": { - "id": 292004268, - "node_id": "MDEwOlJlcG9zaXRvcnkyOTIwMDQyNjg=", - "name": "kogito-sw-demo", - "full_name": "your-username/your-repository", - "owner": { - "login": "your-username", - "id": 1538000, - "node_id": "MDQ6VXNlcjE1MzgwMDA=", - "avatar_url": "https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/your-username", - "html_url": "https://github.com/your-username", - "followers_url": "https://api.github.com/users/your-username/followers", - "following_url": "https://api.github.com/users/your-username/following{/other_user}", - "gists_url": "https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url": "https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/your-username/subscriptions", - "organizations_url": "https://api.github.com/users/your-username/orgs", - "repos_url": "https://api.github.com/users/your-username/repos", - "events_url": "https://api.github.com/users/your-username/events{/privacy}", - "received_events_url": "https://api.github.com/users/your-username/received_events", - "type": "User", - "site_admin": false - }, - "private": false, - "html_url": "https://github.com/your-username/your-repository", - "description": "Kogito Serverless Workflow Demo App", - "fork": false, - "url": "https://api.github.com/repos/your-username/your-repository", - "forks_url": "https://api.github.com/repos/your-username/your-repository/forks", - "keys_url": "https://api.github.com/repos/your-username/your-repository/keys{/key_id}", - "collaborators_url": "https://api.github.com/repos/your-username/your-repository/collaborators{/collaborator}", - "teams_url": "https://api.github.com/repos/your-username/your-repository/teams", - "hooks_url": "https://api.github.com/repos/your-username/your-repository/hooks", - "issue_events_url": "https://api.github.com/repos/your-username/your-repository/issues/events{/number}", - "events_url": "https://api.github.com/repos/your-username/your-repository/events", - "assignees_url": "https://api.github.com/repos/your-username/your-repository/assignees{/user}", - "branches_url": "https://api.github.com/repos/your-username/your-repository/branches{/branch}", - "tags_url": "https://api.github.com/repos/your-username/your-repository/tags", - "blobs_url": "https://api.github.com/repos/your-username/your-repository/git/blobs{/sha}", - "git_tags_url": "https://api.github.com/repos/your-username/your-repository/git/tags{/sha}", - "git_refs_url": "https://api.github.com/repos/your-username/your-repository/git/refs{/sha}", - "trees_url": "https://api.github.com/repos/your-username/your-repository/git/trees{/sha}", - "statuses_url": "https://api.github.com/repos/your-username/your-repository/statuses/{sha}", - "languages_url": "https://api.github.com/repos/your-username/your-repository/languages", - "stargazers_url": "https://api.github.com/repos/your-username/your-repository/stargazers", - "contributors_url": "https://api.github.com/repos/your-username/your-repository/contributors", - "subscribers_url": "https://api.github.com/repos/your-username/your-repository/subscribers", - "subscription_url": "https://api.github.com/repos/your-username/your-repository/subscription", - "commits_url": "https://api.github.com/repos/your-username/your-repository/commits{/sha}", - "git_commits_url": "https://api.github.com/repos/your-username/your-repository/git/commits{/sha}", - "comments_url": "https://api.github.com/repos/your-username/your-repository/comments{/number}", - "issue_comment_url": "https://api.github.com/repos/your-username/your-repository/issues/comments{/number}", - "contents_url": "https://api.github.com/repos/your-username/your-repository/contents/{+path}", - "compare_url": "https://api.github.com/repos/your-username/your-repository/compare/{base}...{head}", - "merges_url": "https://api.github.com/repos/your-username/your-repository/merges", - "archive_url": "https://api.github.com/repos/your-username/your-repository/{archive_format}{/ref}", - "downloads_url": "https://api.github.com/repos/your-username/your-repository/downloads", - "issues_url": "https://api.github.com/repos/your-username/your-repository/issues{/number}", - "pulls_url": "https://api.github.com/repos/your-username/your-repository/pulls{/number}", - "milestones_url": "https://api.github.com/repos/your-username/your-repository/milestones{/number}", - "notifications_url": "https://api.github.com/repos/your-username/your-repository/notifications{?since,all,participating}", - "labels_url": "https://api.github.com/repos/your-username/your-repository/labels{/name}", - "releases_url": "https://api.github.com/repos/your-username/your-repository/releases{/id}", - "created_at": "2020-09-01T13:23:59Z", - "updated_at": "2020-09-01T13:24:04Z", - "pushed_at": "2020-09-01T21:23:46Z", - "git_url": "git://github.com/your-username/your-repository.git", - "ssh_url": "git@github.com:your-username/your-repository.git", - "clone_url": "https://github.com/your-username/your-repository.git", - "svn_url": "https://github.com/your-username/your-repository", - "homepage": null, - "size": 5, - "stargazers_count": 0, - "watchers_count": 0, - "language": null, - "has_issues": true, - "has_downloads": true, - "has_wiki": true, - "has_pages": false, - "forks_count": 0, - "mirror_url": null, - "open_issues_count": 2, - "forks": 0, - "open_issues": 2, - "watchers": 0, - "default_branch": "main" - }, - "sender": { - "login": "your-username", - "id": 1538000, - "node_id": "MDQ6VXNlcjE1MzgwMDA=", - "avatar_url": "https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/your-username", - "html_url": "https://github.com/your-username", - "followers_url": "https://api.github.com/users/your-username/followers", - "following_url": "https://api.github.com/users/your-username/following{/other_user}", - "gists_url": "https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url": "https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/your-username/subscriptions", - "organizations_url": "https://api.github.com/users/your-username/orgs", - "repos_url": "https://api.github.com/users/your-username/repos", - "events_url": "https://api.github.com/users/your-username/events{/privacy}", - "received_events_url": "https://api.github.com/users/your-username/received_events", - "type": "User", - "site_admin": false - } - } -} \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/ce_pr_edited.json b/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/ce_pr_edited.json deleted file mode 100644 index 66bb9b10a9..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/pr-checker-workflow/src/test/resources/mock/ce_pr_edited.json +++ /dev/null @@ -1,495 +0,0 @@ -{ - "specversion":"1.0", - "type":"dev.knative.source.github.pull_request", - "source":"https://github.com/your-username/your-repository", - "subject":"2", - "id":"3f816880-fda8-11ea-8222-0e145a5edeb5", - "time":"2020-09-23T14:23:01.764756807Z", - "datacontenttype":"application/json", - "data":{ - "action":"edited", - "number":2, - "pull_request":{ - "url":"https://api.github.com/repos/your-username/your-repository/pulls/2", - "id":477344972, - "node_id":"MDExOlB1bGxSZXF1ZXN0NDc3MzQ0OTcy", - "html_url":"https://github.com/your-username/your-repository/pull/2", - "diff_url":"https://github.com/your-username/your-repository/pull/2.diff", - "patch_url":"https://github.com/your-username/your-repository/pull/2.patch", - "issue_url":"https://api.github.com/repos/your-username/your-repository/issues/2", - "number":2, - "state":"open", - "locked":false, - "title":"Create test_file", - "user":{ - "login":"your-username", - "id":1538000, - "node_id":"MDQ6VXNlcjE1MzgwMDA=", - "avatar_url":"https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id":"", - "url":"https://api.github.com/users/your-username", - "html_url":"https://github.com/your-username", - "followers_url":"https://api.github.com/users/your-username/followers", - "following_url":"https://api.github.com/users/your-username/following{/other_user}", - "gists_url":"https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url":"https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url":"https://api.github.com/users/your-username/subscriptions", - "organizations_url":"https://api.github.com/users/your-username/orgs", - "repos_url":"https://api.github.com/users/your-username/repos", - "events_url":"https://api.github.com/users/your-username/events{/privacy}", - "received_events_url":"https://api.github.com/users/your-username/received_events", - "type":"User", - "site_admin":false - }, - "body":"Let's provide a description to this PR and wait.", - "created_at":"2020-09-01T21:23:45Z", - "updated_at":"2020-09-23T14:22:45Z", - "closed_at":null, - "merged_at":null, - "merge_commit_sha":"f1d69e7cf4ffd1876ca3f4b75ca2b910fa3aa4f3", - "assignee":null, - "assignees":[ - - ], - "milestone":null, - "commits_url":"https://api.github.com/repos/your-username/your-repository/pulls/2/commits", - "review_comments_url":"https://api.github.com/repos/your-username/your-repository/pulls/2/comments", - "review_comment_url":"https://api.github.com/repos/your-username/your-repository/pulls/comments{/number}", - "comments_url":"https://api.github.com/repos/your-username/your-repository/issues/2/comments", - "statuses_url":"https://api.github.com/repos/your-username/your-repository/statuses/8f8bf633cd4eb16300129f979c5dcbd45f1536b0", - "requested_reviewers":[ - { - "login":"Kaitou786", - "id":36669272, - "node_id":"MDQ6VXNlcjM2NjY5Mjcy", - "avatar_url":"https://avatars0.githubusercontent.com/u/36669272?v=4", - "gravatar_id":"", - "url":"https://api.github.com/users/Kaitou786", - "html_url":"https://github.com/Kaitou786", - "followers_url":"https://api.github.com/users/Kaitou786/followers", - "following_url":"https://api.github.com/users/Kaitou786/following{/other_user}", - "gists_url":"https://api.github.com/users/Kaitou786/gists{/gist_id}", - "starred_url":"https://api.github.com/users/Kaitou786/starred{/owner}{/repo}", - "subscriptions_url":"https://api.github.com/users/Kaitou786/subscriptions", - "organizations_url":"https://api.github.com/users/Kaitou786/orgs", - "repos_url":"https://api.github.com/users/Kaitou786/repos", - "events_url":"https://api.github.com/users/Kaitou786/events{/privacy}", - "received_events_url":"https://api.github.com/users/Kaitou786/received_events", - "type":"User", - "site_admin":false - } - ], - "labels":[ - { - "id":2316374125, - "node_id":"MDU6TGFiZWwyMzE2Mzc0MTI1", - "description":"Something isn't working", - "url":"https://api.github.com/repos/your-username/your-repository/labels/bug", - "name":"bug", - "color":"d73a4a", - "default":true - } - ], - "head":{ - "label":"your-username:your-username-patch-1", - "ref":"your-username-patch-1", - "sha":"8f8bf633cd4eb16300129f979c5dcbd45f1536b0", - "user":{ - "login":"your-username", - "id":1538000, - "node_id":"MDQ6VXNlcjE1MzgwMDA=", - "avatar_url":"https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id":"", - "url":"https://api.github.com/users/your-username", - "html_url":"https://github.com/your-username", - "followers_url":"https://api.github.com/users/your-username/followers", - "following_url":"https://api.github.com/users/your-username/following{/other_user}", - "gists_url":"https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url":"https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url":"https://api.github.com/users/your-username/subscriptions", - "organizations_url":"https://api.github.com/users/your-username/orgs", - "repos_url":"https://api.github.com/users/your-username/repos", - "events_url":"https://api.github.com/users/your-username/events{/privacy}", - "received_events_url":"https://api.github.com/users/your-username/received_events", - "type":"User", - "site_admin":false - }, - "repo":{ - "id":292004268, - "node_id":"MDEwOlJlcG9zaXRvcnkyOTIwMDQyNjg=", - "name":"kogito-sw-demo", - "full_name":"your-username/your-repository", - "owner":{ - "login":"your-username", - "id":1538000, - "node_id":"MDQ6VXNlcjE1MzgwMDA=", - "avatar_url":"https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id":"", - "url":"https://api.github.com/users/your-username", - "html_url":"https://github.com/your-username", - "followers_url":"https://api.github.com/users/your-username/followers", - "following_url":"https://api.github.com/users/your-username/following{/other_user}", - "gists_url":"https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url":"https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url":"https://api.github.com/users/your-username/subscriptions", - "organizations_url":"https://api.github.com/users/your-username/orgs", - "repos_url":"https://api.github.com/users/your-username/repos", - "events_url":"https://api.github.com/users/your-username/events{/privacy}", - "received_events_url":"https://api.github.com/users/your-username/received_events", - "type":"User", - "site_admin":false - }, - "private":false, - "html_url":"https://github.com/your-username/your-repository", - "description":"Kogito Serverless Workflow Demo App", - "fork":false, - "url":"https://api.github.com/repos/your-username/your-repository", - "forks_url":"https://api.github.com/repos/your-username/your-repository/forks", - "keys_url":"https://api.github.com/repos/your-username/your-repository/keys{/key_id}", - "collaborators_url":"https://api.github.com/repos/your-username/your-repository/collaborators{/collaborator}", - "teams_url":"https://api.github.com/repos/your-username/your-repository/teams", - "hooks_url":"https://api.github.com/repos/your-username/your-repository/hooks", - "issue_events_url":"https://api.github.com/repos/your-username/your-repository/issues/events{/number}", - "events_url":"https://api.github.com/repos/your-username/your-repository/events", - "assignees_url":"https://api.github.com/repos/your-username/your-repository/assignees{/user}", - "branches_url":"https://api.github.com/repos/your-username/your-repository/branches{/branch}", - "tags_url":"https://api.github.com/repos/your-username/your-repository/tags", - "blobs_url":"https://api.github.com/repos/your-username/your-repository/git/blobs{/sha}", - "git_tags_url":"https://api.github.com/repos/your-username/your-repository/git/tags{/sha}", - "git_refs_url":"https://api.github.com/repos/your-username/your-repository/git/refs{/sha}", - "trees_url":"https://api.github.com/repos/your-username/your-repository/git/trees{/sha}", - "statuses_url":"https://api.github.com/repos/your-username/your-repository/statuses/{sha}", - "languages_url":"https://api.github.com/repos/your-username/your-repository/languages", - "stargazers_url":"https://api.github.com/repos/your-username/your-repository/stargazers", - "contributors_url":"https://api.github.com/repos/your-username/your-repository/contributors", - "subscribers_url":"https://api.github.com/repos/your-username/your-repository/subscribers", - "subscription_url":"https://api.github.com/repos/your-username/your-repository/subscription", - "commits_url":"https://api.github.com/repos/your-username/your-repository/commits{/sha}", - "git_commits_url":"https://api.github.com/repos/your-username/your-repository/git/commits{/sha}", - "comments_url":"https://api.github.com/repos/your-username/your-repository/comments{/number}", - "issue_comment_url":"https://api.github.com/repos/your-username/your-repository/issues/comments{/number}", - "contents_url":"https://api.github.com/repos/your-username/your-repository/contents/{+path}", - "compare_url":"https://api.github.com/repos/your-username/your-repository/compare/{base}...{head}", - "merges_url":"https://api.github.com/repos/your-username/your-repository/merges", - "archive_url":"https://api.github.com/repos/your-username/your-repository/{archive_format}{/ref}", - "downloads_url":"https://api.github.com/repos/your-username/your-repository/downloads", - "issues_url":"https://api.github.com/repos/your-username/your-repository/issues{/number}", - "pulls_url":"https://api.github.com/repos/your-username/your-repository/pulls{/number}", - "milestones_url":"https://api.github.com/repos/your-username/your-repository/milestones{/number}", - "notifications_url":"https://api.github.com/repos/your-username/your-repository/notifications{?since,all,participating}", - "labels_url":"https://api.github.com/repos/your-username/your-repository/labels{/name}", - "releases_url":"https://api.github.com/repos/your-username/your-repository/releases{/id}", - "created_at":"2020-09-01T13:23:59Z", - "updated_at":"2020-09-01T13:24:04Z", - "pushed_at":"2020-09-01T21:23:46Z", - "git_url":"git://github.com/your-username/your-repository.git", - "ssh_url":"git@github.com:your-username/your-repository.git", - "clone_url":"https://github.com/your-username/your-repository.git", - "svn_url":"https://github.com/your-username/your-repository", - "homepage":null, - "size":5, - "stargazers_count":0, - "watchers_count":0, - "language":null, - "has_issues":true, - "has_downloads":true, - "has_wiki":true, - "has_pages":false, - "forks_count":0, - "mirror_url":null, - "open_issues_count":2, - "forks":0, - "open_issues":2, - "watchers":0, - "default_branch":"main" - } - }, - "base":{ - "label":"your-username:main", - "ref":"main", - "sha":"5921558af53606e943823839220a887b66fc2baa", - "user":{ - "login":"your-username", - "id":1538000, - "node_id":"MDQ6VXNlcjE1MzgwMDA=", - "avatar_url":"https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id":"", - "url":"https://api.github.com/users/your-username", - "html_url":"https://github.com/your-username", - "followers_url":"https://api.github.com/users/your-username/followers", - "following_url":"https://api.github.com/users/your-username/following{/other_user}", - "gists_url":"https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url":"https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url":"https://api.github.com/users/your-username/subscriptions", - "organizations_url":"https://api.github.com/users/your-username/orgs", - "repos_url":"https://api.github.com/users/your-username/repos", - "events_url":"https://api.github.com/users/your-username/events{/privacy}", - "received_events_url":"https://api.github.com/users/your-username/received_events", - "type":"User", - "site_admin":false - }, - "repo":{ - "id":292004268, - "node_id":"MDEwOlJlcG9zaXRvcnkyOTIwMDQyNjg=", - "name":"kogito-sw-demo", - "full_name":"your-username/your-repository", - "owner":{ - "login":"your-username", - "id":1538000, - "node_id":"MDQ6VXNlcjE1MzgwMDA=", - "avatar_url":"https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id":"", - "url":"https://api.github.com/users/your-username", - "html_url":"https://github.com/your-username", - "followers_url":"https://api.github.com/users/your-username/followers", - "following_url":"https://api.github.com/users/your-username/following{/other_user}", - "gists_url":"https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url":"https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url":"https://api.github.com/users/your-username/subscriptions", - "organizations_url":"https://api.github.com/users/your-username/orgs", - "repos_url":"https://api.github.com/users/your-username/repos", - "events_url":"https://api.github.com/users/your-username/events{/privacy}", - "received_events_url":"https://api.github.com/users/your-username/received_events", - "type":"User", - "site_admin":false - }, - "private":false, - "html_url":"https://github.com/your-username/your-repository", - "description":"Kogito Serverless Workflow Demo App", - "fork":false, - "url":"https://api.github.com/repos/your-username/your-repository", - "forks_url":"https://api.github.com/repos/your-username/your-repository/forks", - "keys_url":"https://api.github.com/repos/your-username/your-repository/keys{/key_id}", - "collaborators_url":"https://api.github.com/repos/your-username/your-repository/collaborators{/collaborator}", - "teams_url":"https://api.github.com/repos/your-username/your-repository/teams", - "hooks_url":"https://api.github.com/repos/your-username/your-repository/hooks", - "issue_events_url":"https://api.github.com/repos/your-username/your-repository/issues/events{/number}", - "events_url":"https://api.github.com/repos/your-username/your-repository/events", - "assignees_url":"https://api.github.com/repos/your-username/your-repository/assignees{/user}", - "branches_url":"https://api.github.com/repos/your-username/your-repository/branches{/branch}", - "tags_url":"https://api.github.com/repos/your-username/your-repository/tags", - "blobs_url":"https://api.github.com/repos/your-username/your-repository/git/blobs{/sha}", - "git_tags_url":"https://api.github.com/repos/your-username/your-repository/git/tags{/sha}", - "git_refs_url":"https://api.github.com/repos/your-username/your-repository/git/refs{/sha}", - "trees_url":"https://api.github.com/repos/your-username/your-repository/git/trees{/sha}", - "statuses_url":"https://api.github.com/repos/your-username/your-repository/statuses/{sha}", - "languages_url":"https://api.github.com/repos/your-username/your-repository/languages", - "stargazers_url":"https://api.github.com/repos/your-username/your-repository/stargazers", - "contributors_url":"https://api.github.com/repos/your-username/your-repository/contributors", - "subscribers_url":"https://api.github.com/repos/your-username/your-repository/subscribers", - "subscription_url":"https://api.github.com/repos/your-username/your-repository/subscription", - "commits_url":"https://api.github.com/repos/your-username/your-repository/commits{/sha}", - "git_commits_url":"https://api.github.com/repos/your-username/your-repository/git/commits{/sha}", - "comments_url":"https://api.github.com/repos/your-username/your-repository/comments{/number}", - "issue_comment_url":"https://api.github.com/repos/your-username/your-repository/issues/comments{/number}", - "contents_url":"https://api.github.com/repos/your-username/your-repository/contents/{+path}", - "compare_url":"https://api.github.com/repos/your-username/your-repository/compare/{base}...{head}", - "merges_url":"https://api.github.com/repos/your-username/your-repository/merges", - "archive_url":"https://api.github.com/repos/your-username/your-repository/{archive_format}{/ref}", - "downloads_url":"https://api.github.com/repos/your-username/your-repository/downloads", - "issues_url":"https://api.github.com/repos/your-username/your-repository/issues{/number}", - "pulls_url":"https://api.github.com/repos/your-username/your-repository/pulls{/number}", - "milestones_url":"https://api.github.com/repos/your-username/your-repository/milestones{/number}", - "notifications_url":"https://api.github.com/repos/your-username/your-repository/notifications{?since,all,participating}", - "labels_url":"https://api.github.com/repos/your-username/your-repository/labels{/name}", - "releases_url":"https://api.github.com/repos/your-username/your-repository/releases{/id}", - "created_at":"2020-09-01T13:23:59Z", - "updated_at":"2020-09-01T13:24:04Z", - "pushed_at":"2020-09-01T21:23:46Z", - "git_url":"git://github.com/your-username/your-repository.git", - "ssh_url":"git@github.com:your-username/your-repository.git", - "clone_url":"https://github.com/your-username/your-repository.git", - "svn_url":"https://github.com/your-username/your-repository", - "homepage":null, - "size":5, - "stargazers_count":0, - "watchers_count":0, - "language":null, - "has_issues":true, - "has_downloads":true, - "has_wiki":true, - "has_pages":false, - "forks_count":0, - "mirror_url":null, - "open_issues_count":2, - "forks":0, - "open_issues":2, - "watchers":0, - "default_branch":"main" - } - }, - "_links":{ - "self":{ - "href":"https://api.github.com/repos/your-username/your-repository/pulls/2" - }, - "html":{ - "href":"https://github.com/your-username/your-repository/pull/2" - }, - "issue":{ - "href":"https://api.github.com/repos/your-username/your-repository/issues/2" - }, - "comments":{ - "href":"https://api.github.com/repos/your-username/your-repository/issues/2/comments" - }, - "review_comments":{ - "href":"https://api.github.com/repos/your-username/your-repository/pulls/2/comments" - }, - "review_comment":{ - "href":"https://api.github.com/repos/your-username/your-repository/pulls/comments{/number}" - }, - "commits":{ - "href":"https://api.github.com/repos/your-username/your-repository/pulls/2/commits" - }, - "statuses":{ - "href":"https://api.github.com/repos/your-username/your-repository/statuses/8f8bf633cd4eb16300129f979c5dcbd45f1536b0" - } - }, - "merged":false, - "mergeable":true, - "mergeable_state":"clean", - "merged_by":null, - "comments":7, - "review_comments":0, - "commits":1, - "additions":1, - "deletions":0, - "changed_files":1 - }, - "label":{ - "id":0, - "node_id":"", - "description":"", - "url":"", - "name":"", - "color":"", - "default":false - }, - "repository":{ - "id":292004268, - "node_id":"MDEwOlJlcG9zaXRvcnkyOTIwMDQyNjg=", - "name":"kogito-sw-demo", - "full_name":"your-username/your-repository", - "owner":{ - "login":"your-username", - "node_id":"MDQ6VXNlcjE1MzgwMDA=", - "id":1538000, - "avatar_url":"https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id":"", - "url":"https://api.github.com/users/your-username", - "html_url":"https://github.com/your-username", - "followers_url":"https://api.github.com/users/your-username/followers", - "following_url":"https://api.github.com/users/your-username/following{/other_user}", - "gists_url":"https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url":"https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url":"https://api.github.com/users/your-username/subscriptions", - "organizations_url":"https://api.github.com/users/your-username/orgs", - "repos_url":"https://api.github.com/users/your-username/repos", - "events_url":"https://api.github.com/users/your-username/events{/privacy}", - "received_events_url":"https://api.github.com/users/your-username/received_events", - "type":"User", - "site_admin":false - }, - "private":false, - "html_url":"https://github.com/your-username/your-repository", - "description":"Kogito Serverless Workflow Demo App", - "fork":false, - "url":"https://api.github.com/repos/your-username/your-repository", - "forks_url":"https://api.github.com/repos/your-username/your-repository/forks", - "keys_url":"https://api.github.com/repos/your-username/your-repository/keys{/key_id}", - "collaborators_url":"https://api.github.com/repos/your-username/your-repository/collaborators{/collaborator}", - "teams_url":"https://api.github.com/repos/your-username/your-repository/teams", - "hooks_url":"https://api.github.com/repos/your-username/your-repository/hooks", - "issue_events_url":"https://api.github.com/repos/your-username/your-repository/issues/events{/number}", - "events_url":"https://api.github.com/repos/your-username/your-repository/events", - "assignees_url":"https://api.github.com/repos/your-username/your-repository/assignees{/user}", - "branches_url":"https://api.github.com/repos/your-username/your-repository/branches{/branch}", - "tags_url":"https://api.github.com/repos/your-username/your-repository/tags", - "blobs_url":"https://api.github.com/repos/your-username/your-repository/git/blobs{/sha}", - "git_tags_url":"https://api.github.com/repos/your-username/your-repository/git/tags{/sha}", - "git_refs_url":"https://api.github.com/repos/your-username/your-repository/git/refs{/sha}", - "trees_url":"https://api.github.com/repos/your-username/your-repository/git/trees{/sha}", - "statuses_url":"https://api.github.com/repos/your-username/your-repository/statuses/{sha}", - "languages_url":"https://api.github.com/repos/your-username/your-repository/languages", - "stargazers_url":"https://api.github.com/repos/your-username/your-repository/stargazers", - "contributors_url":"https://api.github.com/repos/your-username/your-repository/contributors", - "subscribers_url":"https://api.github.com/repos/your-username/your-repository/subscribers", - "subscription_url":"https://api.github.com/repos/your-username/your-repository/subscription", - "commits_url":"https://api.github.com/repos/your-username/your-repository/commits{/sha}", - "git_commits_url":"https://api.github.com/repos/your-username/your-repository/git/commits{/sha}", - "comments_url":"https://api.github.com/repos/your-username/your-repository/comments{/number}", - "issue_comment_url":"https://api.github.com/repos/your-username/your-repository/issues/comments{/number}", - "contents_url":"https://api.github.com/repos/your-username/your-repository/contents/{+path}", - "compare_url":"https://api.github.com/repos/your-username/your-repository/compare/{base}...{head}", - "merges_url":"https://api.github.com/repos/your-username/your-repository/merges", - "archive_url":"https://api.github.com/repos/your-username/your-repository/{archive_format}{/ref}", - "downloads_url":"https://api.github.com/repos/your-username/your-repository/downloads", - "issues_url":"https://api.github.com/repos/your-username/your-repository/issues{/number}", - "pulls_url":"https://api.github.com/repos/your-username/your-repository/pulls{/number}", - "milestones_url":"https://api.github.com/repos/your-username/your-repository/milestones{/number}", - "notifications_url":"https://api.github.com/repos/your-username/your-repository/notifications{?since,all,participating}", - "labels_url":"https://api.github.com/repos/your-username/your-repository/labels{/name}", - "releases_url":"https://api.github.com/repos/your-username/your-repository/releases{/id}", - "created_at":"2020-09-01T13:23:59Z", - "updated_at":"2020-09-01T13:24:04Z", - "pushed_at":"2020-09-01T21:23:46Z", - "git_url":"git://github.com/your-username/your-repository.git", - "ssh_url":"git@github.com:your-username/your-repository.git", - "clone_url":"https://github.com/your-username/your-repository.git", - "svn_url":"https://github.com/your-username/your-repository", - "homepage":null, - "size":5, - "stargazers_count":0, - "watchers_count":0, - "language":null, - "has_issues":true, - "has_downloads":true, - "has_wiki":true, - "has_pages":false, - "forks_count":0, - "mirror_url":null, - "open_issues_count":2, - "forks":0, - "open_issues":2, - "watchers":0, - "default_branch":"main" - }, - "sender":{ - "login":"your-username", - "id":1538000, - "node_id":"MDQ6VXNlcjE1MzgwMDA=", - "avatar_url":"https://avatars3.githubusercontent.com/u/1538000?v=4", - "gravatar_id":"", - "url":"https://api.github.com/users/your-username", - "html_url":"https://github.com/your-username", - "followers_url":"https://api.github.com/users/your-username/followers", - "following_url":"https://api.github.com/users/your-username/following{/other_user}", - "gists_url":"https://api.github.com/users/your-username/gists{/gist_id}", - "starred_url":"https://api.github.com/users/your-username/starred{/owner}{/repo}", - "subscriptions_url":"https://api.github.com/users/your-username/subscriptions", - "organizations_url":"https://api.github.com/users/your-username/orgs", - "repos_url":"https://api.github.com/users/your-username/repos", - "events_url":"https://api.github.com/users/your-username/events{/privacy}", - "received_events_url":"https://api.github.com/users/your-username/received_events", - "type":"User", - "site_admin":false - }, - "assignee":null, - "requested_reviewer":null, - "requested_team":{ - "name":"", - "id":0, - "node_id":"", - "slug":"", - "description":"", - "privacy":"", - "url":"", - "html_url":"", - "members_url":"", - "repositories_url":"", - "permission":"" - }, - "installation":{ - "id":0 - } - } -} \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/scripts/add-route-to-hosts.sh b/serverless-workflow-examples/serverless-workflow-github-showcase/scripts/add-route-to-hosts.sh deleted file mode 100755 index 1ae6861d70..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/scripts/add-route-to-hosts.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash -# -# 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. -# - -# see: https://knative.dev/docs/serving/using-a-custom-domain/#local-dns-setup - -ROUTE_NAME=$1 -if [ -z "${ROUTE_NAME}" ]; then - echo "---> Please inform the route name. You can get it by running 'kubectl get route ROUTE -n NAMESPACE'" - exit -fi - -GATEWAY_IP=$(kubectl get svc istio-ingressgateway --namespace istio-system --output jsonpath="{.status.loadBalancer.ingress[*]['ip']}") -if [ -z "${GATEWAY_IP}" ]; then - echo "---> Failed to obtain Gateway IP. Have you run 'minikube tunnel' on a separate terminal?" - exit -fi - -echo "---> Trying to connect to ${GATEWAY_IP}" - -if ! curl -m 3 -vv "${GATEWAY_IP}"; then - echo "---> Failed to reach Istio Ingress endpoint. Have you run 'minikube tunnel' on a separate terminal?" - exit -fi - -DOMAIN_NAME=$(kubectl get route "${ROUTE_NAME}" --output jsonpath="{.status.url}" | cut -d'/' -f 3) -if [ -z "${DOMAIN_NAME}" ]; then - echo "---> Route ${ROUTE_NAME} not valid. You can get it by running 'kubectl get route ROUTE -n NAMESPACE'" - exit -fi - -echo "---> Add the record of Gateway IP and Route domain name into file '/etc/hosts'" -echo -e "${GATEWAY_IP}\t${DOMAIN_NAME}" | sudo tee -a /etc/hosts diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/scripts/cleanup-hosts-file.sh b/serverless-workflow-examples/serverless-workflow-github-showcase/scripts/cleanup-hosts-file.sh deleted file mode 100755 index c30b70e4e0..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/scripts/cleanup-hosts-file.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -# -# 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. -# - -sudo sed -i '/pr-checker-workflow/d' /etc/hosts -sudo sed -i '/github-event-listener/d' /etc/hosts -sudo sed -i '/github-service/d' /etc/hosts -sudo sed -i '/notification-service/d' /etc/hosts \ No newline at end of file diff --git a/serverless-workflow-examples/serverless-workflow-github-showcase/scripts/common.sh b/serverless-workflow-examples/serverless-workflow-github-showcase/scripts/common.sh deleted file mode 100755 index 1a70747b13..0000000000 --- a/serverless-workflow-examples/serverless-workflow-github-showcase/scripts/common.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash -# -# 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. -# - -BUILDER=podman - -function check_binaries() { - local return_code=0 - - if ! command -v kubectl &>/dev/null; then - echo "---> kubectl not found, please install it to run this script" - return_code=1 - fi - - if ! command -v podman &>/dev/null; then - echo "---> podman not found, setting default builder to docker" - BUILDER=docker - if ! command -v docker &>/dev/null; then - echo "---> docker not found, please install it to run this script" && return_code=1 - fi - fi - - return ${return_code} -} - -function build_push_image() { - image_ns=$1 - image_name=$2 - # defining image tag - image_tag="quay.io/${image_ns}/${image_name}:latest" - - echo "---> Building and pushing image using tag ${image_tag}" - # build image - if [ "${BUILDER}" == "docker" ]; then - docker build --tag "${image_tag}" . - docker push "${image_tag}" - else - podman build --tag "${image_tag}" . - podman push "${image_tag}" - fi -} diff --git a/serverless-workflow-examples/serverless-workflow-loanbroker-showcase/kubernetes/jobs-service-postgresql.yml b/serverless-workflow-examples/serverless-workflow-loanbroker-showcase/kubernetes/jobs-service-postgresql.yml index 4e2a172afd..d70469d8a9 100644 --- a/serverless-workflow-examples/serverless-workflow-loanbroker-showcase/kubernetes/jobs-service-postgresql.yml +++ b/serverless-workflow-examples/serverless-workflow-loanbroker-showcase/kubernetes/jobs-service-postgresql.yml @@ -77,7 +77,7 @@ spec: spec: containers: - name: jobs-service-postgresql - image: quay.io/kiegroup/kogito-jobs-service-postgresql-nightly:latest + image: docker.io/apache/incubator-kie-kogito-jobs-service-postgresql:main imagePullPolicy: Always ports: - containerPort: 8080 diff --git a/serverless-workflow-examples/serverless-workflow-newsletter-subscription/kubernetes/data-index-services.yml b/serverless-workflow-examples/serverless-workflow-newsletter-subscription/kubernetes/data-index-services.yml index 8f739b156b..48ac42d182 100644 --- a/serverless-workflow-examples/serverless-workflow-newsletter-subscription/kubernetes/data-index-services.yml +++ b/serverless-workflow-examples/serverless-workflow-newsletter-subscription/kubernetes/data-index-services.yml @@ -55,7 +55,7 @@ spec: spec: containers: - name: data-index-service-postgresql - image: quay.io/kiegroup/kogito-data-index-postgresql-nightly:latest + image: docker.io/apache/incubator-kie-kogito-data-index-postgresql:main imagePullPolicy: Always ports: - containerPort: 8080 diff --git a/serverless-workflow-examples/serverless-workflow-newsletter-subscription/kubernetes/supporting-services.yml b/serverless-workflow-examples/serverless-workflow-newsletter-subscription/kubernetes/supporting-services.yml index c55cee2ad5..89f0bbe1d7 100644 --- a/serverless-workflow-examples/serverless-workflow-newsletter-subscription/kubernetes/supporting-services.yml +++ b/serverless-workflow-examples/serverless-workflow-newsletter-subscription/kubernetes/supporting-services.yml @@ -162,7 +162,7 @@ spec: spec: containers: - name: jobs-service-postgresql - image: quay.io/kiegroup/kogito-jobs-service-postgresql-nightly:latest + image: docker.io/apache/incubator-kie-kogito-jobs-service-postgresql:main imagePullPolicy: Always ports: - containerPort: 8080 diff --git a/serverless-workflow-examples/serverless-workflow-timeouts-showcase-extended/kubernetes/data-index-service-postgresql.yml b/serverless-workflow-examples/serverless-workflow-timeouts-showcase-extended/kubernetes/data-index-service-postgresql.yml index 5318bf829b..1b5719ac12 100644 --- a/serverless-workflow-examples/serverless-workflow-timeouts-showcase-extended/kubernetes/data-index-service-postgresql.yml +++ b/serverless-workflow-examples/serverless-workflow-timeouts-showcase-extended/kubernetes/data-index-service-postgresql.yml @@ -55,7 +55,7 @@ spec: spec: containers: - name: data-index-service-postgresql - image: quay.io/kiegroup/kogito-data-index-postgresql-nightly:latest + image: docker.io/apache/incubator-kie-kogito-data-index-postgresql:main imagePullPolicy: Always ports: - containerPort: 8080 diff --git a/serverless-workflow-examples/serverless-workflow-timeouts-showcase-extended/kubernetes/jobs-service-postgresql.yml b/serverless-workflow-examples/serverless-workflow-timeouts-showcase-extended/kubernetes/jobs-service-postgresql.yml index 937c6d29e4..9c6e7a5d03 100644 --- a/serverless-workflow-examples/serverless-workflow-timeouts-showcase-extended/kubernetes/jobs-service-postgresql.yml +++ b/serverless-workflow-examples/serverless-workflow-timeouts-showcase-extended/kubernetes/jobs-service-postgresql.yml @@ -81,7 +81,7 @@ spec: spec: containers: - name: jobs-service-postgresql - image: quay.io/kiegroup/kogito-jobs-service-postgresql-nightly:latest + image: docker.io/apache/incubator-kie-kogito-jobs-service-postgresql:main imagePullPolicy: Always ports: - containerPort: 8080