From 7ac26050478729cebebe9ea44448c031d19ec55c Mon Sep 17 00:00:00 2001 From: Carles Arnal Date: Wed, 18 Oct 2023 13:42:00 +0200 Subject: [PATCH] Refactor tests registry 2 (#3801) * Automated update to next Snapshot Version: 2.4.4-SNAPSHOT * Update to version 2.5 * build(deps): bump test-containers.version from 1.18.1 to 1.18.2 (#3401) Bumps `test-containers.version` from 1.18.1 to 1.18.2. Updates `redpanda` from 1.18.1 to 1.18.2 - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.18.1...1.18.2) Updates `testcontainers` from 1.18.1 to 1.18.2 - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.18.1...1.18.2) Updates `postgresql` from 1.18.1 to 1.18.2 - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.18.1...1.18.2) Updates `selenium` from 1.18.1 to 1.18.2 - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.18.1...1.18.2) --- updated-dependencies: - dependency-name: org.testcontainers:redpanda dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.testcontainers:testcontainers dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.testcontainers:postgresql dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.testcontainers:selenium dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump truth-proto-extension from 1.1.3 to 1.1.4 (#3403) Bumps truth-proto-extension from 1.1.3 to 1.1.4. --- updated-dependencies: - dependency-name: com.google.truth.extensions:truth-proto-extension dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump jackson-datatype-json-org from 2.15.1 to 2.15.2 (#3402) Bumps [jackson-datatype-json-org](https://github.com/FasterXML/jackson-datatypes-misc) from 2.15.1 to 2.15.2. - [Commits](https://github.com/FasterXML/jackson-datatypes-misc/compare/jackson-datatypes-misc-parent-2.15.1...jackson-datatypes-misc-parent-2.15.2) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-json-org dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs: generating client sdk for openapi artifacts (#3404) * docs: generating client sdk for openapi artifacts * docs: add link to ms kiota quickstarts * build(deps): bump test-containers.version from 1.18.2 to 1.18.3 (#3406) Bumps `test-containers.version` from 1.18.2 to 1.18.3. Updates `redpanda` from 1.18.2 to 1.18.3 - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.18.2...1.18.3) Updates `testcontainers` from 1.18.2 to 1.18.3 - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.18.2...1.18.3) Updates `postgresql` from 1.18.2 to 1.18.3 - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.18.2...1.18.3) Updates `selenium` from 1.18.2 to 1.18.3 - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.18.2...1.18.3) --- updated-dependencies: - dependency-name: org.testcontainers:redpanda dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.testcontainers:testcontainers dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.testcontainers:postgresql dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.testcontainers:selenium dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump scala-library from 2.13.10 to 2.13.11 (#3408) Bumps [scala-library](https://github.com/scala/scala) from 2.13.10 to 2.13.11. - [Release notes](https://github.com/scala/scala/releases) - [Commits](https://github.com/scala/scala/compare/v2.13.10...v2.13.11) --- updated-dependencies: - dependency-name: org.scala-lang:scala-library dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump java-generator-maven-plugin from 6.6.2 to 6.7.0 (#3407) Bumps java-generator-maven-plugin from 6.6.2 to 6.7.0. --- updated-dependencies: - dependency-name: io.fabric8:java-generator-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump fabric8.version from 6.6.2 to 6.7.0 (#3405) Bumps `fabric8.version` from 6.6.2 to 6.7.0. Updates `openshift-client` from 6.6.2 to 6.7.0 - [Release notes](https://github.com/fabric8io/kubernetes-client/releases) - [Changelog](https://github.com/fabric8io/kubernetes-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/fabric8io/kubernetes-client/compare/v6.6.2...v6.7.0) Updates `java-generator-maven-plugin` from 6.6.2 to 6.7.0 Updates `kubernetes-client-bom` from 6.6.2 to 6.7.0 - [Release notes](https://github.com/fabric8io/kubernetes-client/releases) - [Changelog](https://github.com/fabric8io/kubernetes-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/fabric8io/kubernetes-client/compare/v6.6.2...v6.7.0) Updates `generator-annotations` from 6.6.2 to 6.7.0 - [Release notes](https://github.com/fabric8io/kubernetes-client/releases) - [Changelog](https://github.com/fabric8io/kubernetes-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/fabric8io/kubernetes-client/compare/v6.6.2...v6.7.0) --- updated-dependencies: - dependency-name: io.fabric8:openshift-client dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: io.fabric8:java-generator-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.fabric8:kubernetes-client-bom dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.fabric8:generator-annotations dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): update rhtap references (#3411) Co-authored-by: red-hat-trusted-app-pipeline <123456+red-hat-trusted-app-pipeline[bot]@users.noreply.github.com> * Enable verify workflow for additional branches * build(deps): bump fabric8.version from 6.7.0 to 6.7.1 (#3416) Bumps `fabric8.version` from 6.7.0 to 6.7.1. Updates `openshift-client` from 6.7.0 to 6.7.1 - [Release notes](https://github.com/fabric8io/kubernetes-client/releases) - [Changelog](https://github.com/fabric8io/kubernetes-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/fabric8io/kubernetes-client/compare/v6.7.0...v6.7.1) Updates `java-generator-maven-plugin` from 6.7.0 to 6.7.1 Updates `kubernetes-client-bom` from 6.7.0 to 6.7.1 - [Release notes](https://github.com/fabric8io/kubernetes-client/releases) - [Changelog](https://github.com/fabric8io/kubernetes-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/fabric8io/kubernetes-client/compare/v6.7.0...v6.7.1) Updates `generator-annotations` from 6.7.0 to 6.7.1 - [Release notes](https://github.com/fabric8io/kubernetes-client/releases) - [Changelog](https://github.com/fabric8io/kubernetes-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/fabric8io/kubernetes-client/compare/v6.7.0...v6.7.1) --- updated-dependencies: - dependency-name: io.fabric8:openshift-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: io.fabric8:java-generator-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.fabric8:kubernetes-client-bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.fabric8:generator-annotations dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump maven-surefire-plugin from 3.1.0 to 3.1.2 (#3417) Bumps [maven-surefire-plugin](https://github.com/apache/maven-surefire) from 3.1.0 to 3.1.2. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.1.0...surefire-3.1.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump java-generator-maven-plugin from 6.7.0 to 6.7.1 (#3419) Bumps java-generator-maven-plugin from 6.7.0 to 6.7.1. --- updated-dependencies: - dependency-name: io.fabric8:java-generator-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Added configuration of the date-time format for the REST API (#3413) * Enable verify workflow for additional branches * Added configuration of the date-time format for the REST API * Made the legacy date format the default and added startup message * Add message to date-format startup when overriding the default. * Automatically updated the core v2 API OpenAPI definition. * build(deps): bump proto-google-common-protos from 2.19.1 to 2.20.0 (#3420) Bumps [proto-google-common-protos](https://github.com/googleapis/sdk-platform-java) from 2.19.1 to 2.20.0. - [Release notes](https://github.com/googleapis/sdk-platform-java/releases) - [Changelog](https://github.com/googleapis/sdk-platform-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/sdk-platform-java/commits/v2.20.0) --- updated-dependencies: - dependency-name: com.google.api.grpc:proto-google-common-protos dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump maven-failsafe-plugin from 3.1.0 to 3.1.2 (#3418) Bumps [maven-failsafe-plugin](https://github.com/apache/maven-surefire) from 3.1.0 to 3.1.2. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.1.0...surefire-3.1.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs: v2.4 UI updates for view-only artifact references, delete artifact version setting (#3412) * build(deps): bump api from 0.35.0 to 0.35.1 (#3422) Bumps [api](https://github.com/strimzi/strimzi-kafka-operator) from 0.35.0 to 0.35.1. - [Release notes](https://github.com/strimzi/strimzi-kafka-operator/releases) - [Changelog](https://github.com/strimzi/strimzi-kafka-operator/blob/main/CHANGELOG.md) - [Commits](https://github.com/strimzi/strimzi-kafka-operator/compare/0.35.0...0.35.1) --- updated-dependencies: - dependency-name: io.strimzi:api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump guava from 32.0.0-jre to 32.0.1-jre (#3424) Bumps [guava](https://github.com/google/guava) from 32.0.0-jre to 32.0.1-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) --- updated-dependencies: - dependency-name: com.google.guava:guava dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump graphql-java from 20.3 to 20.4 (#3421) Bumps [graphql-java](https://github.com/graphql-java/graphql-java) from 20.3 to 20.4. - [Release notes](https://github.com/graphql-java/graphql-java/releases) - [Commits](https://github.com/graphql-java/graphql-java/compare/v20.3...v20.4) --- updated-dependencies: - dependency-name: com.graphql-java:graphql-java dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add content hash and canonical hash upgrader (#3423) * Add content hash and canonical hash upgrader * Update database version * Add integration test for content hash upgrade * Fix kafkasql upgrade test * Fix common sql statements * Update compose to use ports instead of host (#3426) * build(deps): bump json-schema-validator from 1.0.83 to 1.0.84 (#3427) Bumps [json-schema-validator](https://github.com/networknt/json-schema-validator) from 1.0.83 to 1.0.84. - [Release notes](https://github.com/networknt/json-schema-validator/releases) - [Changelog](https://github.com/networknt/json-schema-validator/blob/master/CHANGELOG.md) - [Commits](https://github.com/networknt/json-schema-validator/compare/1.0.83...1.0.84) --- updated-dependencies: - dependency-name: com.networknt:json-schema-validator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump logback-classic from 1.4.7 to 1.4.8 (#3430) Bumps [logback-classic](https://github.com/qos-ch/logback) from 1.4.7 to 1.4.8. - [Commits](https://github.com/qos-ch/logback/compare/v_1.4.7...v_1.4.8) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump icu4j from 73.1 to 73.2 (#3432) Bumps [icu4j](https://github.com/unicode-org/icu) from 73.1 to 73.2. - [Release notes](https://github.com/unicode-org/icu/releases) - [Commits](https://github.com/unicode-org/icu/commits) --- updated-dependencies: - dependency-name: com.ibm.icu:icu4j dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump org.eclipse.jgit (#3431) Bumps org.eclipse.jgit from 6.5.0.202303070854-r to 6.6.0.202305301015-r. --- updated-dependencies: - dependency-name: org.eclipse.jgit:org.eclipse.jgit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): update rhtap references (#3429) Co-authored-by: red-hat-trusted-app-pipeline <123456+red-hat-trusted-app-pipeline[bot]@users.noreply.github.com> * build(deps): bump java-generator-maven-plugin from 6.7.1 to 6.7.2 (#3436) Bumps java-generator-maven-plugin from 6.7.1 to 6.7.2. --- updated-dependencies: - dependency-name: io.fabric8:java-generator-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): update rhtap references (#3435) Co-authored-by: red-hat-trusted-app-pipeline <123456+red-hat-trusted-app-pipeline[bot]@users.noreply.github.com> * build(deps): bump fabric8.version from 6.7.1 to 6.7.2 (#3443) Bumps `fabric8.version` from 6.7.1 to 6.7.2. Updates `openshift-client` from 6.7.1 to 6.7.2 - [Release notes](https://github.com/fabric8io/kubernetes-client/releases) - [Changelog](https://github.com/fabric8io/kubernetes-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/fabric8io/kubernetes-client/compare/v6.7.1...v6.7.2) Updates `java-generator-maven-plugin` from 6.7.1 to 6.7.2 Updates `kubernetes-client-bom` from 6.7.1 to 6.7.2 - [Release notes](https://github.com/fabric8io/kubernetes-client/releases) - [Changelog](https://github.com/fabric8io/kubernetes-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/fabric8io/kubernetes-client/compare/v6.7.1...v6.7.2) Updates `generator-annotations` from 6.7.1 to 6.7.2 - [Release notes](https://github.com/fabric8io/kubernetes-client/releases) - [Changelog](https://github.com/fabric8io/kubernetes-client/blob/master/CHANGELOG.md) - [Commits](https://github.com/fabric8io/kubernetes-client/compare/v6.7.1...v6.7.2) --- updated-dependencies: - dependency-name: io.fabric8:openshift-client dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: io.fabric8:java-generator-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.fabric8:kubernetes-client-bom dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.fabric8:generator-annotations dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump truth-proto-extension from 1.1.4 to 1.1.5 (#3442) Bumps truth-proto-extension from 1.1.4 to 1.1.5. --- updated-dependencies: - dependency-name: com.google.truth.extensions:truth-proto-extension dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump httpcore5 from 5.2.1 to 5.2.2 (#3446) Bumps [httpcore5](https://github.com/apache/httpcomponents-core) from 5.2.1 to 5.2.2. - [Changelog](https://github.com/apache/httpcomponents-core/blob/master/RELEASE_NOTES.txt) - [Commits](https://github.com/apache/httpcomponents-core/compare/rel/v5.2.1...rel/v5.2.2) --- updated-dependencies: - dependency-name: org.apache.httpcomponents.core5:httpcore5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump maven-clean-plugin from 3.2.0 to 3.3.1 (#3447) Bumps [maven-clean-plugin](https://github.com/apache/maven-clean-plugin) from 3.2.0 to 3.3.1. - [Release notes](https://github.com/apache/maven-clean-plugin/releases) - [Commits](https://github.com/apache/maven-clean-plugin/compare/maven-clean-plugin-3.2.0...maven-clean-plugin-3.3.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-clean-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): update rhtap references (#3440) Co-authored-by: red-hat-trusted-app-pipeline <123456+red-hat-trusted-app-pipeline[bot]@users.noreply.github.com> * Proposed change to the Maven Plugin: Auto References (#3439) * Added a new ReferenceFinder component for artifacts (per-type). Added a proposed change to the maven plugin to auto detect refs * Added a ref finder for JSON Schema * build(deps): bump json from 20230227 to 20230618 (#3444) Bumps [json](https://github.com/douglascrockford/JSON-java) from 20230227 to 20230618. - [Release notes](https://github.com/douglascrockford/JSON-java/releases) - [Changelog](https://github.com/stleary/JSON-java/blob/master/docs/RELEASES.md) - [Commits](https://github.com/douglascrockford/JSON-java/commits) --- updated-dependencies: - dependency-name: org.json:json dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump json-schema-validator from 1.0.84 to 1.0.85 (#3455) Bumps [json-schema-validator](https://github.com/networknt/json-schema-validator) from 1.0.84 to 1.0.85. - [Release notes](https://github.com/networknt/json-schema-validator/releases) - [Changelog](https://github.com/networknt/json-schema-validator/blob/master/CHANGELOG.md) - [Commits](https://github.com/networknt/json-schema-validator/compare/1.0.84...1.0.85) --- updated-dependencies: - dependency-name: com.networknt:json-schema-validator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump proto-google-common-protos from 2.20.0 to 2.21.0 (#3456) Bumps [proto-google-common-protos](https://github.com/googleapis/sdk-platform-java) from 2.20.0 to 2.21.0. - [Release notes](https://github.com/googleapis/sdk-platform-java/releases) - [Changelog](https://github.com/googleapis/sdk-platform-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/sdk-platform-java/compare/v2.20.0...v2.21.0) --- updated-dependencies: - dependency-name: com.google.api.grpc:proto-google-common-protos dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix dynamic basic auth ui resolution (#3458) * chore(deps): update rhtap references (#3457) Co-authored-by: red-hat-trusted-app-pipeline <123456+red-hat-trusted-app-pipeline[bot]@users.noreply.github.com> * build(deps): bump commons-codec from 1.15 to 1.16.0 (#3453) Bumps [commons-codec](https://github.com/apache/commons-codec) from 1.15 to 1.16.0. - [Changelog](https://github.com/apache/commons-codec/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-codec/compare/rel/commons-codec-1.15...rel/commons-codec-1.16.0) --- updated-dependencies: - dependency-name: commons-codec:commons-codec dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * No longer need to override the data-models version (#3452) * Use the .zip file instead of the tar.gz file for the client-gen release (#3451) * Install "unzip" in the RHTAP builder image * chore(deps): update rhtap references (#3461) Co-authored-by: red-hat-trusted-app-pipeline <123456+red-hat-trusted-app-pipeline[bot]@users.noreply.github.com> * Removed unused tekton pipelines * build(deps): bump maven-artifact from 3.9.2 to 3.9.3 (#3460) Bumps [maven-artifact](https://github.com/apache/maven) from 3.9.2 to 3.9.3. - [Release notes](https://github.com/apache/maven/releases) - [Commits](https://github.com/apache/maven/compare/maven-3.9.2...maven-3.9.3) --- updated-dependencies: - dependency-name: org.apache.maven:maven-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Eric Wittmann * Native image fully statically linked (#3459) Co-authored-by: Eric Wittmann * Fix RHTAP repo (#3464) * Red Hat Trusted App Pipeline purge apicurio-registry-f36x (#3469) Co-authored-by: red-hat-trusted-app-pipeline * Red Hat Trusted App Pipeline update github-apicurio-registry (#3470) Co-authored-by: red-hat-trusted-app-pipeline * build(deps): bump keycloak-admin-client from 21.1.1 to 21.1.2 (#3468) Bumps keycloak-admin-client from 21.1.1 to 21.1.2. --- updated-dependencies: - dependency-name: org.keycloak:keycloak-admin-client dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update github-apicurio-registry-push.yaml * Update github-apicurio-registry-push.yaml * Update webpack.common.js * Update webpack.common.js * Update github-apicurio-registry-pull-request.yaml * Update webpack.common.js * Red Hat Trusted App Pipeline purge github-apicurio-registry (#3473) Co-authored-by: red-hat-trusted-app-pipeline * feat: Expose listArtifactTypes in the client library (#3477) * Update REST API to support different artifact reference strategies on GET (#3462) * Changing "derefence" support to support both deref and ref rewriting * Add tests for ref writing. Fix failing build. * Automatically updated the core v2 API OpenAPI definition. * build(deps): bump strimzi-test-container from 0.103.0 to 0.104.0 (#3479) Bumps [strimzi-test-container](https://github.com/strimzi/test-container) from 0.103.0 to 0.104.0. - [Release notes](https://github.com/strimzi/test-container/releases) - [Commits](https://github.com/strimzi/test-container/compare/0.103.0...0.104.0) --- updated-dependencies: - dependency-name: io.strimzi:strimzi-test-container dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump guava from 32.0.1-jre to 32.1.0-jre (#3478) Bumps [guava](https://github.com/google/guava) from 32.0.1-jre to 32.1.0-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) --- updated-dependencies: - dependency-name: com.google.guava:guava dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump guava from 32.1.0-jre to 32.1.1-jre (#3484) Bumps [guava](https://github.com/google/guava) from 32.1.0-jre to 32.1.1-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) --- updated-dependencies: - dependency-name: com.google.guava:guava dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump json-schema-validator from 1.0.85 to 1.0.86 (#3492) Bumps [json-schema-validator](https://github.com/networknt/json-schema-validator) from 1.0.85 to 1.0.86. - [Release notes](https://github.com/networknt/json-schema-validator/releases) - [Changelog](https://github.com/networknt/json-schema-validator/blob/master/CHANGELOG.md) - [Commits](https://github.com/networknt/json-schema-validator/compare/1.0.85...1.0.86) --- updated-dependencies: - dependency-name: com.networknt:json-schema-validator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump protobuf.version from 3.23.2 to 3.23.4 (#3494) Bumps `protobuf.version` from 3.23.2 to 3.23.4. Updates `protobuf-java` from 3.23.2 to 3.23.4 - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.23.2...v3.23.4) Updates `protobuf-java-util` from 3.23.2 to 3.23.4 --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.google.protobuf:protobuf-java-util dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Handle avro complex types in serdes (#3496) * build(deps): bump okio-fakefilesystem from 3.3.0 to 3.4.0 Bumps [okio-fakefilesystem](https://github.com/square/okio) from 3.3.0 to 3.4.0. - [Changelog](https://github.com/square/okio/blob/master/CHANGELOG.md) - [Commits](https://github.com/square/okio/compare/parent-3.3.0...parent-3.4.0) --- updated-dependencies: - dependency-name: com.squareup.okio:okio-fakefilesystem dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * build(deps): bump okio-jvm from 3.3.0 to 3.4.0 Bumps [okio-jvm](https://github.com/square/okio) from 3.3.0 to 3.4.0. - [Changelog](https://github.com/square/okio/blob/master/CHANGELOG.md) - [Commits](https://github.com/square/okio/compare/parent-3.3.0...parent-3.4.0) --- updated-dependencies: - dependency-name: com.squareup.okio:okio-jvm dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Support azure ad * docs: add section on HTTP basic client credentials token expiry * docs: clean up HTTP basic client credentials token expiry option * docs: add auto-detect and register using maven plugin, clean up * docs: minor clean up of artifact refs with maven plugin * build(deps): bump okio from 3.3.0 to 3.4.0 Bumps [okio](https://github.com/square/okio) from 3.3.0 to 3.4.0. - [Changelog](https://github.com/square/okio/blob/master/CHANGELOG.md) - [Commits](https://github.com/square/okio/compare/parent-3.3.0...parent-3.4.0) --- updated-dependencies: - dependency-name: com.squareup.okio:okio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * build(deps): bump proto-google-common-protos from 2.21.0 to 2.22.0 Bumps [proto-google-common-protos](https://github.com/googleapis/sdk-platform-java) from 2.21.0 to 2.22.0. - [Release notes](https://github.com/googleapis/sdk-platform-java/releases) - [Changelog](https://github.com/googleapis/sdk-platform-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/sdk-platform-java/compare/v2.21.0...v2.22.0) --- updated-dependencies: - dependency-name: com.google.api.grpc:proto-google-common-protos dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * build(deps): bump kafka-oauth-client from 0.12.0 to 0.13.0 Bumps [kafka-oauth-client](https://github.com/strimzi/strimzi-kafka-oauth) from 0.12.0 to 0.13.0. - [Release notes](https://github.com/strimzi/strimzi-kafka-oauth/releases) - [Changelog](https://github.com/strimzi/strimzi-kafka-oauth/blob/main/RELEASE_NOTES.md) - [Commits](https://github.com/strimzi/strimzi-kafka-oauth/compare/0.12.0...0.13.0) --- updated-dependencies: - dependency-name: io.strimzi:kafka-oauth-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * build(deps): bump keycloak-admin-client from 21.1.2 to 22.0.0 Bumps keycloak-admin-client from 21.1.2 to 22.0.0. --- updated-dependencies: - dependency-name: org.keycloak:keycloak-admin-client dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * build(deps): bump graphql-java from 20.4 to 21.0 Bumps [graphql-java](https://github.com/graphql-java/graphql-java) from 20.4 to 21.0. - [Release notes](https://github.com/graphql-java/graphql-java/releases) - [Commits](https://github.com/graphql-java/graphql-java/compare/v20.4...v21.0) --- updated-dependencies: - dependency-name: com.graphql-java:graphql-java dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * build(deps): bump kafka-schema-registry-client from 7.4.0 to 7.4.1 (#3510) Bumps [kafka-schema-registry-client](https://github.com/confluentinc/schema-registry) from 7.4.0 to 7.4.1. - [Commits](https://github.com/confluentinc/schema-registry/commits) --- updated-dependencies: - dependency-name: io.confluent:kafka-schema-registry-client dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump apicurio-common-rest-client.version (#3513) Bumps `apicurio-common-rest-client.version` from 0.1.17.Final to 0.1.18.Final. Updates `apicurio-common-rest-client-vertx` from 0.1.17.Final to 0.1.18.Final - [Release notes](https://github.com/apicurio/apicurio-common-rest-client/releases) - [Commits](https://github.com/apicurio/apicurio-common-rest-client/compare/0.1.17.Final...0.1.18.Final) Updates `apicurio-common-rest-client-jdk` from 0.1.17.Final to 0.1.18.Final - [Release notes](https://github.com/apicurio/apicurio-common-rest-client/releases) - [Commits](https://github.com/apicurio/apicurio-common-rest-client/compare/0.1.17.Final...0.1.18.Final) Updates `apicurio-common-rest-client-common` from 0.1.17.Final to 0.1.18.Final - [Release notes](https://github.com/apicurio/apicurio-common-rest-client/releases) - [Commits](https://github.com/apicurio/apicurio-common-rest-client/compare/0.1.17.Final...0.1.18.Final) --- updated-dependencies: - dependency-name: io.apicurio:apicurio-common-rest-client-vertx dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.apicurio:apicurio-common-rest-client-jdk dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: io.apicurio:apicurio-common-rest-client-common dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add header for group customization in the ccompat api * Fix kafkasql image building * build(deps): bump keycloak-admin-client from 22.0.0 to 22.0.1 (#3517) Bumps keycloak-admin-client from 22.0.0 to 22.0.1. --- updated-dependencies: - dependency-name: org.keycloak:keycloak-admin-client dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Upgraded Avro and fixed a test * Update AvroSerdeTest.java Removed a test that wasn't doing anything useful. * Add scope for basic auth * Correctly handle non snake-case query parameters in the Python sdk (#3466) * Reproduction of 3465 * fmt * finalize the fix with upstream bits * fmt * feat: support HTTPS passthrough ingress in the presence of redirects * Eagerly start and initialize EventsService before EventSourcedRegistryStorage (#3519) * Eagerly start and initialize EventsService before EventSourcedRegistryStorage * review * build(deps): bump com.google.api.grpc:proto-google-common-protos (#3522) Bumps [com.google.api.grpc:proto-google-common-protos](https://github.com/googleapis/sdk-platform-java) from 2.22.0 to 2.22.1. - [Release notes](https://github.com/googleapis/sdk-platform-java/releases) - [Changelog](https://github.com/googleapis/sdk-platform-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/sdk-platform-java/commits) --- updated-dependencies: - dependency-name: com.google.api.grpc:proto-google-common-protos dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump io.strimzi:api from 0.35.1 to 0.36.0 Bumps [io.strimzi:api](https://github.com/strimzi/strimzi-kafka-operator) from 0.35.1 to 0.36.0. - [Release notes](https://github.com/strimzi/strimzi-kafka-operator/releases) - [Changelog](https://github.com/strimzi/strimzi-kafka-operator/blob/main/CHANGELOG.md) - [Commits](https://github.com/strimzi/strimzi-kafka-operator/compare/0.35.1...0.36.0) --- updated-dependencies: - dependency-name: io.strimzi:api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * build(deps): bump junit.version from 5.9.3 to 5.10.0 Bumps `junit.version` from 5.9.3 to 5.10.0. Updates `org.junit.jupiter:junit-jupiter` from 5.9.3 to 5.10.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.9.3...r5.10.0) Updates `org.junit.jupiter:junit-jupiter-api` from 5.9.3 to 5.10.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.9.3...r5.10.0) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * build(deps): bump com.squareup.wire:wire-schema from 4.5.5 to 4.8.0 Bumps [com.squareup.wire:wire-schema](https://github.com/square/wire) from 4.5.5 to 4.8.0. - [Changelog](https://github.com/square/wire/blob/master/CHANGELOG.md) - [Commits](https://github.com/square/wire/compare/4.5.5...4.8.0) --- updated-dependencies: - dependency-name: com.squareup.wire:wire-schema dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * build(deps): bump io.fabric8:java-generator-maven-plugin Bumps io.fabric8:java-generator-maven-plugin from 6.7.2 to 6.8.0. --- updated-dependencies: - dependency-name: io.fabric8:java-generator-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * build(deps): bump word-wrap from 1.2.3 to 1.2.4 in /ui Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4. - [Release notes](https://github.com/jonschlinkert/word-wrap/releases) - [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4) --- updated-dependencies: - dependency-name: word-wrap dependency-type: indirect ... Signed-off-by: dependabot[bot] * Update kafka client libraries * Address snakeyaml critical cve * Initialize yaml constructor at runtime * Align jackson version with Quarkus * Revert "Align jackson version with Quarkus" This reverts commit 9db0b9019c86dced2277ae2897dc12a32c480e75. * Revert "Initialize yaml constructor at runtime" This reverts commit 193531a201b117379b3f4f2b4fc9d4d4d58664ae. * Revert "Address snakeyaml critical cve" This reverts commit 5684db92ed9ccf88cb5343e033ff58b92c3e28ae. * build(deps): bump com.googlecode.maven-download-plugin:download-maven-plugin (#3533) Bumps [com.googlecode.maven-download-plugin:download-maven-plugin](https://github.com/maven-download-plugin/maven-download-plugin) from 1.7.0 to 1.7.1. - [Release notes](https://github.com/maven-download-plugin/maven-download-plugin/releases) - [Commits](https://github.com/maven-download-plugin/maven-download-plugin/compare/1.7.0...1.7.1) --- updated-dependencies: - dependency-name: com.googlecode.maven-download-plugin:download-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Migrate first two tests to quarkus integration tests * Prepare infra management structure * Add kubernetes resources for the in memory variant * Add capability to run tests on a kubernetes cluster * Simplify kubernetes resources management * Use port forward for in memory deployment * Add default in memory profile for e2e testing * Use property for cluster tests * Fix port forwarding * Wait for pods to be ready * Add initial kafka and keycloak support * Add realm to e2e testing * Update keycloak and simplify registry in-memory deployment * Fix kafka deploymeny networking * Proper organization of resources * Add kafka testing support * Add local sql profile for system tests * Add postgresql resource and fix registry sql deployment * Add sql to deployment manager * Add support for running the testsuite locally and in a cluster * Add support for running authentication tests * Fix authorization resources * Add local kafka and wait for resources termination * Set registry replicas to 3 * Add converters integration tests * Add ui testing capabilities * Simplify kubernetes resource management and add all the apicurio smoke tests * Add confluent smoke and acceptance tests * Add all the serdes tests and improve tests structure * Make the ci workflows use the new system tests * Refactor ui tests and improve test execution form IDE * Prepare migration tests * Add log compaction test * Add kafka upgrade tests * Add sql upgrade tests * Remove some old integration test utils * Add minikube to integration tests and execute sql integration tests * Update minikube and kubernetes version * Add more tests to the ci workflow * Build image from pr and push to ttl * Add data migration tests * Add rate limiting tests * Add reaper tests and remove integration tests module * Remove integration tests module entirely * Add multitenant resources and infra management * Add remote migration tests preparation * Add remote multitenancy tests * Add migration sql tests to ci workflow * Add sql database migration tests to ci * Fix the kafka datbase upgrade tests * Refactor native image workflows to use the new integration tests approach * Add documentation on how to run the new integration tests * Use load balancer service for tests reliability * Use port forward for the UI tests * Add openshift profile for running the integration tests * Restore system tests for better traceability * Fix multitenancy integration tests to work locally on mac os * Switch to redpanda for speed * Align testcontainers version with the version used in Quarkus * Fix integration tests workflow * Upgrade deps * Fix ccompat tests --------- Signed-off-by: dependabot[bot] Co-authored-by: apicurio-ci Co-authored-by: Eric Wittmann Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Stephen McCarthy <29098561+smccarthy-ie@users.noreply.github.com> Co-authored-by: red-hat-trusted-app-pipeline[bot] <126015336+red-hat-trusted-app-pipeline[bot]@users.noreply.github.com> Co-authored-by: red-hat-trusted-app-pipeline <123456+red-hat-trusted-app-pipeline[bot]@users.noreply.github.com> Co-authored-by: Hugo Guerrero <1001939+hguerrero@users.noreply.github.com> Co-authored-by: Andrea Peruffo Co-authored-by: Stuart Douglas Co-authored-by: red-hat-trusted-app-pipeline Co-authored-by: Stephen McCarthy Co-authored-by: Jakub Senko --- .github/workflows/integration-tests.yaml | 161 +- .../workflows/kubernetes-tests-manual.yaml | 59 - .github/workflows/kubernetes-tests.yaml | 124 - .github/workflows/new-system-tests.yaml | 43 - .github/workflows/publish-debug-image.yaml | 41 - .github/workflows/release-images.yaml | 1 + .github/workflows/verify.yaml | 71 +- .../apicurio-registry-f36x-pull-request.yaml | 342 --- .tekton/apicurio-registry-f36x-push.yaml | 341 --- .../apicurio-registry-qnbk-pull-request.yaml | 342 --- .tekton/apicurio-registry-qnbk-push.yaml | 341 --- Dockerfile.jvm.staged | 3 + Makefile | 250 +- TESTING.md | 39 +- app/pom.xml | 7 +- app/src/main/resources/application.properties | 3 +- .../registry/events/KafkaEventsTest.java | 10 +- .../rest/v6/ConfluentCompatApiTest.java | 859 ------ .../rest/v7/ConfluentCompatApiTest.java | 295 -- .../noprofile/maven/RegistryMojoTestBase.java | 3 +- .../registry/rbac/AdminResourceTest.java | 2 +- .../registry/rbac/RegistryClientTest.java | 3 +- client/pom.xml | 2 +- .../registry/rest/client/AdminClient.java | 3 + .../rest/client/impl/AdminClientImpl.java | 5 + .../provider/AdminRequestsProvider.java | 10 + .../rest/client/request/provider/Routes.java | 2 + common/pom.xml | 8 +- distro/connect-converter/pom.xml | 2 +- distro/docker-compose/README.md | 2 - distro/docker-compose/pom.xml | 2 +- .../resources/docker-compose.apicurio.yml | 17 +- distro/docker/pom.xml | 2 +- .../src/main/docker/Dockerfile.native-scratch | 33 + distro/openshift-template/pom.xml | 2 +- distro/pom.xml | 2 +- .../ref-registry-security-configuration.adoc | 8 +- .../ROOT/partials/shared/attributes.adoc | 4 +- docs/pom.xml | 2 +- docs/rest-api/pom.xml | 2 +- .../integration-tests-common/pom.xml | 197 -- .../tests/common/ApicurioRegistryBaseIT.java | 39 - .../apicurio/tests/common/AuthServerInfo.java | 139 - .../io/apicurio/tests/common/KafkaFacade.java | 203 -- .../common/RegistryDeploymentManager.java | 113 - .../apicurio/tests/common/RegistryFacade.java | 1039 ------- .../tests/common/auth/CustomJWTAuth.java | 52 - .../tests/common/auth/JWKSMockServer.java | 155 - .../apicurio/tests/common/executor/Exec.java | 313 --- .../tests/common/executor/ExecResult.java | 45 - .../tests/common/kafka/EmbeddedKafka.java | 79 - .../kafka/TrustAllSslEngineFactory.java | 94 - .../tests/common/utils/RegistryUtils.java | 47 - .../src/main/resources/logback.xml | 15 - .../src/main/resources/test-realm.json | 2491 ----------------- integration-tests/pom.xml | 700 +++++ .../io/apicurio/deployment/Constants.java | 57 + .../deployment/InMemoryDeploymentManager.java | 39 + .../deployment/KafkaSqlDeploymentManager.java | 99 + .../deployment/KubernetesTestResources.java | 54 + .../deployment/PortForwardManager.java | 88 + .../deployment/RegistryDeploymentManager.java | 233 ++ .../deployment/SqlDeploymentManager.java | 127 + .../tests/ApicurioRegistryBaseIT.java | 735 +++++ .../io/apicurio/tests/ConfluentBaseIT.java | 27 +- .../io/apicurio/tests/auth/SimpleAuthIT.java | 75 +- .../tests/common/serdes/TestObject.java | 2 +- .../common/serdes/json/InvalidMessage.java | 0 .../tests/common/serdes/json/Msg.java | 0 .../common/serdes/json/ValidMessage.java | 0 .../tests/common/serdes/proto/MsgTypes.java | 204 +- .../tests/common/serdes/proto/TestCmmn.java | 154 +- .../tests/converters/RegistryConverterIT.java | 64 +- .../dbupgrade/KafkaSqlLogCompactionIT.java | 191 ++ .../dbupgrade/KafkaSqlStorageUpgradeIT.java | 167 ++ .../tests/dbupgrade/SqlStorageUpgradeIT.java | 273 ++ .../UpgradeTestsDataInitializer.java | 243 ++ .../tests/migration/DataMigrationIT.java | 98 + .../migration/DoNotPreserveIdsImportIT.java | 124 + .../GenerateCanonicalHashImportIT.java | 150 + .../MigrationTestsDataInitializer.java | 213 ++ .../multitenancy/MultitenancyLimitsIT.java} | 60 +- .../multitenancy/MultitenancySupport.java | 51 +- .../tests/multitenancy/TenantReaperIT.java | 60 +- .../tests/multitenancy/TenantUser.java | 2 +- .../tests/multitenancy/TenantUserClient.java | 2 +- .../serdes/RateLimitedRegistrySerdeIT.java | 215 +- .../io/apicurio/tests/protobuf/Header.java | 390 +-- .../tests/protobuf/HeaderOrBuilder.java | 14 +- .../io/apicurio/tests/protobuf/Point.java | 240 +- .../tests/protobuf/PointOrBuilder.java | 6 +- .../tests/protobuf/ProtobufTestMessage.java | 274 +- .../ProtobufTestMessageOrBuilder.java | 8 +- .../apicurio/tests/protobuf/Testmessage.java | 8 +- .../AvroGenericRecordSchemaFactory.java | 14 +- .../tests/serdes/apicurio/AvroSerdeIT.java | 60 +- .../serdes/apicurio/JsonSchemaMsgFactory.java | 13 +- .../serdes/apicurio/JsonSchemaSerdeIT.java | 37 +- .../serdes/apicurio/ProtobufSerdeIT.java | 36 +- .../apicurio/ProtobufTestMessageFactory.java | 12 +- .../apicurio/ProtobufUUIDTestMessage.java | 12 +- .../tests/serdes/apicurio/SerdesTester.java | 57 +- .../apicurio/SimpleSerdesTesterBuilder.java | 23 +- .../tests/serdes/apicurio/Tester.java | 2 +- .../WrongConfiguredConsumerTesterBuilder.java | 18 +- .../WrongConfiguredSerdesTesterBuilder.java | 22 +- .../confluent/BasicConfluentSerDesIT.java | 48 +- .../apicurio/AllArtifactTypesIT.java | 20 +- .../smokeTests/apicurio/ArtifactsIT.java | 48 +- .../tests/smokeTests/apicurio/LoadIT.java | 9 +- .../tests/smokeTests/apicurio/MetadataIT.java | 33 +- .../smokeTests/apicurio/RulesResourceIT.java | 45 +- .../confluent}/ConfluentConfigUtils.java | 19 +- .../confluent}/ConfluentSubjectsUtils.java | 16 +- .../confluent/MetadataConfluentIT.java | 27 +- .../confluent/RulesResourceConfluentIT.java | 7 +- .../confluent/SchemasConfluentIT.java | 34 +- .../apicurio/tests/ui/DeleteArtifactIT.java | 37 +- .../apicurio/tests/ui/RegistryUITester.java | 19 +- .../apicurio/tests/ui/UploadArtifactsIT.java | 37 +- .../tests/ui/pages/ArtifactDetailsPage.java | 9 +- .../tests/ui/pages/ArtifactsListPage.java | 15 +- .../io/apicurio/tests/ui/pages/BasePage.java | 3 +- .../tests/ui/pages/UploadArtifactDialog.java | 3 +- .../tests/ui}/selenium/SeleniumChrome.java | 8 +- .../ui}/selenium/SeleniumChromeExtension.java | 35 +- .../tests/ui}/selenium/SeleniumProvider.java | 8 +- .../selenium/resources/ArtifactListItem.java | 10 +- .../tests/ui}/selenium/resources/WebItem.java | 2 +- .../utils/AbstractTestDataInitializer.java | 67 + .../apicurio/tests/utils/ArtifactUtils.java | 12 +- .../utils/AvroGenericRecordSchemaFactory.java | 123 + .../apicurio/tests}/utils/BaseHttpUtils.java | 6 +- .../io/apicurio/tests/utils}/Constants.java | 9 +- .../tests/utils/CustomTestsUtils.java | 34 +- .../ExtensionContextParameterResolver.java | 4 +- .../io/apicurio/tests/utils/KafkaFacade.java | 112 + .../apicurio/tests/utils/LimitingProxy.java | 2 +- .../utils}/LoadBalanceRegistryClient.java | 219 +- .../tests/utils/RateLimitingProxy.java | 2 +- .../tests/utils/RegistryWaitUtils.java | 6 +- .../apicurio/tests/utils}/RestConstants.java | 2 +- .../tests/utils/RetryLimitingProxy.java | 6 +- .../utils/TenantManagerTestResource.java | 122 + .../apicurio/tests/utils}/TestSeparator.java | 8 +- ...it.platform.launcher.TestExecutionListener | 1 + .../asyncapi/2.0-streetlights_v1.json | 0 .../asyncapi/2.0-streetlights_v2.json | 0 .../artifactTypes/avro/multi-field_v1.json | 0 .../artifactTypes/avro/multi-field_v2.json | 0 .../artifactTypes/graphql/swars_v1.graphql | 0 .../artifactTypes/graphql/swars_v2.graphql | 0 .../artifactTypes/jsonSchema/person_v1.json | 0 .../artifactTypes/jsonSchema/person_v2.json | 0 .../artifactTypes/kafkaConnect/simple_v1.json | 0 .../artifactTypes/kafkaConnect/simple_v2.json | 0 .../openapi/2.0-petstore_v1.json | 0 .../openapi/2.0-petstore_v2.json | 0 .../openapi/3.0-petstore_v1.json | 0 .../openapi/3.0-petstore_v2.json | 0 .../artifactTypes/protobuf/tutorial_v1.proto | 0 .../artifactTypes/protobuf/tutorial_v2.proto | 0 .../test/resources/infra/auth/keycloak.yml | 2014 ++++++++----- .../test/resources/infra/e2e-namespace.yml | 6 + .../in-memory/registry-in-memory-secured.yml | 96 + .../infra/in-memory/registry-in-memory.yml | 74 + .../registry-multitenant-in-memory.yml | 84 + .../src/test/resources/infra/kafka/kafka.yml | 43 + .../infra/kafka/registry-kafka-old.yml | 76 + .../infra/kafka/registry-kafka-secured.yml | 98 + .../resources/infra/kafka/registry-kafka.yml | 76 + .../kafka/registry-multitenant-kafka.yml | 86 + .../infra/openshift/registry-route.yml | 15 + .../infra/openshift/tenant-manager-route.yml | 15 + .../test/resources/infra/sql/postgresql.yml | 55 + .../infra/sql/registry-multitenant-sql.yml | 85 + .../resources/infra/sql/registry-sql-old.yml | 92 + .../infra/sql/registry-sql-secured.yml | 102 + .../test/resources/infra/sql/registry-sql.yml | 80 + .../tenant-manager-database.yml | 55 + .../infra/tenant-manager/tenant-manager.yml | 86 + .../src/test/resources/serdes/person.proto | 0 .../test/resources/serdes/testmessage.proto | 0 integration-tests/testsuite/pom.xml | 405 --- .../io/apicurio/tests/ApicurioV2BaseIT.java | 225 -- .../tests/clustered/ClusteredRegistryIT.java | 242 -- .../dbupgrade/KafkaSqlLogCompactionIT.java | 153 - .../dbupgrade/KafkaSqlStorageUpgradeIT.java | 241 -- .../tests/dbupgrade/SqlStorageUpgradeIT.java | 379 --- .../tests/migration/DataMigrationIT.java | 322 --- .../tests/multitenancy/MultitenantAuthIT.java | 275 -- .../asyncapi/2.0-streetlights_v1.json | 297 -- .../asyncapi/2.0-streetlights_v2.json | 301 -- .../artifactTypes/avro/multi-field_v1.json | 52 - .../artifactTypes/avro/multi-field_v2.json | 57 - .../artifactTypes/graphql/swars_v1.graphql | 24 - .../artifactTypes/graphql/swars_v2.graphql | 25 - .../artifactTypes/jsonSchema/person_v1.json | 21 - .../artifactTypes/jsonSchema/person_v2.json | 26 - .../artifactTypes/kafkaConnect/simple_v1.json | 11 - .../artifactTypes/kafkaConnect/simple_v2.json | 16 - .../openapi/2.0-petstore_v1.json | 1043 ------- .../openapi/2.0-petstore_v2.json | 1046 ------- .../openapi/3.0-petstore_v1.json | 177 -- .../openapi/3.0-petstore_v2.json | 180 -- .../artifactTypes/protobuf/tutorial_v1.proto | 29 - .../artifactTypes/protobuf/tutorial_v2.proto | 29 - .../src/test/resources/privateKey.jwk | 11 - new-system-tests/README.md | 3 - new-system-tests/pom.xml | 167 -- new-system-tests/scripts/kind_config.yaml | 18 - new-system-tests/scripts/run.sh | 5 - new-system-tests/scripts/setup_cluster.sh | 161 -- .../registry/systemtests/Constants.java | 19 - .../systemtests/KafkasqlNoAuthKeycloak.java | 88 - .../systemtests/KafkasqlNoAuthNoIAM.java | 81 - .../registry/systemtests/SqlKeycloak.java | 76 - .../registry/systemtests/SqlNoIAM.java | 69 - .../registry/systemtests/TestBase.java | 16 - .../apicurio/registry/systemtests/Utils.java | 200 -- .../resources/apicurio/01_subscription.yaml | 9 - ...02_registry_kafkasql_no_auth_keycloak.yaml | 16 - .../02_registry_kafkasql_no_auth_no_iam.yaml | 9 - .../apicurio/02_registry_sql_keycloak.yaml | 20 - .../apicurio/02_registry_sql_no_iam.yaml | 13 - .../resources/common/00_operator_group.yaml | 4 - .../resources/kafkasql/01_subscription.yaml | 9 - .../test/resources/kafkasql/02_no_auth.yaml | 25 - .../test/resources/keycloak/00_service.yaml | 14 - .../resources/keycloak/02_deployment.yaml | 39 - .../src/test/resources/sql/00_service.yaml | 15 - .../src/test/resources/sql/01_deployment.yaml | 48 - pom.xml | 100 +- schema-resolver/pom.xml | 2 +- schema-util/asyncapi/pom.xml | 2 +- .../dereference/AsyncApiDereferencer.java | 23 + .../extract/AsyncApiContentExtractor.java | 24 + .../content/refs/AsyncApiReferenceFinder.java | 26 + schema-util/avro/pom.xml | 2 +- .../content/dereference/AvroDereferencer.java | 12 + .../content/refs/AvroReferenceFinder.java | 105 + schema-util/common/pom.xml | 2 +- .../dereference/ContentDereferencer.java | 10 + .../content/refs/ExternalReference.java | 158 ++ .../refs/JsonPointerExternalReference.java | 54 + .../content/refs/NoOpReferenceFinder.java | 39 + .../content/refs/ReferenceFinder.java | 34 + schema-util/graphql/pom.xml | 2 +- .../validity/GraphQLContentValidator.java | 1 + schema-util/json/pom.xml | 2 +- .../dereference/JsonSchemaDereferencer.java | 52 +- .../refs/JsonSchemaReferenceFinder.java | 80 + schema-util/kconnect/pom.xml | 2 +- schema-util/openapi/pom.xml | 2 +- ...ApicurioDataModelsContentDereferencer.java | 49 + .../dereference/OpenApiDereferencer.java | 13 +- .../dereference/ReferenceRewriter.java | 76 + ...> ApicurioDataModelsContentExtractor.java} | 2 +- .../extract/OpenApiContentExtractor.java | 18 +- .../AbstractDataModelsReferenceFinder.java | 98 + .../content/refs/OpenApiReferenceFinder.java | 26 + schema-util/protobuf/pom.xml | 2 +- .../dereference/ProtobufDereferencer.java | 10 + .../content/refs/ProtobufReferenceFinder.java | 57 + schema-util/util-provider/pom.xml | 2 +- .../provider/ArtifactTypeUtilProvider.java | 3 + .../AsyncApiArtifactTypeUtilProvider.java | 15 +- .../AvroArtifactTypeUtilProvider.java | 7 + .../GraphQLArtifactTypeUtilProvider.java | 10 + .../JsonArtifactTypeUtilProvider.java | 11 +- .../KConnectArtifactTypeUtilProvider.java | 10 + .../OpenApiArtifactTypeUtilProvider.java | 15 +- .../ProtobufArtifactTypeUtilProvider.java | 7 + .../WsdlArtifactTypeUtilProvider.java | 10 + .../provider/XmlArtifactTypeUtilProvider.java | 10 + .../provider/XsdArtifactTypeUtilProvider.java | 10 + .../AsyncApiContentDereferencerTest.java | 51 + .../JsonSchemaContentDereferencerTest.java | 51 + .../OpenApiContentDereferencerTest.java | 51 + .../refs/AsyncApiReferenceFinderTest.java | 47 + .../content/refs/AvroReferenceFinderTest.java | 47 + .../refs/JsonSchemaReferenceFinderTest.java | 45 + .../refs/OpenApiReferenceFinderTest.java | 47 + .../refs/ProtobufReferenceFinderTest.java | 48 + .../dereference/asyncapi-to-rewrite.json | 33 + .../dereference/json-schema-to-rewrite.json | 10 + .../dereference/openapi-to-rewrite.json | 159 ++ .../content/refs/asyncapi-with-refs.json | 33 + .../registry/content/refs/avro-with-refs.avsc | 23 + .../content/refs/json-schema-with-refs.json | 10 + .../content/refs/openapi-with-refs.json | 159 ++ .../content/refs/protobuf-with-refs.proto | 22 + schema-util/wsdl/pom.xml | 2 +- schema-util/xml/pom.xml | 2 +- schema-util/xsd/pom.xml | 2 +- serdes/avro-serde/pom.xml | 2 +- serdes/jsonschema-serde/pom.xml | 2 +- serdes/protobuf-serde/pom.xml | 2 +- serdes/serde-common/pom.xml | 2 +- storage/kafkasql/pom.xml | 51 +- .../src/main/resources/overlay.properties | 2 +- storage/mssql/pom.xml | 28 +- .../src/main/resources/overlay.properties | 2 +- storage/mysql/pom.xml | 25 +- storage/pom.xml | 6 +- storage/sql/pom.xml | 42 +- .../sql/src/main/resources/overlay.properties | 2 +- .../storage/util/SqlStorageTestResources.java | 1 + system-tests/pom.xml | 8 +- ui/package-lock.json | 12 +- ui/pom.xml | 2 +- utils/converter/pom.xml | 2 +- utils/exportConfluent/pom.xml | 2 +- utils/exportV1/pom.xml | 2 +- utils/importexport/pom.xml | 2 +- utils/kafka/pom.xml | 18 +- .../test/utils/KafkaTestContainerManager.java | 13 +- utils/maven-plugin/pom.xml | 12 +- .../registry/maven/ExistingReference.java | 90 + .../registry/maven/RegisterArtifact.java | 18 + .../registry/maven/RegisterRegistryMojo.java | 198 +- .../registry/maven/refs/IndexedResource.java | 122 + .../registry/maven/refs/ReferenceIndex.java | 170 ++ utils/protobuf-schema-utilities/pom.xml | 2 +- .../protobuf/schema/FileDescriptorUtils.java | 20 +- utils/tests/pom.xml | 10 +- .../registry/utils/tests/AuthTestProfile.java | 10 +- .../registry/utils/tests/JWKSMockServer.java | 4 +- .../tests/MultitenancyNoAuthTestProfile.java | 40 + .../PostgreSqlEmbeddedTestResource.java | 40 +- utils/tools/pom.xml | 2 +- 331 files changed, 11108 insertions(+), 17293 deletions(-) delete mode 100644 .github/workflows/kubernetes-tests-manual.yaml delete mode 100644 .github/workflows/kubernetes-tests.yaml delete mode 100644 .github/workflows/new-system-tests.yaml delete mode 100644 .github/workflows/publish-debug-image.yaml delete mode 100644 .tekton/apicurio-registry-f36x-pull-request.yaml delete mode 100644 .tekton/apicurio-registry-f36x-push.yaml delete mode 100644 .tekton/apicurio-registry-qnbk-pull-request.yaml delete mode 100644 .tekton/apicurio-registry-qnbk-push.yaml delete mode 100644 app/src/test/java/io/apicurio/registry/noprofile/ccompat/rest/v6/ConfluentCompatApiTest.java delete mode 100644 app/src/test/java/io/apicurio/registry/noprofile/ccompat/rest/v7/ConfluentCompatApiTest.java create mode 100644 distro/docker/src/main/docker/Dockerfile.native-scratch delete mode 100644 integration-tests/integration-tests-common/pom.xml delete mode 100644 integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/ApicurioRegistryBaseIT.java delete mode 100644 integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/AuthServerInfo.java delete mode 100644 integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/KafkaFacade.java delete mode 100644 integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryDeploymentManager.java delete mode 100644 integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryFacade.java delete mode 100644 integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/auth/CustomJWTAuth.java delete mode 100644 integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/auth/JWKSMockServer.java delete mode 100644 integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/executor/Exec.java delete mode 100644 integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/executor/ExecResult.java delete mode 100644 integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/kafka/EmbeddedKafka.java delete mode 100644 integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/kafka/TrustAllSslEngineFactory.java delete mode 100644 integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/RegistryUtils.java delete mode 100644 integration-tests/integration-tests-common/src/main/resources/logback.xml delete mode 100644 integration-tests/integration-tests-common/src/main/resources/test-realm.json create mode 100644 integration-tests/pom.xml create mode 100644 integration-tests/src/main/java/io/apicurio/deployment/Constants.java create mode 100644 integration-tests/src/test/java/io/apicurio/deployment/InMemoryDeploymentManager.java create mode 100644 integration-tests/src/test/java/io/apicurio/deployment/KafkaSqlDeploymentManager.java create mode 100644 integration-tests/src/test/java/io/apicurio/deployment/KubernetesTestResources.java create mode 100644 integration-tests/src/test/java/io/apicurio/deployment/PortForwardManager.java create mode 100644 integration-tests/src/test/java/io/apicurio/deployment/RegistryDeploymentManager.java create mode 100644 integration-tests/src/test/java/io/apicurio/deployment/SqlDeploymentManager.java create mode 100644 integration-tests/src/test/java/io/apicurio/tests/ApicurioRegistryBaseIT.java rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/ConfluentBaseIT.java (94%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/auth/SimpleAuthIT.java (78%) rename integration-tests/{integration-tests-common/src/main => src/test}/java/io/apicurio/tests/common/serdes/TestObject.java (98%) rename integration-tests/{integration-tests-common/src/main => src/test}/java/io/apicurio/tests/common/serdes/json/InvalidMessage.java (100%) rename integration-tests/{integration-tests-common/src/main => src/test}/java/io/apicurio/tests/common/serdes/json/Msg.java (100%) rename integration-tests/{integration-tests-common/src/main => src/test}/java/io/apicurio/tests/common/serdes/json/ValidMessage.java (100%) rename integration-tests/{integration-tests-common/src/main => src/test}/java/io/apicurio/tests/common/serdes/proto/MsgTypes.java (74%) rename integration-tests/{integration-tests-common/src/main => src/test}/java/io/apicurio/tests/common/serdes/proto/TestCmmn.java (83%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/converters/RegistryConverterIT.java (90%) create mode 100644 integration-tests/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlLogCompactionIT.java create mode 100644 integration-tests/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlStorageUpgradeIT.java create mode 100644 integration-tests/src/test/java/io/apicurio/tests/dbupgrade/SqlStorageUpgradeIT.java create mode 100644 integration-tests/src/test/java/io/apicurio/tests/dbupgrade/UpgradeTestsDataInitializer.java create mode 100644 integration-tests/src/test/java/io/apicurio/tests/migration/DataMigrationIT.java create mode 100644 integration-tests/src/test/java/io/apicurio/tests/migration/DoNotPreserveIdsImportIT.java create mode 100644 integration-tests/src/test/java/io/apicurio/tests/migration/GenerateCanonicalHashImportIT.java create mode 100644 integration-tests/src/test/java/io/apicurio/tests/migration/MigrationTestsDataInitializer.java rename integration-tests/{testsuite/src/test/java/io/apicurio/tests/multitenancy/MultitenantLimitsIT.java => src/test/java/io/apicurio/tests/multitenancy/MultitenancyLimitsIT.java} (82%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/multitenancy/MultitenancySupport.java (68%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/multitenancy/TenantReaperIT.java (77%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/multitenancy/TenantUser.java (97%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/multitenancy/TenantUserClient.java (97%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/multitenancy/serdes/RateLimitedRegistrySerdeIT.java (61%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/protobuf/Header.java (80%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/protobuf/HeaderOrBuilder.java (91%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/protobuf/Point.java (77%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/protobuf/PointOrBuilder.java (80%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessage.java (81%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessageOrBuilder.java (91%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/protobuf/Testmessage.java (91%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/apicurio/AvroGenericRecordSchemaFactory.java (99%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/apicurio/AvroSerdeIT.java (98%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaMsgFactory.java (98%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaSerdeIT.java (95%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufSerdeIT.java (98%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufTestMessageFactory.java (98%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufUUIDTestMessage.java (98%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/apicurio/SerdesTester.java (89%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/apicurio/SimpleSerdesTesterBuilder.java (94%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/apicurio/Tester.java (96%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredConsumerTesterBuilder.java (93%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredSerdesTesterBuilder.java (91%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/serdes/confluent/BasicConfluentSerDesIT.java (98%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/smokeTests/apicurio/AllArtifactTypesIT.java (95%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/smokeTests/apicurio/ArtifactsIT.java (94%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/smokeTests/apicurio/LoadIT.java (96%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/smokeTests/apicurio/MetadataIT.java (96%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/smokeTests/apicurio/RulesResourceIT.java (97%) rename integration-tests/{integration-tests-common/src/main/java/io/apicurio/tests/common/utils/subUtils => src/test/java/io/apicurio/tests/smokeTests/confluent}/ConfluentConfigUtils.java (75%) rename integration-tests/{integration-tests-common/src/main/java/io/apicurio/tests/common/utils/subUtils => src/test/java/io/apicurio/tests/smokeTests/confluent}/ConfluentSubjectsUtils.java (83%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/smokeTests/confluent/MetadataConfluentIT.java (95%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/smokeTests/confluent/RulesResourceConfluentIT.java (96%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/smokeTests/confluent/SchemasConfluentIT.java (96%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/ui/DeleteArtifactIT.java (94%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/ui/RegistryUITester.java (98%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/ui/UploadArtifactsIT.java (95%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/ui/pages/ArtifactDetailsPage.java (96%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/ui/pages/ArtifactsListPage.java (97%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/ui/pages/BasePage.java (95%) rename integration-tests/{testsuite => }/src/test/java/io/apicurio/tests/ui/pages/UploadArtifactDialog.java (98%) rename integration-tests/{testsuite/src/test/java/io/apicurio/tests => src/test/java/io/apicurio/tests/ui}/selenium/SeleniumChrome.java (93%) rename integration-tests/{testsuite/src/test/java/io/apicurio/tests => src/test/java/io/apicurio/tests/ui}/selenium/SeleniumChromeExtension.java (82%) rename integration-tests/{testsuite/src/test/java/io/apicurio/tests => src/test/java/io/apicurio/tests/ui}/selenium/SeleniumProvider.java (98%) rename integration-tests/{testsuite/src/test/java/io/apicurio/tests => src/test/java/io/apicurio/tests/ui}/selenium/resources/ArtifactListItem.java (96%) rename integration-tests/{testsuite/src/test/java/io/apicurio/tests => src/test/java/io/apicurio/tests/ui}/selenium/resources/WebItem.java (94%) create mode 100644 integration-tests/src/test/java/io/apicurio/tests/utils/AbstractTestDataInitializer.java rename integration-tests/{testsuite/src/main => src/test}/java/io/apicurio/tests/utils/ArtifactUtils.java (80%) create mode 100644 integration-tests/src/test/java/io/apicurio/tests/utils/AvroGenericRecordSchemaFactory.java rename integration-tests/{integration-tests-common/src/main/java/io/apicurio/tests/common => src/test/java/io/apicurio/tests}/utils/BaseHttpUtils.java (99%) rename integration-tests/{integration-tests-common/src/main/java/io/apicurio/tests/common => src/test/java/io/apicurio/tests/utils}/Constants.java (91%) rename integration-tests/{testsuite/src/main => src/test}/java/io/apicurio/tests/utils/CustomTestsUtils.java (73%) rename integration-tests/{integration-tests-common/src/main/java/io/apicurio/tests/common/interfaces => src/test/java/io/apicurio/tests/utils}/ExtensionContextParameterResolver.java (94%) create mode 100644 integration-tests/src/test/java/io/apicurio/tests/utils/KafkaFacade.java rename integration-tests/{testsuite/src/main => src/test}/java/io/apicurio/tests/utils/LimitingProxy.java (99%) rename integration-tests/{testsuite/src/main/java/io/apicurio/tests => src/test/java/io/apicurio/tests/utils}/LoadBalanceRegistryClient.java (64%) rename integration-tests/{testsuite/src/main => src/test}/java/io/apicurio/tests/utils/RateLimitingProxy.java (98%) rename integration-tests/{testsuite/src/main => src/test}/java/io/apicurio/tests/utils/RegistryWaitUtils.java (88%) rename integration-tests/{integration-tests-common/src/main/java/io/apicurio/tests/common/utils/subUtils => src/test/java/io/apicurio/tests/utils}/RestConstants.java (94%) rename integration-tests/{testsuite/src/main => src/test}/java/io/apicurio/tests/utils/RetryLimitingProxy.java (95%) create mode 100644 integration-tests/src/test/java/io/apicurio/tests/utils/TenantManagerTestResource.java rename integration-tests/{integration-tests-common/src/main/java/io/apicurio/tests/common/interfaces => src/test/java/io/apicurio/tests/utils}/TestSeparator.java (95%) create mode 100644 integration-tests/src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v1.json (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v2.json (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/avro/multi-field_v1.json (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/avro/multi-field_v2.json (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/graphql/swars_v1.graphql (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/graphql/swars_v2.graphql (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/jsonSchema/person_v1.json (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/jsonSchema/person_v2.json (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/kafkaConnect/simple_v1.json (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/kafkaConnect/simple_v2.json (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/openapi/2.0-petstore_v1.json (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/openapi/2.0-petstore_v2.json (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/openapi/3.0-petstore_v1.json (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/openapi/3.0-petstore_v2.json (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/protobuf/tutorial_v1.proto (100%) rename integration-tests/{integration-tests-common => }/src/test/resources/artifactTypes/protobuf/tutorial_v2.proto (100%) rename new-system-tests/src/test/resources/keycloak/01_realm.yaml => integration-tests/src/test/resources/infra/auth/keycloak.yml (67%) create mode 100644 integration-tests/src/test/resources/infra/e2e-namespace.yml create mode 100644 integration-tests/src/test/resources/infra/in-memory/registry-in-memory-secured.yml create mode 100644 integration-tests/src/test/resources/infra/in-memory/registry-in-memory.yml create mode 100644 integration-tests/src/test/resources/infra/in-memory/registry-multitenant-in-memory.yml create mode 100644 integration-tests/src/test/resources/infra/kafka/kafka.yml create mode 100644 integration-tests/src/test/resources/infra/kafka/registry-kafka-old.yml create mode 100644 integration-tests/src/test/resources/infra/kafka/registry-kafka-secured.yml create mode 100644 integration-tests/src/test/resources/infra/kafka/registry-kafka.yml create mode 100644 integration-tests/src/test/resources/infra/kafka/registry-multitenant-kafka.yml create mode 100644 integration-tests/src/test/resources/infra/openshift/registry-route.yml create mode 100644 integration-tests/src/test/resources/infra/openshift/tenant-manager-route.yml create mode 100644 integration-tests/src/test/resources/infra/sql/postgresql.yml create mode 100644 integration-tests/src/test/resources/infra/sql/registry-multitenant-sql.yml create mode 100644 integration-tests/src/test/resources/infra/sql/registry-sql-old.yml create mode 100644 integration-tests/src/test/resources/infra/sql/registry-sql-secured.yml create mode 100644 integration-tests/src/test/resources/infra/sql/registry-sql.yml create mode 100644 integration-tests/src/test/resources/infra/tenant-manager/tenant-manager-database.yml create mode 100644 integration-tests/src/test/resources/infra/tenant-manager/tenant-manager.yml rename integration-tests/{testsuite => }/src/test/resources/serdes/person.proto (100%) rename integration-tests/{testsuite => }/src/test/resources/serdes/testmessage.proto (100%) delete mode 100644 integration-tests/testsuite/pom.xml delete mode 100644 integration-tests/testsuite/src/test/java/io/apicurio/tests/ApicurioV2BaseIT.java delete mode 100644 integration-tests/testsuite/src/test/java/io/apicurio/tests/clustered/ClusteredRegistryIT.java delete mode 100644 integration-tests/testsuite/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlLogCompactionIT.java delete mode 100644 integration-tests/testsuite/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlStorageUpgradeIT.java delete mode 100644 integration-tests/testsuite/src/test/java/io/apicurio/tests/dbupgrade/SqlStorageUpgradeIT.java delete mode 100644 integration-tests/testsuite/src/test/java/io/apicurio/tests/migration/DataMigrationIT.java delete mode 100644 integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/MultitenantAuthIT.java delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v1.json delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v2.json delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/avro/multi-field_v1.json delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/avro/multi-field_v2.json delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/graphql/swars_v1.graphql delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/graphql/swars_v2.graphql delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/jsonSchema/person_v1.json delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/jsonSchema/person_v2.json delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/kafkaConnect/simple_v1.json delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/kafkaConnect/simple_v2.json delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/openapi/2.0-petstore_v1.json delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/openapi/2.0-petstore_v2.json delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/openapi/3.0-petstore_v1.json delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/openapi/3.0-petstore_v2.json delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/protobuf/tutorial_v1.proto delete mode 100644 integration-tests/testsuite/src/test/resources/artifactTypes/protobuf/tutorial_v2.proto delete mode 100644 integration-tests/testsuite/src/test/resources/privateKey.jwk delete mode 100644 new-system-tests/README.md delete mode 100644 new-system-tests/pom.xml delete mode 100644 new-system-tests/scripts/kind_config.yaml delete mode 100755 new-system-tests/scripts/run.sh delete mode 100755 new-system-tests/scripts/setup_cluster.sh delete mode 100644 new-system-tests/src/main/java/io/apicurio/registry/systemtests/Constants.java delete mode 100644 new-system-tests/src/test/java/io/apicurio/registry/systemtests/KafkasqlNoAuthKeycloak.java delete mode 100644 new-system-tests/src/test/java/io/apicurio/registry/systemtests/KafkasqlNoAuthNoIAM.java delete mode 100644 new-system-tests/src/test/java/io/apicurio/registry/systemtests/SqlKeycloak.java delete mode 100644 new-system-tests/src/test/java/io/apicurio/registry/systemtests/SqlNoIAM.java delete mode 100644 new-system-tests/src/test/java/io/apicurio/registry/systemtests/TestBase.java delete mode 100644 new-system-tests/src/test/java/io/apicurio/registry/systemtests/Utils.java delete mode 100644 new-system-tests/src/test/resources/apicurio/01_subscription.yaml delete mode 100644 new-system-tests/src/test/resources/apicurio/02_registry_kafkasql_no_auth_keycloak.yaml delete mode 100644 new-system-tests/src/test/resources/apicurio/02_registry_kafkasql_no_auth_no_iam.yaml delete mode 100644 new-system-tests/src/test/resources/apicurio/02_registry_sql_keycloak.yaml delete mode 100644 new-system-tests/src/test/resources/apicurio/02_registry_sql_no_iam.yaml delete mode 100644 new-system-tests/src/test/resources/common/00_operator_group.yaml delete mode 100644 new-system-tests/src/test/resources/kafkasql/01_subscription.yaml delete mode 100644 new-system-tests/src/test/resources/kafkasql/02_no_auth.yaml delete mode 100644 new-system-tests/src/test/resources/keycloak/00_service.yaml delete mode 100644 new-system-tests/src/test/resources/keycloak/02_deployment.yaml delete mode 100644 new-system-tests/src/test/resources/sql/00_service.yaml delete mode 100644 new-system-tests/src/test/resources/sql/01_deployment.yaml create mode 100644 schema-util/asyncapi/src/main/java/io/apicurio/registry/content/dereference/AsyncApiDereferencer.java create mode 100644 schema-util/asyncapi/src/main/java/io/apicurio/registry/content/extract/AsyncApiContentExtractor.java create mode 100644 schema-util/asyncapi/src/main/java/io/apicurio/registry/content/refs/AsyncApiReferenceFinder.java create mode 100644 schema-util/avro/src/main/java/io/apicurio/registry/content/refs/AvroReferenceFinder.java create mode 100644 schema-util/common/src/main/java/io/apicurio/registry/content/refs/ExternalReference.java create mode 100644 schema-util/common/src/main/java/io/apicurio/registry/content/refs/JsonPointerExternalReference.java create mode 100644 schema-util/common/src/main/java/io/apicurio/registry/content/refs/NoOpReferenceFinder.java create mode 100644 schema-util/common/src/main/java/io/apicurio/registry/content/refs/ReferenceFinder.java create mode 100644 schema-util/json/src/main/java/io/apicurio/registry/content/refs/JsonSchemaReferenceFinder.java create mode 100644 schema-util/openapi/src/main/java/io/apicurio/registry/content/dereference/ApicurioDataModelsContentDereferencer.java rename integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryStorageType.java => schema-util/openapi/src/main/java/io/apicurio/registry/content/dereference/OpenApiDereferencer.java (73%) create mode 100644 schema-util/openapi/src/main/java/io/apicurio/registry/content/dereference/ReferenceRewriter.java rename schema-util/openapi/src/main/java/io/apicurio/registry/content/extract/{OpenApiOrAsyncApiContentExtractor.java => ApicurioDataModelsContentExtractor.java} (96%) rename integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryTestProcess.java => schema-util/openapi/src/main/java/io/apicurio/registry/content/extract/OpenApiContentExtractor.java (72%) create mode 100644 schema-util/openapi/src/main/java/io/apicurio/registry/content/refs/AbstractDataModelsReferenceFinder.java create mode 100644 schema-util/openapi/src/main/java/io/apicurio/registry/content/refs/OpenApiReferenceFinder.java create mode 100644 schema-util/protobuf/src/main/java/io/apicurio/registry/content/refs/ProtobufReferenceFinder.java create mode 100644 schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/AsyncApiContentDereferencerTest.java create mode 100644 schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/JsonSchemaContentDereferencerTest.java create mode 100644 schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/OpenApiContentDereferencerTest.java create mode 100644 schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/AsyncApiReferenceFinderTest.java create mode 100644 schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/AvroReferenceFinderTest.java create mode 100644 schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/JsonSchemaReferenceFinderTest.java create mode 100644 schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/OpenApiReferenceFinderTest.java create mode 100644 schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/ProtobufReferenceFinderTest.java create mode 100644 schema-util/util-provider/src/test/resources/io/apicurio/registry/content/dereference/asyncapi-to-rewrite.json create mode 100644 schema-util/util-provider/src/test/resources/io/apicurio/registry/content/dereference/json-schema-to-rewrite.json create mode 100644 schema-util/util-provider/src/test/resources/io/apicurio/registry/content/dereference/openapi-to-rewrite.json create mode 100644 schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/asyncapi-with-refs.json create mode 100644 schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/avro-with-refs.avsc create mode 100644 schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/json-schema-with-refs.json create mode 100644 schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/openapi-with-refs.json create mode 100644 schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/protobuf-with-refs.proto create mode 100644 utils/maven-plugin/src/main/java/io/apicurio/registry/maven/ExistingReference.java create mode 100644 utils/maven-plugin/src/main/java/io/apicurio/registry/maven/refs/IndexedResource.java create mode 100644 utils/maven-plugin/src/main/java/io/apicurio/registry/maven/refs/ReferenceIndex.java create mode 100644 utils/tests/src/main/java/io/apicurio/registry/utils/tests/MultitenancyNoAuthTestProfile.java rename {storage/sql/src/test/java/io/apicurio/registry/storage/util => utils/tests/src/main/java/io/apicurio/registry/utils/tests}/PostgreSqlEmbeddedTestResource.java (64%) diff --git a/.github/workflows/integration-tests.yaml b/.github/workflows/integration-tests.yaml index 56b52c83ba..3084057fbf 100644 --- a/.github/workflows/integration-tests.yaml +++ b/.github/workflows/integration-tests.yaml @@ -22,8 +22,8 @@ concurrency: cancel-in-progress: true jobs: - prepare-integration-tests: - name: Prepare for Integration Tests + prepare-sql-tests: + name: Prepare for SQL Integration Tests runs-on: ubuntu-20.04 if: github.repository_owner == 'Apicurio' && !contains(github.event.*.labels.*.name, 'DO NOT MERGE') steps: @@ -38,33 +38,53 @@ jobs: distribution: 'temurin' cache: 'maven' - - name: Workaround jackson-coreutils - run: | - # upstream issue: https://github.com/java-json-tools/jackson-coreutils/issues/59 - rm -rf ~/.m2/repository/com/github/java-json-tools - mkdir -p /tmp/coreutils-workaround - ( cd /tmp/coreutils-workaround && mvn dependency:get -DremoteRepositories=https://repo1.maven.org/maven2 -Dartifact=com.github.java-json-tools:jackson-coreutils:2.0 ) - - name: Get maven wrapper run: mvn -N io.takari:maven:wrapper -Dmaven=3.8.2 - - name: Build integration-tests-common - run: ./mvnw install -Pintegration-tests -pl integration-tests/integration-tests-common -am + - name: Build Sql Variant + run: make SKIP_TESTS=true BUILD_FLAGS='-Dmaven.javadoc.skip=true --no-transfer-progress -Dmaven.wagon.httpconnectionManager.maxTotal=30 -Dmaven.wagon.http.retryHandler.count=5' build-sql + + - name: Build and Push Sql image + env: + IMAGE_REPO: ttl.sh/${{ github.sha }} + # maximum allowed + IMAGE_TAG: 1d + run: make build-sql-image push-sql-image - - name: Store Apicurio artifacts - id: store-apicurio - uses: actions/upload-artifact@v3 + + prepare-kafkasql-tests: + name: Prepare for KafkaSQL Integration Tests + runs-on: ubuntu-20.04 + if: github.repository_owner == 'Apicurio' && !contains(github.event.*.labels.*.name, 'DO NOT MERGE') + steps: + - name: Show Actor + run: echo ${{github.actor}} + - name: Checkout Code + uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 with: - name: apicurio-artifacts.zip - retention-days: 1 - path: | - ~/.m2/repository/io/apicurio - !~/.m2/repository/io/apicurio/**/*.tar.gz + java-version: '17' + distribution: 'temurin' + cache: 'maven' + + - name: Get maven wrapper + run: mvn -N io.takari:maven:wrapper -Dmaven=3.8.2 + + - name: Build kafkasql Variant + run: make SKIP_TESTS=true BUILD_FLAGS='-DskipUiBuild=true -Dmaven.javadoc.skip=true --no-transfer-progress -Dmaven.wagon.httpconnectionManager.maxTotal=30 -Dmaven.wagon.http.retryHandler.count=5' build-kafkasql + + - name: Build and Push kafkasql image + env: + IMAGE_REPO: ttl.sh/${{ github.sha }} + # maximum allowed + IMAGE_TAG: 1d + run: make build-kafkasql-image push-kafkasql-image integration-tests-sql: name: Integration Tests SQL runs-on: ubuntu-20.04 - needs: prepare-integration-tests + needs: prepare-sql-tests steps: - name: Checkout Code uses: actions/checkout@v3 @@ -75,35 +95,37 @@ jobs: distribution: 'temurin' cache: 'maven' - - name: Download built apicurio artifacts - id: download-apicurio - uses: actions/download-artifact@v3 + - name: Setup Minikube + uses: manusa/actions-setup-minikube@v2.7.2 with: - path: ~/.m2/repository/io/apicurio - name: apicurio-artifacts.zip + minikube version: 'v1.31.1' + kubernetes version: 'v1.26.3' + github token: ${{ secrets.GITHUB_TOKEN }} + driver: docker - - name: Prepare Tenant Manager - run: make build-integration-tests-multitenancy - - - name: Build Sql Variant - run: make SKIP_TESTS=true BUILD_FLAGS='-DskipUiBuild=true -Dmaven.javadoc.skip=true --no-transfer-progress -Dmaven.wagon.httpconnectionManager.maxTotal=30 -Dmaven.wagon.http.retryHandler.count=5' build-sql + - name: Prepare minikube tunnel + run: minikube tunnel &> /dev/null & - name: Run Integration Tests - sql - run: ./mvnw verify -Pintegration-tests -Pci -Psql -Psqlit -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false - - name: Run Integration Tests - sql clustered - run: ./mvnw verify -Pintegration-tests -Pclustered -Psql -Psqlit -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false - - name: Run Integration Tests - sql migration - run: ./mvnw verify -Pintegration-tests -Pmigration -Psql -Psqlit -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false - - name: Run Integration Tests - sql auth - run: ./mvnw verify -Pintegration-tests -Pauth -Psql -Psqlit -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false - - name: Run Integration Tests - multitenancy - run: ./mvnw verify -Pintegration-tests -Pmultitenancy -Psql -Psqlit -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false - - name: Run Integration Tests - sql dbupgrade - run: ./mvnw verify -Pintegration-tests -Pdbupgrade -Psql -Psqlit -pl integration-tests/testsuite -DtrimStackTrace=false -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false + run: make REGISTRY_IMAGE='-Dregistry-sql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-sql:1d' run-sql-integration-tests + + - name: Run Integration Tests - sql - auth + run: make REGISTRY_IMAGE='-Dregistry-sql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-sql:1d' run-sql-auth-tests + + - name: Run Integration Tests - sql - migration + run: make REGISTRY_IMAGE='-Dregistry-sql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-sql:1d' run-sql-migration-integration-tests + + - name: Run Integration Tests - sql - db upgrade + run: make REGISTRY_IMAGE='-Dregistry-sql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-sql:1d' run-sql-upgrade-tests + + - name: Run Integration Tests - sql - multitenancy + run: make REGISTRY_IMAGE='-Dregistry-sql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-sql:1d' run-sql-multitenancy-integration-tests + - name: Collect logs if: failure() run: ./.github/scripts/collect_logs.sh + - name: Upload tests logs artifacts if: failure() uses: actions/upload-artifact@v1.0.0 @@ -114,7 +136,7 @@ jobs: integration-tests-kafkasql: name: Integration Tests KafkaSql runs-on: ubuntu-20.04 - needs: prepare-integration-tests + needs: prepare-kafkasql-tests steps: - name: Checkout Code uses: actions/checkout@v3 @@ -125,26 +147,28 @@ jobs: distribution: 'temurin' cache: 'maven' - - name: Download built apicurio artifacts - id: download-apicurio - uses: actions/download-artifact@v3 + - name: Setup Minikube + uses: manusa/actions-setup-minikube@v2.7.2 with: - path: ~/.m2/repository/io/apicurio - name: apicurio-artifacts.zip + minikube version: 'v1.31.1' + kubernetes version: 'v1.26.3' + github token: ${{ secrets.GITHUB_TOKEN }} + driver: docker - - name: Build KafkaSql variant - run: make SKIP_TESTS=true BUILD_FLAGS='-DskipUiBuild=true -Dmaven.javadoc.skip=true --no-transfer-progress -Dmaven.wagon.httpconnectionManager.maxTotal=30 -Dmaven.wagon.http.retryHandler.count=5' build-kafkasql + - name: Prepare minikube tunnel + run: minikube tunnel &> /dev/null & + + - name: Run Integration Tests - KafkaSql + run: make REGISTRY_IMAGE='-Dregistry-kafkasql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-kafkasql:1d' run-kafkasql-integration-tests + + - name: Run Integration Tests - KafkaSql - Migration + run: make REGISTRY_IMAGE='-Dregistry-kafkasql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-kafkasql:1d' run-kafkasql-migration-integration-tests + + - name: Run Integration Tests - KafkaSql - DBUpgrade + run: make REGISTRY_IMAGE='-Dregistry-kafkasql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-kafkasql:1d' run-kafkasql-upgrade-tests - - name: Run Integration Tests - kafkasql - run: ./mvnw verify -Pintegration-tests -Pci -Pkafkasql -Pkafkasqlit -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false - - name: Run Integration Tests - kafkasql clustered - run: ./mvnw verify -Pintegration-tests -Pclustered -Pkafkasql -Pkafkasqlit -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false - - name: Run Integration Tests - kafkasql migration - run: ./mvnw verify -Pintegration-tests -Pmigration -Pkafkasql -Pkafkasqlit -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false - - name: Run Integration Tests - kafkasql auth - run: ./mvnw verify -Pintegration-tests -Pauth -Pkafkasql -Pkafkasqlit -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false - - name: Run Integration Tests - kafkasql dbupgrade - run: ./mvnw verify -Pintegration-tests -Pdbupgrade -Pkafkasql -Pkafkasqlit -pl integration-tests/testsuite -DtrimStackTrace=false -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false + - name: Run Integration Tests - KafkaSql - Auth + run: make REGISTRY_IMAGE='-Dregistry-kafkasql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-kafkasql:1d' run-kafkasql-auth-tests - name: Collect logs if: failure() @@ -159,7 +183,7 @@ jobs: integration-tests-ui: name: Integration Tests UI runs-on: ubuntu-20.04 - needs: prepare-integration-tests + needs: prepare-sql-tests steps: - name: Checkout Code uses: actions/checkout@v3 @@ -170,18 +194,19 @@ jobs: distribution: 'temurin' cache: 'maven' - - name: Download built apicurio artifacts - id: download-apicurio - uses: actions/download-artifact@v3 + - name: Setup Minikube + uses: manusa/actions-setup-minikube@v2.7.2 with: - path: ~/.m2/repository/io/apicurio - name: apicurio-artifacts.zip + minikube version: 'v1.31.1' + kubernetes version: 'v1.26.3' + github token: ${{ secrets.GITHUB_TOKEN }} + driver: docker - - name: Build In-memory variant - run: make SKIP_TESTS=true BUILD_FLAGS='-Dmaven.javadoc.skip=true --no-transfer-progress -Dmaven.wagon.httpconnectionManager.maxTotal=30 -Dmaven.wagon.http.retryHandler.count=5' build-in-memory + - name: Prepare minikube tunnel + run: minikube tunnel &> /dev/null & - name: Run UI tests - run: ./mvnw verify -Pintegration-tests -Pui -Pinmemory -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false + run: make REGISTRY_IMAGE='-Dregistry-sql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-sql:1d' run-ui-tests - name: Collect logs if: failure() diff --git a/.github/workflows/kubernetes-tests-manual.yaml b/.github/workflows/kubernetes-tests-manual.yaml deleted file mode 100644 index 455bee321c..0000000000 --- a/.github/workflows/kubernetes-tests-manual.yaml +++ /dev/null @@ -1,59 +0,0 @@ -name: Kubernetes Tests Workflow - Manual -on: - - workflow_dispatch: - inputs: - branch: - description: 'Branch to run tests on' - required: true - default: 'main' - apicurio-tests-profile: - description: 'Apicurio Tests Profile to be used, determines what tests are executed from tests module' - required: true - default: 'smoke' - -jobs: - kubernetes-tests: - name: Kubernetes Tests - runs-on: ubuntu-20.04 - if: github.repository_owner == 'Apicurio' - steps: - - name: Checkout Code - uses: actions/checkout@v3 - with: - ref: ${{ github.event.inputs.branch }} - - - uses: actions/setup-go@v2 - with: - go-version: '^1.16.8' - - run: go version - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: 'maven' - - - name: Build All Variants - run: make SKIP_TESTS=true build-all - - - name: Build The Tagged Docker Images - run: | - make IMAGE_TAG=latest-snapshot build-mem-image - make IMAGE_TAG=latest-snapshot build-sql-image - make IMAGE_TAG=latest-snapshot build-kafkasql-image - - - name: Kubernetes Tests - run: CI_BUILD=true APICURIO_IMAGES_TAG="latest-snapshot" E2E_APICURIO_TESTS_PROFILE=${{ github.event.inputs.apicurio-tests-profile }} ./.github/scripts/test_apicurio_kubernetes.sh - - - name: Collect logs - if: failure() - run: ./.github/scripts/collect_kubernetes_logs.sh - - - name: Upload tests logs artifacts - if: failure() - uses: actions/upload-artifact@v1.0.0 - with: - name: tests-logs - path: artifacts diff --git a/.github/workflows/kubernetes-tests.yaml b/.github/workflows/kubernetes-tests.yaml deleted file mode 100644 index e05805b59a..0000000000 --- a/.github/workflows/kubernetes-tests.yaml +++ /dev/null @@ -1,124 +0,0 @@ -name: Kubernetes Tests Workflow -on: - push: - paths-ignore: - - '.gitignore' - - 'LICENSE' - - 'README*' - - 'docs/**' - - '.github/workflows/**' - branches: [main] - pull_request: - paths-ignore: - - '.gitignore' - - 'LICENSE' - - 'README*' - - 'docs/**' - branches: [main] - -concurrency: - # Only run once for latest commit per ref and cancel other (previous) runs. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - kubernetes-tests-basic: - name: Kubernetes Tests Basic - runs-on: ubuntu-20.04 - if: github.repository_owner == 'Apicurio' && !contains(github.event.*.labels.*.name, 'DO NOT MERGE') - steps: - - name: Checkout Code - uses: actions/checkout@v3 - - - uses: actions/setup-go@v2 - with: - go-version: '^1.16.8' - - run: go version - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: 'maven' - - - name: Get maven wrapper - run: mvn -N io.takari:maven:wrapper -Dmaven=3.8.2 - - - name: Build api-model - run: | - git clone https://github.com/Apicurio/apicurio-registry-operator.git - cd apicurio-registry-operator/api-model - mvn install - - - name: Build All Variants - run: make SKIP_TESTS=true BUILD_FLAGS='-Dmaven.javadoc.skip=true --no-transfer-progress -Dmaven.wagon.httpconnectionManager.maxTotal=30 -Dmaven.wagon.http.retryHandler.count=5' build-all - - - name: Build The Tagged Docker Images - run: | - make IMAGE_TAG=latest-ci build-mem-image - make IMAGE_TAG=latest-ci build-sql-image - make IMAGE_TAG=latest-ci build-kafkasql-image - - - name: Kubernetes Tests - run: CI_BUILD=true APICURIO_IMAGES_TAG="latest-ci" E2E_APICURIO_TESTS_PROFILE=acceptance ./.github/scripts/test_apicurio_kubernetes.sh - - - name: Collect logs - if: failure() - run: ./.github/scripts/collect_kubernetes_logs.sh - - - name: Upload tests logs artifacts - if: failure() - uses: actions/upload-artifact@v1.0.0 - with: - name: tests-logs - path: artifacts - - kubernetes-tests-clustered: - name: Kubernetes Tests Clustered - runs-on: ubuntu-20.04 - if: github.repository_owner == 'Apicurio' && !contains(github.event.*.labels.*.name, 'DO NOT MERGE') - steps: - - name: Checkout Code - uses: actions/checkout@v3 - - - uses: actions/setup-go@v2 - with: - go-version: '^1.16.8' - - run: go version - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: 'maven' - - - name: Build api-model - run: | - git clone https://github.com/Apicurio/apicurio-registry-operator.git - cd apicurio-registry-operator/api-model - mvn install - - - name: Build All Variants - run: mvn clean install -Pprod -Psql -Pkafkasql -DskipTests -Dmaven.javadoc.skip=true --no-transfer-progress - - - name: Build The Tagged Docker Images - run: | - make IMAGE_TAG=latest-ci build-mem-image - make IMAGE_TAG=latest-ci build-sql-image - make IMAGE_TAG=latest-ci build-kafkasql-image - - - name: Kubernetes Tests - run: CI_BUILD=true APICURIO_IMAGES_TAG="latest-ci" E2E_APICURIO_TESTS_PROFILE=clustered ./.github/scripts/test_apicurio_kubernetes.sh - - - name: Collect logs - if: failure() - run: ./.github/scripts/collect_kubernetes_logs.sh - - - name: Upload tests logs artifacts - if: failure() - uses: actions/upload-artifact@v1.0.0 - with: - name: tests-logs - path: artifacts diff --git a/.github/workflows/new-system-tests.yaml b/.github/workflows/new-system-tests.yaml deleted file mode 100644 index e4bec8a7fc..0000000000 --- a/.github/workflows/new-system-tests.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: New System Tests Infrastructure -on: - push: - paths-ignore: - - '.gitignore' - - 'LICENSE' - - 'README*' - - 'docs/**' - - '.github/workflows/**' - branches: [main] - pull_request: - paths-ignore: - - '.gitignore' - - 'LICENSE' - - 'README*' - - 'docs/**' - branches: [main] - -jobs: - test: - name: Run New System Tests - runs-on: ubuntu-latest - steps: - - name: Checkout Code with Ref '${{ github.ref }}' - uses: actions/checkout@v3 - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: 17 - distribution: 'temurin' - cache: 'maven' - - - name: Setup Minikube - uses: manusa/actions-setup-minikube@v2.7.2 - with: - minikube version: 'v1.28.0' - kubernetes version: 'v1.25.3' - github token: ${{ secrets.GITHUB_TOKEN }} - - - name: Run the tests - working-directory: new-system-tests - run: mvn clean verify diff --git a/.github/workflows/publish-debug-image.yaml b/.github/workflows/publish-debug-image.yaml deleted file mode 100644 index 4d5e62c686..0000000000 --- a/.github/workflows/publish-debug-image.yaml +++ /dev/null @@ -1,41 +0,0 @@ -name: Publish debug mem image - -on: - pull_request: - branches: [main] - -concurrency: - # Only run once for latest commit per ref and cancel other (previous) runs. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build-push-mem-image: - name: Docker image from PR - runs-on: ubuntu-20.04 - if: github.repository_owner == 'Apicurio' - steps: - - name: Checkout Code with Ref '${{ github.ref }}' - uses: actions/checkout@v3 - - - name: Set up JDK - uses: actions/setup-java@v3 - with: - java-version: 17 - distribution: 'temurin' - cache: 'maven' - - - name: Build the project - env: - SKIP_TESTS: true - run: make build-all - - - name: Build and Push Mem image - env: - IMAGE_REPO: ttl.sh/${{ github.sha }} - # maximum allowed - IMAGE_TAG: 1d - run: make build-mem-image push-mem-image - - - name: EXECUTABLE COMMAND - run: echo "docker run --rm -it -p 8080:8080 ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-mem:1d" diff --git a/.github/workflows/release-images.yaml b/.github/workflows/release-images.yaml index bb66e9209a..a55d0d7ad5 100644 --- a/.github/workflows/release-images.yaml +++ b/.github/workflows/release-images.yaml @@ -21,6 +21,7 @@ jobs: release-images: if: github.repository_owner == 'Apicurio' runs-on: ubuntu-20.04 + timeout-minutes: 120 env: RELEASE_TYPE: release steps: diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index f9790bbe14..3dd6e86333 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -198,11 +198,10 @@ jobs: if: github.event_name == 'push' run: docker login -u "${{ secrets.QUAY_USERNAME }}" -p "${{ secrets.QUAY_PASSWORD }}" quay.io - - name: Build and Push In Memory Multi-arch Images to Quay.io + - name: Build and Push KafkaSQL Multi-arch Images to Quay.io if: github.event_name == 'push' run: ./.github/scripts/build-and-push-multiarch-images.sh ${GITHUB_REF#refs/heads/} quay.io kafkasql-multiarch-images snapshot - build-mem-native-images: name: Build and Test In Memory native images runs-on: ubuntu-20.04 @@ -255,15 +254,29 @@ jobs: run: | make BUILD_FLAGS='-DskipUiBuild' build-mem-native - - name: Prepare Tenant Manager - run: make build-integration-tests-multitenancy + - name: Build and Push Temporary image for testing + env: + IMAGE_REPO: ttl.sh/${{ github.sha }} + # maximum allowed + IMAGE_TAG: 1d + run: make build-mem-native-image push-mem-native-image + + - name: Setup Minikube + uses: manusa/actions-setup-minikube@v2.7.2 + with: + minikube version: 'v1.31.1' + kubernetes version: 'v1.26.3' + github token: ${{ secrets.GITHUB_TOKEN }} + driver: docker + + - name: Prepare minikube tunnel + run: minikube tunnel &> /dev/null & - - name: Build integration-tests-common - run: ./mvnw install -Pintegration-tests -pl integration-tests/integration-tests-common - name: Run Integration Tests - inmemory - run: ./mvnw verify -Pintegration-tests -Pacceptance -Pinmemory -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtestNative=true - - name: Run Integration Tests - inmemory auth - run: ./mvnw verify -Pintegration-tests -Pauth -Pinmemory -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtestNative=true + run: make REGISTRY_IMAGE='-Dregistry-in-memory-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-mem-native:1d' run-in-memory-integration-tests + + - name: Run Integration Tests - inmemory - auth + run: make REGISTRY_IMAGE='-Dregistry-in-memory-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-mem-native:1d' run-in-memory-auth-tests - name: Collect logs if: failure() @@ -321,10 +334,10 @@ jobs: - name: Build Sql Variant if: github.ref == 'refs/heads/main' - run: make SKIP_TESTS=true BUILD_FLAGS='-DskipCommitIdPlugin=false -Dmaven.wagon.httpconnectionManager.maxTotal=30 -Dmaven.wagon.http.retryHandler.count=5 --no-transfer-progress' build-sql + run: make SKIP_TESTS=true BUILD_FLAGS='-DskipUiBuild=false -Dmaven.javadoc.skip=true --no-transfer-progress -Dmaven.wagon.httpconnectionManager.maxTotal=30 -Dmaven.wagon.http.retryHandler.count=5' build-sql - name: Build Sql Variant Without UI if: github.ref != 'refs/heads/main' - run: make SKIP_TESTS=true BUILD_FLAGS='-DskipUiBuild -Dmaven.wagon.httpconnectionManager.maxTotal=30 -Dmaven.wagon.http.retryHandler.count=5 --no-transfer-progress' build-sql + run: make SKIP_TESTS=true BUILD_FLAGS='-DskipUiBuild=true -Dmaven.javadoc.skip=true --no-transfer-progress -Dmaven.wagon.httpconnectionManager.maxTotal=30 -Dmaven.wagon.http.retryHandler.count=5' build-sql - name: Verify docs generation run: | @@ -347,19 +360,35 @@ jobs: if: github.ref != 'refs/heads/main' run: make BUILD_FLAGS='-DskipUiBuild' build-sql-native - - name: Prepare Tenant Manager - run: make build-integration-tests-multitenancy + - name: Build and Push Temporary image for testing + env: + IMAGE_REPO: ttl.sh/${{ github.sha }} + # maximum allowed + IMAGE_TAG: 1d + run: make build-sql-native-image push-sql-native-image + + - name: Setup Minikube + uses: manusa/actions-setup-minikube@v2.7.2 + with: + minikube version: 'v1.31.1' + kubernetes version: 'v1.26.3' + github token: ${{ secrets.GITHUB_TOKEN }} + driver: docker + + - name: Prepare minikube tunnel + run: minikube tunnel &> /dev/null & - - name: Build integration-tests-common - run: ./mvnw install -Pintegration-tests -pl integration-tests/integration-tests-common - - name: Run Integration Tests - multitenancy - run: ./mvnw verify -Pintegration-tests -Pmultitenancy -Psql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false -DtestNative=true - name: Run Integration Tests - sql - run: ./mvnw verify -Pintegration-tests -Pacceptance -Psql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtestNative=true - - name: Run Integration Tests - sql migration - run: ./mvnw verify -Pintegration-tests -Pmigration -Psql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtestNative=true + run: make REGISTRY_IMAGE='-Dregistry-sql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-sql-native:1d' run-sql-integration-tests + - name: Run Integration Tests - sql auth - run: ./mvnw verify -Pintegration-tests -Pauth -Psql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtestNative=true + run: make REGISTRY_IMAGE='-Dregistry-sql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-sql-native:1d' run-sql-auth-tests + + - name: Run Integration Tests - sql migration + run: make REGISTRY_IMAGE='-Dregistry-sql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-sql-native:1d' run-sql-migration-integration-tests + + - name: Run Integration Tests - sql multitenancy + run: make REGISTRY_IMAGE='-Dregistry-sql-image=ttl.sh/${{ github.sha }}/apicurio/apicurio-registry-sql-native:1d' run-sql-multitenancy-integration-tests - name: Collect logs if: failure() diff --git a/.tekton/apicurio-registry-f36x-pull-request.yaml b/.tekton/apicurio-registry-f36x-pull-request.yaml deleted file mode 100644 index 04a1c31639..0000000000 --- a/.tekton/apicurio-registry-f36x-pull-request.yaml +++ /dev/null @@ -1,342 +0,0 @@ -apiVersion: tekton.dev/v1beta1 -kind: PipelineRun -metadata: - annotations: - build.appstudio.redhat.com/commit_sha: '{{revision}}' - build.appstudio.redhat.com/pull_request_number: '{{pull_request_number}}' - build.appstudio.redhat.com/target_branch: '{{target_branch}}' - pipelinesascode.tekton.dev/max-keep-runs: "3" - pipelinesascode.tekton.dev/on-event: '[pull_request]' - pipelinesascode.tekton.dev/on-target-branch: '[main]' - creationTimestamp: null - labels: - appstudio.openshift.io/application: apicurio-registry - appstudio.openshift.io/component: apicurio-registry-f36x - pipelines.appstudio.openshift.io/type: build - name: apicurio-registry-f36x-on-pull-request - namespace: service-registry-tenant -spec: - params: - - name: dockerfile - value: Dockerfile.jvm.staged - - name: git-url - value: '{{repo_url}}' - - name: output-image - value: quay.io/redhat-appstudio/user-workload:on-pr-{{revision}} - - name: path-context - value: . - - name: revision - value: '{{revision}}' - pipelineSpec: - finally: - - name: show-summary - params: - - name: pipelinerun-name - value: $(context.pipelineRun.name) - - name: git-url - value: $(tasks.clone-repository.results.url)?rev=$(tasks.clone-repository.results.commit) - - name: image-url - value: $(params.output-image) - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-summary:0.1@sha256:9e21e57456c026c15765db23b986e47fc1394fa5d4823d3038b697971dd1a2bd - name: summary - params: - - description: Source Repository URL - name: git-url - type: string - - default: "" - description: Revision of the Source Repository - name: revision - type: string - - description: Fully Qualified Output Image - name: output-image - type: string - - default: . - description: The path to your source code - name: path-context - type: string - - default: Dockerfile - description: Path to the Dockerfile - name: dockerfile - type: string - - default: "false" - description: Force rebuild image - name: rebuild - type: string - - default: "false" - description: Skip checks against built image - name: skip-checks - type: string - - default: "false" - description: Execute the build with network isolation - name: hermetic - type: string - - default: "" - description: Build dependencies to be prefetched by Cachi2 - name: prefetch-input - type: string - - default: "false" - description: Java build - name: java - type: string - - default: "" - description: Snyk Token Secret Name - name: snyk-secret - type: string - results: - - description: "" - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - description: "" - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - description: "" - name: CHAINS-GIT_URL - value: $(tasks.clone-repository.results.url) - - description: "" - name: CHAINS-GIT_COMMIT - value: $(tasks.clone-repository.results.commit) - - description: "" - name: JAVA_COMMUNITY_DEPENDENCIES - value: $(tasks.build-container.results.JAVA_COMMUNITY_DEPENDENCIES) - tasks: - - name: init - params: - - name: image-url - value: $(params.output-image) - - name: rebuild - value: $(params.rebuild) - - name: skip-checks - value: $(params.skip-checks) - - name: pipelinerun-name - value: $(context.pipelineRun.name) - - name: pipelinerun-uid - value: $(context.pipelineRun.uid) - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-init:0.1@sha256:8c06b307b7f74622503b80ff0b81ffda63129959f52f8ed8f753d8ab98f38411 - name: init - - name: clone-repository - params: - - name: url - value: $(params.git-url) - - name: revision - value: $(params.revision) - runAfter: - - init - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-git-clone:0.1@sha256:458f4853a01c3273bd76076ac1b015d5f901e70fb4b776f788b577adb25bf5f8 - name: git-clone - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: output - workspace: workspace - - name: basic-auth - workspace: git-auth - - name: prefetch-dependencies - params: - - name: input - value: $(params.prefetch-input) - runAfter: - - clone-repository - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-prefetch-dependencies:0.1@sha256:609f5c2a0d72dddb193a0fc2aef2390601172d09f093deadfb9827e28e8dea30 - name: prefetch-dependencies - when: - - input: $(params.hermetic) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace - - name: build-container - params: - - name: IMAGE - value: $(params.output-image) - - name: DOCKERFILE - value: $(params.dockerfile) - - name: CONTEXT - value: $(params.path-context) - - name: DOCKER_AUTH - value: $(tasks.init.results.container-registry-secret) - - name: HERMETIC - value: $(params.hermetic) - - name: PREFETCH_INPUT - value: $(params.prefetch-input) - runAfter: - - prefetch-dependencies - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-buildah:0.1@sha256:f4c4c211a7b8c859fb23d9b01faaf1a995a33b243476a617370e35f6438096e0 - name: buildah - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace - - name: sanity-inspect-image - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: DOCKER_AUTH - value: $(tasks.init.results.container-registry-secret) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sanity-inspect-image:0.1@sha256:b9ad0ed56be21c9e3c8e2e636275f92d887e57681c718cd36f117eb6fa547824 - name: sanity-inspect-image - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: source - workspace: workspace - - name: sanity-label-check - runAfter: - - sanity-inspect-image - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sanity-label-check:0.1@sha256:dd49667be76c81264a7fb28e3b43f72c527507e5691720c6262575255cb60689 - name: sanity-label-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - workspace: workspace - - name: sanity-optional-label-check - params: - - name: POLICY_NAMESPACE - value: optional_checks - runAfter: - - sanity-inspect-image - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sanity-label-check:0.1@sha256:dd49667be76c81264a7fb28e3b43f72c527507e5691720c6262575255cb60689 - name: sanity-label-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - workspace: workspace - - name: deprecated-base-image-check - params: - - name: BASE_IMAGES_DIGESTS - value: $(tasks.build-container.results.BASE_IMAGES_DIGESTS) - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-deprecated-image-check:0.2@sha256:bf1a1cad85bb896e920f0f7ff5dda2f885b76f2617934f72e7954565cd50df49 - name: deprecated-image-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: test-ws - workspace: workspace - - name: clair-scan - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - - name: docker-auth - value: $(tasks.init.results.container-registry-secret) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-clair-scan:0.1@sha256:1b4951e91fdfb3188d459d0abac411a6364da5cb135e81fb4a84bbd782bb545d - name: clair-scan - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: sast-snyk-check - params: - - name: SNYK_SECRET - value: $(params.snyk-secret) - runAfter: - - clone-repository - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sast-snyk-check:0.1@sha256:58f288a86ae7e1a2fff416d11720521effcf8e9b410355080a2b8a9bb8ae587c - name: sast-snyk-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - input: $(params.snyk-secret) - operator: notin - values: - - "" - workspaces: - - name: workspace - workspace: workspace - - name: clamav-scan - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - - name: docker-auth - value: $(tasks.init.results.container-registry-secret) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-clamav-scan:0.1@sha256:2c8dbe8aa7c0fa126a9c84e7590c4e901bcfeec6dde4ccbffda4c493cefb43ed - name: clamav-scan - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: sbom-json-check - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sbom-json-check:0.1@sha256:9a232f343d6397bfaf9620b6e63ce6943e256ad30da93cf8e9de3ca63ada7717 - name: sbom-json-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - - name: git-auth - optional: true - workspaces: - - name: workspace - volumeClaimTemplate: - metadata: - creationTimestamp: null - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - status: {} - - name: git-auth - secret: - secretName: '{{ git_auth_secret }}' -status: {} diff --git a/.tekton/apicurio-registry-f36x-push.yaml b/.tekton/apicurio-registry-f36x-push.yaml deleted file mode 100644 index 7957079168..0000000000 --- a/.tekton/apicurio-registry-f36x-push.yaml +++ /dev/null @@ -1,341 +0,0 @@ -apiVersion: tekton.dev/v1beta1 -kind: PipelineRun -metadata: - annotations: - build.appstudio.redhat.com/commit_sha: '{{revision}}' - build.appstudio.redhat.com/target_branch: '{{target_branch}}' - pipelinesascode.tekton.dev/max-keep-runs: "3" - pipelinesascode.tekton.dev/on-event: '[push]' - pipelinesascode.tekton.dev/on-target-branch: '[main]' - creationTimestamp: null - labels: - appstudio.openshift.io/application: apicurio-registry - appstudio.openshift.io/component: apicurio-registry-f36x - pipelines.appstudio.openshift.io/type: build - name: apicurio-registry-f36x-on-push - namespace: service-registry-tenant -spec: - params: - - name: dockerfile - value: Dockerfile.jvm.staged - - name: git-url - value: '{{repo_url}}' - - name: output-image - value: quay.io/redhat-appstudio/user-workload:{{revision}} - - name: path-context - value: . - - name: revision - value: '{{revision}}' - pipelineSpec: - finally: - - name: show-summary - params: - - name: pipelinerun-name - value: $(context.pipelineRun.name) - - name: git-url - value: $(tasks.clone-repository.results.url)?rev=$(tasks.clone-repository.results.commit) - - name: image-url - value: $(params.output-image) - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-summary:0.1@sha256:9e21e57456c026c15765db23b986e47fc1394fa5d4823d3038b697971dd1a2bd - name: summary - params: - - description: Source Repository URL - name: git-url - type: string - - default: "" - description: Revision of the Source Repository - name: revision - type: string - - description: Fully Qualified Output Image - name: output-image - type: string - - default: . - description: The path to your source code - name: path-context - type: string - - default: Dockerfile - description: Path to the Dockerfile - name: dockerfile - type: string - - default: "false" - description: Force rebuild image - name: rebuild - type: string - - default: "false" - description: Skip checks against built image - name: skip-checks - type: string - - default: "false" - description: Execute the build with network isolation - name: hermetic - type: string - - default: "" - description: Build dependencies to be prefetched by Cachi2 - name: prefetch-input - type: string - - default: "false" - description: Java build - name: java - type: string - - default: "" - description: Snyk Token Secret Name - name: snyk-secret - type: string - results: - - description: "" - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - description: "" - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - description: "" - name: CHAINS-GIT_URL - value: $(tasks.clone-repository.results.url) - - description: "" - name: CHAINS-GIT_COMMIT - value: $(tasks.clone-repository.results.commit) - - description: "" - name: JAVA_COMMUNITY_DEPENDENCIES - value: $(tasks.build-container.results.JAVA_COMMUNITY_DEPENDENCIES) - tasks: - - name: init - params: - - name: image-url - value: $(params.output-image) - - name: rebuild - value: $(params.rebuild) - - name: skip-checks - value: $(params.skip-checks) - - name: pipelinerun-name - value: $(context.pipelineRun.name) - - name: pipelinerun-uid - value: $(context.pipelineRun.uid) - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-init:0.1@sha256:8c06b307b7f74622503b80ff0b81ffda63129959f52f8ed8f753d8ab98f38411 - name: init - - name: clone-repository - params: - - name: url - value: $(params.git-url) - - name: revision - value: $(params.revision) - runAfter: - - init - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-git-clone:0.1@sha256:458f4853a01c3273bd76076ac1b015d5f901e70fb4b776f788b577adb25bf5f8 - name: git-clone - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: output - workspace: workspace - - name: basic-auth - workspace: git-auth - - name: prefetch-dependencies - params: - - name: input - value: $(params.prefetch-input) - runAfter: - - clone-repository - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-prefetch-dependencies:0.1@sha256:609f5c2a0d72dddb193a0fc2aef2390601172d09f093deadfb9827e28e8dea30 - name: prefetch-dependencies - when: - - input: $(params.hermetic) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace - - name: build-container - params: - - name: IMAGE - value: $(params.output-image) - - name: DOCKERFILE - value: $(params.dockerfile) - - name: CONTEXT - value: $(params.path-context) - - name: DOCKER_AUTH - value: $(tasks.init.results.container-registry-secret) - - name: HERMETIC - value: $(params.hermetic) - - name: PREFETCH_INPUT - value: $(params.prefetch-input) - runAfter: - - prefetch-dependencies - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-buildah:0.1@sha256:f4c4c211a7b8c859fb23d9b01faaf1a995a33b243476a617370e35f6438096e0 - name: buildah - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace - - name: sanity-inspect-image - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: DOCKER_AUTH - value: $(tasks.init.results.container-registry-secret) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sanity-inspect-image:0.1@sha256:b9ad0ed56be21c9e3c8e2e636275f92d887e57681c718cd36f117eb6fa547824 - name: sanity-inspect-image - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: source - workspace: workspace - - name: sanity-label-check - runAfter: - - sanity-inspect-image - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sanity-label-check:0.1@sha256:dd49667be76c81264a7fb28e3b43f72c527507e5691720c6262575255cb60689 - name: sanity-label-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - workspace: workspace - - name: sanity-optional-label-check - params: - - name: POLICY_NAMESPACE - value: optional_checks - runAfter: - - sanity-inspect-image - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sanity-label-check:0.1@sha256:dd49667be76c81264a7fb28e3b43f72c527507e5691720c6262575255cb60689 - name: sanity-label-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - workspace: workspace - - name: deprecated-base-image-check - params: - - name: BASE_IMAGES_DIGESTS - value: $(tasks.build-container.results.BASE_IMAGES_DIGESTS) - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-deprecated-image-check:0.2@sha256:bf1a1cad85bb896e920f0f7ff5dda2f885b76f2617934f72e7954565cd50df49 - name: deprecated-image-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: test-ws - workspace: workspace - - name: clair-scan - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - - name: docker-auth - value: $(tasks.init.results.container-registry-secret) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-clair-scan:0.1@sha256:1b4951e91fdfb3188d459d0abac411a6364da5cb135e81fb4a84bbd782bb545d - name: clair-scan - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: sast-snyk-check - params: - - name: SNYK_SECRET - value: $(params.snyk-secret) - runAfter: - - clone-repository - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sast-snyk-check:0.1@sha256:58f288a86ae7e1a2fff416d11720521effcf8e9b410355080a2b8a9bb8ae587c - name: sast-snyk-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - input: $(params.snyk-secret) - operator: notin - values: - - "" - workspaces: - - name: workspace - workspace: workspace - - name: clamav-scan - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - - name: docker-auth - value: $(tasks.init.results.container-registry-secret) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-clamav-scan:0.1@sha256:2c8dbe8aa7c0fa126a9c84e7590c4e901bcfeec6dde4ccbffda4c493cefb43ed - name: clamav-scan - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: sbom-json-check - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sbom-json-check:0.1@sha256:9a232f343d6397bfaf9620b6e63ce6943e256ad30da93cf8e9de3ca63ada7717 - name: sbom-json-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - - name: git-auth - optional: true - workspaces: - - name: workspace - volumeClaimTemplate: - metadata: - creationTimestamp: null - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - status: {} - - name: git-auth - secret: - secretName: '{{ git_auth_secret }}' -status: {} diff --git a/.tekton/apicurio-registry-qnbk-pull-request.yaml b/.tekton/apicurio-registry-qnbk-pull-request.yaml deleted file mode 100644 index 4645e49d5f..0000000000 --- a/.tekton/apicurio-registry-qnbk-pull-request.yaml +++ /dev/null @@ -1,342 +0,0 @@ -apiVersion: tekton.dev/v1beta1 -kind: PipelineRun -metadata: - annotations: - build.appstudio.redhat.com/commit_sha: '{{revision}}' - build.appstudio.redhat.com/pull_request_number: '{{pull_request_number}}' - build.appstudio.redhat.com/target_branch: '{{target_branch}}' - pipelinesascode.tekton.dev/max-keep-runs: "3" - pipelinesascode.tekton.dev/on-event: '[pull_request]' - pipelinesascode.tekton.dev/on-target-branch: '[main,master]' - creationTimestamp: null - labels: - appstudio.openshift.io/application: apicurio-registry - appstudio.openshift.io/component: apicurio-registry-qnbk - pipelines.appstudio.openshift.io/type: build - name: apicurio-registry-qnbk-on-pull-request - namespace: carnalca-srs-tenant -spec: - params: - - name: dockerfile - value: Dockerfile.jvm.staged - - name: git-url - value: '{{repo_url}}' - - name: output-image - value: quay.io/redhat-appstudio/user-workload:on-pr-{{revision}} - - name: path-context - value: . - - name: revision - value: '{{revision}}' - pipelineSpec: - finally: - - name: show-summary - params: - - name: pipelinerun-name - value: $(context.pipelineRun.name) - - name: git-url - value: $(tasks.clone-repository.results.url)?rev=$(tasks.clone-repository.results.commit) - - name: image-url - value: $(params.output-image) - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-summary:0.1@sha256:9e21e57456c026c15765db23b986e47fc1394fa5d4823d3038b697971dd1a2bd - name: summary - params: - - description: Source Repository URL - name: git-url - type: string - - default: "" - description: Revision of the Source Repository - name: revision - type: string - - description: Fully Qualified Output Image - name: output-image - type: string - - default: . - description: The path to your source code - name: path-context - type: string - - default: Dockerfile - description: Path to the Dockerfile - name: dockerfile - type: string - - default: "false" - description: Force rebuild image - name: rebuild - type: string - - default: "false" - description: Skip checks against built image - name: skip-checks - type: string - - default: "false" - description: Execute the build with network isolation - name: hermetic - type: string - - default: "" - description: Build dependencies to be prefetched by Cachi2 - name: prefetch-input - type: string - - default: "false" - description: Java build - name: java - type: string - - default: "" - description: Snyk Token Secret Name - name: snyk-secret - type: string - results: - - description: "" - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - description: "" - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - description: "" - name: CHAINS-GIT_URL - value: $(tasks.clone-repository.results.url) - - description: "" - name: CHAINS-GIT_COMMIT - value: $(tasks.clone-repository.results.commit) - - description: "" - name: JAVA_COMMUNITY_DEPENDENCIES - value: $(tasks.build-container.results.JAVA_COMMUNITY_DEPENDENCIES) - tasks: - - name: init - params: - - name: image-url - value: $(params.output-image) - - name: rebuild - value: $(params.rebuild) - - name: skip-checks - value: $(params.skip-checks) - - name: pipelinerun-name - value: $(context.pipelineRun.name) - - name: pipelinerun-uid - value: $(context.pipelineRun.uid) - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-init:0.1@sha256:8c06b307b7f74622503b80ff0b81ffda63129959f52f8ed8f753d8ab98f38411 - name: init - - name: clone-repository - params: - - name: url - value: $(params.git-url) - - name: revision - value: $(params.revision) - runAfter: - - init - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-git-clone:0.1@sha256:458f4853a01c3273bd76076ac1b015d5f901e70fb4b776f788b577adb25bf5f8 - name: git-clone - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: output - workspace: workspace - - name: basic-auth - workspace: git-auth - - name: prefetch-dependencies - params: - - name: input - value: $(params.prefetch-input) - runAfter: - - clone-repository - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-prefetch-dependencies:0.1@sha256:609f5c2a0d72dddb193a0fc2aef2390601172d09f093deadfb9827e28e8dea30 - name: prefetch-dependencies - when: - - input: $(params.hermetic) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace - - name: build-container - params: - - name: IMAGE - value: $(params.output-image) - - name: DOCKERFILE - value: $(params.dockerfile) - - name: CONTEXT - value: $(params.path-context) - - name: DOCKER_AUTH - value: $(tasks.init.results.container-registry-secret) - - name: HERMETIC - value: $(params.hermetic) - - name: PREFETCH_INPUT - value: $(params.prefetch-input) - runAfter: - - prefetch-dependencies - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-buildah:0.1@sha256:f4c4c211a7b8c859fb23d9b01faaf1a995a33b243476a617370e35f6438096e0 - name: buildah - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace - - name: sanity-inspect-image - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: DOCKER_AUTH - value: $(tasks.init.results.container-registry-secret) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sanity-inspect-image:0.1@sha256:b9ad0ed56be21c9e3c8e2e636275f92d887e57681c718cd36f117eb6fa547824 - name: sanity-inspect-image - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: source - workspace: workspace - - name: sanity-label-check - runAfter: - - sanity-inspect-image - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sanity-label-check:0.1@sha256:dd49667be76c81264a7fb28e3b43f72c527507e5691720c6262575255cb60689 - name: sanity-label-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - workspace: workspace - - name: sanity-optional-label-check - params: - - name: POLICY_NAMESPACE - value: optional_checks - runAfter: - - sanity-inspect-image - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sanity-label-check:0.1@sha256:dd49667be76c81264a7fb28e3b43f72c527507e5691720c6262575255cb60689 - name: sanity-label-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - workspace: workspace - - name: deprecated-base-image-check - params: - - name: BASE_IMAGES_DIGESTS - value: $(tasks.build-container.results.BASE_IMAGES_DIGESTS) - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-deprecated-image-check:0.2@sha256:bf1a1cad85bb896e920f0f7ff5dda2f885b76f2617934f72e7954565cd50df49 - name: deprecated-image-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: test-ws - workspace: workspace - - name: clair-scan - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - - name: docker-auth - value: $(tasks.init.results.container-registry-secret) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-clair-scan:0.1@sha256:1b4951e91fdfb3188d459d0abac411a6364da5cb135e81fb4a84bbd782bb545d - name: clair-scan - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: sast-snyk-check - params: - - name: SNYK_SECRET - value: $(params.snyk-secret) - runAfter: - - clone-repository - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sast-snyk-check:0.1@sha256:58f288a86ae7e1a2fff416d11720521effcf8e9b410355080a2b8a9bb8ae587c - name: sast-snyk-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - input: $(params.snyk-secret) - operator: notin - values: - - "" - workspaces: - - name: workspace - workspace: workspace - - name: clamav-scan - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - - name: docker-auth - value: $(tasks.init.results.container-registry-secret) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-clamav-scan:0.1@sha256:2c8dbe8aa7c0fa126a9c84e7590c4e901bcfeec6dde4ccbffda4c493cefb43ed - name: clamav-scan - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: sbom-json-check - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sbom-json-check:0.1@sha256:9a232f343d6397bfaf9620b6e63ce6943e256ad30da93cf8e9de3ca63ada7717 - name: sbom-json-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - - name: git-auth - optional: true - workspaces: - - name: workspace - volumeClaimTemplate: - metadata: - creationTimestamp: null - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - status: {} - - name: git-auth - secret: - secretName: '{{ git_auth_secret }}' -status: {} diff --git a/.tekton/apicurio-registry-qnbk-push.yaml b/.tekton/apicurio-registry-qnbk-push.yaml deleted file mode 100644 index 723cba6c93..0000000000 --- a/.tekton/apicurio-registry-qnbk-push.yaml +++ /dev/null @@ -1,341 +0,0 @@ -apiVersion: tekton.dev/v1beta1 -kind: PipelineRun -metadata: - annotations: - build.appstudio.redhat.com/commit_sha: '{{revision}}' - build.appstudio.redhat.com/target_branch: '{{target_branch}}' - pipelinesascode.tekton.dev/max-keep-runs: "3" - pipelinesascode.tekton.dev/on-event: '[push]' - pipelinesascode.tekton.dev/on-target-branch: '[main,master]' - creationTimestamp: null - labels: - appstudio.openshift.io/application: apicurio-registry - appstudio.openshift.io/component: apicurio-registry-qnbk - pipelines.appstudio.openshift.io/type: build - name: apicurio-registry-qnbk-on-push - namespace: carnalca-srs-tenant -spec: - params: - - name: dockerfile - value: Dockerfile.jvm.staged - - name: git-url - value: '{{repo_url}}' - - name: output-image - value: quay.io/redhat-appstudio/user-workload:{{revision}} - - name: path-context - value: . - - name: revision - value: '{{revision}}' - pipelineSpec: - finally: - - name: show-summary - params: - - name: pipelinerun-name - value: $(context.pipelineRun.name) - - name: git-url - value: $(tasks.clone-repository.results.url)?rev=$(tasks.clone-repository.results.commit) - - name: image-url - value: $(params.output-image) - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-summary:0.1@sha256:9e21e57456c026c15765db23b986e47fc1394fa5d4823d3038b697971dd1a2bd - name: summary - params: - - description: Source Repository URL - name: git-url - type: string - - default: "" - description: Revision of the Source Repository - name: revision - type: string - - description: Fully Qualified Output Image - name: output-image - type: string - - default: . - description: The path to your source code - name: path-context - type: string - - default: Dockerfile - description: Path to the Dockerfile - name: dockerfile - type: string - - default: "false" - description: Force rebuild image - name: rebuild - type: string - - default: "false" - description: Skip checks against built image - name: skip-checks - type: string - - default: "false" - description: Execute the build with network isolation - name: hermetic - type: string - - default: "" - description: Build dependencies to be prefetched by Cachi2 - name: prefetch-input - type: string - - default: "false" - description: Java build - name: java - type: string - - default: "" - description: Snyk Token Secret Name - name: snyk-secret - type: string - results: - - description: "" - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - description: "" - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - description: "" - name: CHAINS-GIT_URL - value: $(tasks.clone-repository.results.url) - - description: "" - name: CHAINS-GIT_COMMIT - value: $(tasks.clone-repository.results.commit) - - description: "" - name: JAVA_COMMUNITY_DEPENDENCIES - value: $(tasks.build-container.results.JAVA_COMMUNITY_DEPENDENCIES) - tasks: - - name: init - params: - - name: image-url - value: $(params.output-image) - - name: rebuild - value: $(params.rebuild) - - name: skip-checks - value: $(params.skip-checks) - - name: pipelinerun-name - value: $(context.pipelineRun.name) - - name: pipelinerun-uid - value: $(context.pipelineRun.uid) - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-init:0.1@sha256:8c06b307b7f74622503b80ff0b81ffda63129959f52f8ed8f753d8ab98f38411 - name: init - - name: clone-repository - params: - - name: url - value: $(params.git-url) - - name: revision - value: $(params.revision) - runAfter: - - init - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-git-clone:0.1@sha256:458f4853a01c3273bd76076ac1b015d5f901e70fb4b776f788b577adb25bf5f8 - name: git-clone - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: output - workspace: workspace - - name: basic-auth - workspace: git-auth - - name: prefetch-dependencies - params: - - name: input - value: $(params.prefetch-input) - runAfter: - - clone-repository - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-prefetch-dependencies:0.1@sha256:609f5c2a0d72dddb193a0fc2aef2390601172d09f093deadfb9827e28e8dea30 - name: prefetch-dependencies - when: - - input: $(params.hermetic) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace - - name: build-container - params: - - name: IMAGE - value: $(params.output-image) - - name: DOCKERFILE - value: $(params.dockerfile) - - name: CONTEXT - value: $(params.path-context) - - name: DOCKER_AUTH - value: $(tasks.init.results.container-registry-secret) - - name: HERMETIC - value: $(params.hermetic) - - name: PREFETCH_INPUT - value: $(params.prefetch-input) - runAfter: - - prefetch-dependencies - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-buildah:0.1@sha256:f4c4c211a7b8c859fb23d9b01faaf1a995a33b243476a617370e35f6438096e0 - name: buildah - when: - - input: $(tasks.init.results.build) - operator: in - values: - - "true" - workspaces: - - name: source - workspace: workspace - - name: sanity-inspect-image - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: DOCKER_AUTH - value: $(tasks.init.results.container-registry-secret) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sanity-inspect-image:0.1@sha256:b9ad0ed56be21c9e3c8e2e636275f92d887e57681c718cd36f117eb6fa547824 - name: sanity-inspect-image - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: source - workspace: workspace - - name: sanity-label-check - runAfter: - - sanity-inspect-image - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sanity-label-check:0.1@sha256:dd49667be76c81264a7fb28e3b43f72c527507e5691720c6262575255cb60689 - name: sanity-label-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - workspace: workspace - - name: sanity-optional-label-check - params: - - name: POLICY_NAMESPACE - value: optional_checks - runAfter: - - sanity-inspect-image - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sanity-label-check:0.1@sha256:dd49667be76c81264a7fb28e3b43f72c527507e5691720c6262575255cb60689 - name: sanity-label-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - workspace: workspace - - name: deprecated-base-image-check - params: - - name: BASE_IMAGES_DIGESTS - value: $(tasks.build-container.results.BASE_IMAGES_DIGESTS) - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-deprecated-image-check:0.2@sha256:bf1a1cad85bb896e920f0f7ff5dda2f885b76f2617934f72e7954565cd50df49 - name: deprecated-image-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: test-ws - workspace: workspace - - name: clair-scan - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - - name: docker-auth - value: $(tasks.init.results.container-registry-secret) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-clair-scan:0.1@sha256:1b4951e91fdfb3188d459d0abac411a6364da5cb135e81fb4a84bbd782bb545d - name: clair-scan - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: sast-snyk-check - params: - - name: SNYK_SECRET - value: $(params.snyk-secret) - runAfter: - - clone-repository - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sast-snyk-check:0.1@sha256:58f288a86ae7e1a2fff416d11720521effcf8e9b410355080a2b8a9bb8ae587c - name: sast-snyk-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - input: $(params.snyk-secret) - operator: notin - values: - - "" - workspaces: - - name: workspace - workspace: workspace - - name: clamav-scan - params: - - name: image-digest - value: $(tasks.build-container.results.IMAGE_DIGEST) - - name: image-url - value: $(tasks.build-container.results.IMAGE_URL) - - name: docker-auth - value: $(tasks.init.results.container-registry-secret) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-clamav-scan:0.1@sha256:2c8dbe8aa7c0fa126a9c84e7590c4e901bcfeec6dde4ccbffda4c493cefb43ed - name: clamav-scan - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - - name: sbom-json-check - params: - - name: IMAGE_URL - value: $(tasks.build-container.results.IMAGE_URL) - - name: IMAGE_DIGEST - value: $(tasks.build-container.results.IMAGE_DIGEST) - runAfter: - - build-container - taskRef: - bundle: quay.io/redhat-appstudio-tekton-catalog/task-sbom-json-check:0.1@sha256:9a232f343d6397bfaf9620b6e63ce6943e256ad30da93cf8e9de3ca63ada7717 - name: sbom-json-check - when: - - input: $(params.skip-checks) - operator: in - values: - - "false" - workspaces: - - name: workspace - - name: git-auth - optional: true - workspaces: - - name: workspace - volumeClaimTemplate: - metadata: - creationTimestamp: null - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - status: {} - - name: git-auth - secret: - secretName: '{{ git_auth_secret }}' -status: {} diff --git a/Dockerfile.jvm.staged b/Dockerfile.jvm.staged index bb4da412da..bea85c4820 100644 --- a/Dockerfile.jvm.staged +++ b/Dockerfile.jvm.staged @@ -1,7 +1,10 @@ FROM registry.access.redhat.com/ubi8/openjdk-17:1.15 AS builder + WORKDIR /work COPY . . + USER 0 +RUN microdnf install unzip RUN mvn clean package -Pprod -Psql -DskipTests -DskipDocsGen FROM registry.access.redhat.com/ubi8/openjdk-17-runtime:1.13 diff --git a/Makefile b/Makefile index 4e06295b51..d21acdcd40 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,13 @@ DOCKER_BUILD_WORKSPACE ?= $(DOCKERFILE_LOCATION) # You can override these variables from the command line. IMAGE_REPO ?= docker.io +IMAGE_GROUP ?= apicurio IMAGE_TAG ?= latest IMAGE_PLATFORMS ?= linux/amd64,linux/arm64,linux/s390x,linux/ppc64le SKIP_TESTS ?= false INTEGRATION_TESTS_PROFILE ?= ci BUILD_FLAGS ?= +REGISTRY_IMAGE ?= # Colour Codes for help message @@ -42,6 +44,7 @@ help: @printf "$(BLUE)SKIP_TESTS$(NC) Skips Tests. The Default value is '$(SKIP_TESTS)'\n" @printf "$(BLUE)BUILD_FLAGS$(NC) Additional maven build flags. By Default, it doesn't pass any additional flags.\n" @printf "$(BLUE)IMAGE_REPO$(NC) Image Repository of the image. Default is '$(IMAGE_REPO)'\n" + @printf "$(BLUE)IMAGE_GROUP$(NC) Image Group of the image. Default is '$(IMAGE_GROUP)'\n" @printf "$(BLUE)IMAGE_TAG$(NC) Image tag. Default is '$(IMAGE_TAG)'\n" @printf "$(BLUE)IMAGE_PLATFORMS$(NC) Supported Platforms for Multi-arch Images. Default platforms are '$(IMAGE_PLATFORMS)'\n" @printf "$(BLUE)DOCKERFILE_LOCATION$(NC) Path to the dockerfile. Default is '$(DOCKERFILE_LOCATION)'\n" @@ -108,7 +111,7 @@ build-mem-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker build -f $(DOCKERFILE_LOCATION)/$(MEM_DOCKERFILE) -t $(IMAGE_REPO)/apicurio/apicurio-registry-mem:$(IMAGE_TAG) $(DOCKER_BUILD_WORKSPACE) + docker build -f $(DOCKERFILE_LOCATION)/$(MEM_DOCKERFILE) -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-mem:$(IMAGE_TAG) $(DOCKER_BUILD_WORKSPACE) .PHONY: push-mem-image ## Pushes docker image for 'in-memory' storage variant. Variables available for override [IMAGE_REPO, IMAGE_TAG] @@ -118,7 +121,7 @@ push-mem-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker push $(IMAGE_REPO)/apicurio/apicurio-registry-mem:$(IMAGE_TAG) + docker push $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-mem:$(IMAGE_TAG) .PHONY: build-mem-native-image ## Builds native docker image for 'mem' storage variant. Variables available for override [IMAGE_REPO, IMAGE_TAG] @@ -128,7 +131,16 @@ build-mem-native-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker build -f $(DOCKERFILE_LOCATION)/Dockerfile.native -t $(IMAGE_REPO)/apicurio/apicurio-registry-mem-native:$(IMAGE_TAG) app/ + docker build -f $(DOCKERFILE_LOCATION)/Dockerfile.native -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-mem-native:$(IMAGE_TAG) app/ + +.PHONY: build-mem-native-scratch-image ## Builds native docker image from scratch for 'mem' storage variant. Variables available for override [IMAGE_REPO, IMAGE_TAG] +build-mem-native-scratch-image: + @echo "------------------------------------------------------------------------" + @echo " Building Image For In-Memory Storage Variant (using Native Executable)" + @echo " Repository: $(IMAGE_REPO)" + @echo " Tag: $(IMAGE_TAG)" + @echo "------------------------------------------------------------------------" + docker build -f $(DOCKERFILE_LOCATION)/Dockerfile.native-scratch -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-mem-native-scratch:$(IMAGE_TAG) ./ .PHONY: build-mem-native-scratch-image ## Builds native docker image from scratch for 'mem' storage variant. Variables available for override [IMAGE_REPO, IMAGE_TAG] build-mem-native-scratch-image: @@ -147,7 +159,7 @@ push-mem-native-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker push $(IMAGE_REPO)/apicurio/apicurio-registry-mem-native:$(IMAGE_TAG) + docker push $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-mem-native:$(IMAGE_TAG) .PHONY: build-sql-image ## Builds docker image for 'sql' storage variant. Variables available for override [SQL_DOCKERFILE, IMAGE_REPO, IMAGE_TAG, DOCKER_BUILD_WORKSPACE] @@ -157,7 +169,7 @@ build-sql-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker build -f $(DOCKERFILE_LOCATION)/$(SQL_DOCKERFILE) -t $(IMAGE_REPO)/apicurio/apicurio-registry-sql:$(IMAGE_TAG) $(DOCKER_BUILD_WORKSPACE) + docker build -f $(DOCKERFILE_LOCATION)/$(SQL_DOCKERFILE) -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-sql:$(IMAGE_TAG) $(DOCKER_BUILD_WORKSPACE) .PHONY: push-sql-image ## Pushes docker image for 'sql' storage variant. Variables available for override [IMAGE_REPO, IMAGE_TAG] push-sql-image: @@ -166,7 +178,7 @@ push-sql-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker push $(IMAGE_REPO)/apicurio/apicurio-registry-sql:$(IMAGE_TAG) + docker push $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-sql:$(IMAGE_TAG) .PHONY: build-sql-native-image ## Builds native docker image for 'sql' storage variant. Variables available for override [IMAGE_REPO, IMAGE_TAG] build-sql-native-image: @@ -175,7 +187,7 @@ build-sql-native-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker build -f $(DOCKERFILE_LOCATION)/Dockerfile.native -t $(IMAGE_REPO)/apicurio/apicurio-registry-sql-native:$(IMAGE_TAG) storage/sql + docker build -f $(DOCKERFILE_LOCATION)/Dockerfile.native -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-sql-native:$(IMAGE_TAG) storage/sql .PHONY: push-sql-native-image ## Pushes native docker image for 'sql' storage variant. Variables available for override [IMAGE_REPO, IMAGE_TAG] push-sql-native-image: @@ -184,7 +196,7 @@ push-sql-native-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker push $(IMAGE_REPO)/apicurio/apicurio-registry-sql-native:$(IMAGE_TAG) + docker push $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-sql-native:$(IMAGE_TAG) .PHONY: build-mssql-image ## Builds docker image for 'mssql' storage variant. Variables available for override [MSSQL_DOCKERFILE, IMAGE_REPO, IMAGE_TAG, DOCKER_BUILD_WORKSPACE] build-mssql-image: @@ -193,7 +205,7 @@ build-mssql-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker build -f $(DOCKERFILE_LOCATION)/$(MSSQL_DOCKERFILE) -t $(IMAGE_REPO)/apicurio/apicurio-registry-mssql:$(IMAGE_TAG) $(DOCKER_BUILD_WORKSPACE) + docker build -f $(DOCKERFILE_LOCATION)/$(MSSQL_DOCKERFILE) -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-mssql:$(IMAGE_TAG) $(DOCKER_BUILD_WORKSPACE) .PHONY: push-mssql-image ## Pushes docker image for 'mssql' storage variant. Variables available for override [IMAGE_REPO, IMAGE_TAG] push-mssql-image: @@ -202,7 +214,7 @@ push-mssql-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker push $(IMAGE_REPO)/apicurio/apicurio-registry-mssql:$(IMAGE_TAG) + docker push $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-mssql:$(IMAGE_TAG) .PHONY: build-mysql-image ## Builds docker image for 'mysql' storage variant. Variables available for override [MYSQL_DOCKERFILE, IMAGE_REPO, IMAGE_TAG, DOCKER_BUILD_WORKSPACE] build-mysql-image: @@ -229,7 +241,7 @@ build-kafkasql-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker build -f $(DOCKERFILE_LOCATION)/$(KAFKASQL_DOCKERFILE) -t $(IMAGE_REPO)/apicurio/apicurio-registry-kafkasql:$(IMAGE_TAG) $(DOCKER_BUILD_WORKSPACE) + docker build -f $(DOCKERFILE_LOCATION)/$(KAFKASQL_DOCKERFILE) -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-kafkasql:$(IMAGE_TAG) $(DOCKER_BUILD_WORKSPACE) .PHONY: push-kafkasql-image ## Pushes docker image for 'kafkasql' storage variant. Variables available for override [IMAGE_REPO, IMAGE_TAG] push-kafkasql-image: @@ -238,7 +250,7 @@ push-kafkasql-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker push $(IMAGE_REPO)/apicurio/apicurio-registry-kafkasql:$(IMAGE_TAG) + docker push $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-kafkasql:$(IMAGE_TAG) .PHONY: build-kafkasql-native-image ## Builds native docker image for kafkasql storage variant. Variables available for override [IMAGE_REPO, IMAGE_TAG] build-kafkasql-native-image: @@ -247,7 +259,7 @@ build-kafkasql-native-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker build -f $(DOCKERFILE_LOCATION)/Dockerfile.native -t $(IMAGE_REPO)/apicurio/apicurio-registry-kafkasql-native:$(IMAGE_TAG) storage/kafkasql + docker build -f $(DOCKERFILE_LOCATION)/Dockerfile.native -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-kafkasql-native:$(IMAGE_TAG) storage/kafkasql .PHONY: push-kafkasql-native-image ## Pushes native docker image for 'kafkasql' storage variant. Variables available for override [IMAGE_REPO, IMAGE_TAG] push-kafkasql-native-image: @@ -256,7 +268,7 @@ push-kafkasql-native-image: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker push $(IMAGE_REPO)/apicurio/apicurio-registry-kafkasql-native:$(IMAGE_TAG) + docker push $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-kafkasql-native:$(IMAGE_TAG) .PHONY: build-all-images ## Builds all the Images. Variables available for override [IMAGE_REPO, IMAGE_TAG] build-all-images: build-mem-image build-sql-image build-mssql-image build-kafkasql-image build-mysql-image @@ -273,7 +285,7 @@ mem-multiarch-images: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker buildx build --push -f $(DOCKERFILE_LOCATION)/$(MEM_DOCKERFILE) -t $(IMAGE_REPO)/apicurio/apicurio-registry-mem:$(IMAGE_TAG) --platform $(IMAGE_PLATFORMS) $(DOCKER_BUILD_WORKSPACE) + docker buildx build --push -f $(DOCKERFILE_LOCATION)/$(MEM_DOCKERFILE) -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-mem:$(IMAGE_TAG) --platform $(IMAGE_PLATFORMS) $(DOCKER_BUILD_WORKSPACE) .PHONY: sql-multiarch-images ## Builds and pushes multi-arch images for 'sql' storage variant. Variables available for override [SQL_DOCKERFILE, IMAGE_REPO, IMAGE_TAG, DOCKER_BUILD_WORKSPACE] sql-multiarch-images: @@ -283,7 +295,7 @@ sql-multiarch-images: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker buildx build --push -f $(DOCKERFILE_LOCATION)/$(SQL_DOCKERFILE) -t $(IMAGE_REPO)/apicurio/apicurio-registry-sql:$(IMAGE_TAG) --platform $(IMAGE_PLATFORMS) $(DOCKER_BUILD_WORKSPACE) + docker buildx build --push -f $(DOCKERFILE_LOCATION)/$(SQL_DOCKERFILE) -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-sql:$(IMAGE_TAG) --platform $(IMAGE_PLATFORMS) $(DOCKER_BUILD_WORKSPACE) .PHONY: mssql-multiarch-images ## Builds and pushes multi-arch images for 'mssql' storage variant. Variables available for override [MSSQL_DOCKERFILE, IMAGE_REPO, IMAGE_TAG, DOCKER_BUILD_WORKSPACE] mssql-multiarch-images: @@ -293,7 +305,7 @@ mssql-multiarch-images: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker buildx build --push -f $(DOCKERFILE_LOCATION)/$(MSSQL_DOCKERFILE) -t $(IMAGE_REPO)/apicurio/apicurio-registry-mssql:$(IMAGE_TAG) --platform $(IMAGE_PLATFORMS) $(DOCKER_BUILD_WORKSPACE) + docker buildx build --push -f $(DOCKERFILE_LOCATION)/$(MSSQL_DOCKERFILE) -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-mssql:$(IMAGE_TAG) --platform $(IMAGE_PLATFORMS) $(DOCKER_BUILD_WORKSPACE) .PHONY: mysql-multiarch-images ## Builds and pushes multi-arch images for 'mysql' storage variant. Variables available for override [MYSQL_DOCKERFILE, IMAGE_REPO, IMAGE_TAG, DOCKER_BUILD_WORKSPACE] mysql-multiarch-images: @@ -313,7 +325,17 @@ kafkasql-multiarch-images: @echo " Repository: $(IMAGE_REPO)" @echo " Tag: $(IMAGE_TAG)" @echo "------------------------------------------------------------------------" - docker buildx build --push -f $(DOCKERFILE_LOCATION)/$(KAFKASQL_DOCKERFILE) -t $(IMAGE_REPO)/apicurio/apicurio-registry-kafkasql:$(IMAGE_TAG) --platform $(IMAGE_PLATFORMS) $(DOCKER_BUILD_WORKSPACE) + docker buildx build --push -f $(DOCKERFILE_LOCATION)/$(KAFKASQL_DOCKERFILE) -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-kafkasql:$(IMAGE_TAG) --platform $(IMAGE_PLATFORMS) $(DOCKER_BUILD_WORKSPACE) + +.PHONY: mem-native-scratch-image ## Builds and pushes multi-arch images for mem storage variant based on scratch. Variables available for override [MEM_SCRATCH_DOCKERFILE, IMAGE_REPO, IMAGE_TAG, DOCKER_BUILD_WORKSPACE] +mem-native-scratch-image: + @echo "------------------------------------------------------------------------" + @echo " Building Multi-arch Images For Mem Storage Variant on Scratch" + @echo " Supported Platforms: $(IMAGE_PLATFORMS)" + @echo " Repository: $(IMAGE_REPO)" + @echo " Tag: $(IMAGE_TAG)" + @echo "------------------------------------------------------------------------" + docker buildx build --push -f $(DOCKERFILE_LOCATION)/$(MEM_SCRATCH_DOCKERFILE) -t $(IMAGE_REPO)/$(IMAGE_GROUP)/apicurio-registry-mem-native-scratch:$(IMAGE_TAG) --platform $(IMAGE_PLATFORMS) $(DOCKER_BUILD_WORKSPACE) .PHONY: mem-native-scratch-image ## Builds and pushes multi-arch images for mem storage variant based on scratch. Variables available for override [MEM_SCRATCH_DOCKERFILE, IMAGE_REPO, IMAGE_TAG, DOCKER_BUILD_WORKSPACE] mem-native-scratch-image: @@ -326,8 +348,7 @@ mem-native-scratch-image: docker buildx build --push -f $(DOCKERFILE_LOCATION)/$(MEM_SCRATCH_DOCKERFILE) -t $(IMAGE_REPO)/apicurio/apicurio-registry-mem-native-scratch:$(IMAGE_TAG) --platform $(IMAGE_PLATFORMS) $(DOCKER_BUILD_WORKSPACE) .PHONY: multiarch-registry-images ## Builds and pushes multi-arch registry images for all variants. Variables available for override [IMAGE_REPO, IMAGE_TAG] -multiarch-registry-images: mem-multiarch-images sql-multiarch-images mssql-multiarch-images kafkasql-multiarch-images mysql-multiarch-images - +multiarch-registry-images: mem-multiarch-images sql-multiarch-images mssql-multiarch-images kafkasql-multiarch-images mem-native-scratch-image mysql-multiarch-images .PHONY: pr-check ## Builds and runs basic tests for multitenant registry pipelines @@ -335,7 +356,7 @@ pr-check: CURRENT_ENV=mas mvn clean install -Pno-docker -Dskip.npm -Pprod -Psql -am -pl storage/sql \ -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false ./scripts/clean-postgres.sh - CURRENT_ENV=mas NO_DOCKER=true mvn verify -Pintegration-tests -Psql -am -pl integration-tests/testsuite \ + CURRENT_ENV=mas NO_DOCKER=true mvn verify -Pintegration-tests -Psql -am -pl integration-tests \ -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false .PHONY: build-project ## Builds the components for multitenant registry pipelines @@ -345,178 +366,147 @@ build-project: # build everything without running tests in order to be able to build container images CURRENT_ENV=mas mvn clean install -Pprod -Pno-docker -Dskip.npm -Psql -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false -DskipTests -.PHONY: build-integration-tests-multitenancy ## Builds Tenant manager -build-integration-tests-multitenancy: - @echo "----------------------------------------------------------------------" - @echo " Building Tenant Manager for Integration Tests " - @echo "----------------------------------------------------------------------" - rm -rf multitenancy - git clone https://github.com/Apicurio/apicurio-tenant-manager.git --branch="main" --depth 1 multitenancy - ( cd multitenancy && .././mvnw clean install --no-transfer-progress -DskipTests=true ) -.PHONY: build-integration-tests-common ## Builds integration-tests-common -build-integration-tests-common: - @echo "----------------------------------------------------------------------" - @echo " Building Integration Tests Common " - @echo "----------------------------------------------------------------------" - ./mvnw -T 1.5C package install --no-transfer-progress -Pintegration-tests -pl integration-tests/integration-tests-common - -.PHONY: run-ui-tests ## Runs sql integration tests -run-ui-tests: build-integration-tests-common +.PHONY: run-ui-tests ## Runs ui e2e tests +run-ui-tests: @echo "----------------------------------------------------------------------" @echo " Running UI Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pui -Pinmemory -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false + ./mvnw -am verify --no-transfer-progress -Pintegration-tests -Pui -Premote-sql -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false -.PHONY: run-sql-integration-tests ## Runs sql integration tests -run-sql-integration-tests: build-integration-tests-common - @echo "----------------------------------------------------------------------" - @echo " Running Sql Integration Tests " - @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -P$(INTEGRATION_TESTS_PROFILE) -Psql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-sql-clustered-integration-tests ## Runs sql clustered integration tests -run-sql-clustered-integration-tests: build-integration-tests-common - @echo "----------------------------------------------------------------------" - @echo " Running Sql clustered Integration Tests " - @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pclustered -Psql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress +############################################# In-Memory Integration Tests ######################################################################### + -.PHONY: run-mssql-integration-tests ## Runs mssql integration tests -run-mssql-integration-tests: build-integration-tests-common - @echo "----------------------------------------------------------------------" - @echo " Running SQL Server Integration Tests " - @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -P$(INTEGRATION_TESTS_PROFILE) -Pmssql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-mssql-clustered-integration-tests ## Runs mssql clustered integration tests -run-mssql-clustered-integration-tests: build-integration-tests-common - @echo "----------------------------------------------------------------------" - @echo " Running SQL Server clustered Integration Tests " - @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pclustered -Pmssql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-mysql-integration-tests ## Runs mysql integration tests -run-mysql-integration-tests: build-integration-tests-common +.PHONY: run-in-memory-integration-tests ## Runs mem e2e tests +run-in-memory-integration-tests: @echo "----------------------------------------------------------------------" - @echo " Running SQL Server Integration Tests " + @echo " Running In Memory Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -P$(INTEGRATION_TESTS_PROFILE) -Pmysql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests -P$(INTEGRATION_TESTS_PROFILE) $(REGISTRY_IMAGE) -Premote-mem -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress + -.PHONY: run-mysql-clustered-integration-tests ## Runs mysql clustered integration tests -run-mysql-clustered-integration-tests: build-integration-tests-common +.PHONY: run-in-memory-auth-tests ## Runs mem auth integration tests +run-in-memory-auth-tests: @echo "----------------------------------------------------------------------" - @echo " Running SQL Server clustered Integration Tests " + @echo " Running In Memory Auth Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pclustered -Pmysql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests -Pauth $(REGISTRY_IMAGE) -Premote-mem -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-kafkasql-integration-tests ## Runs kafkasql integration tests -run-kafkasql-integration-tests: build-integration-tests-common + +############################################# SQL Integration Tests ######################################################################### + + +.PHONY: run-sql-integration-tests ## Runs sql e2e tests +run-sql-integration-tests: @echo "----------------------------------------------------------------------" - @echo " Running KafkaSql Integration Tests " + @echo " Running Sql Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -P$(INTEGRATION_TESTS_PROFILE) -Pkafkasql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests -P$(INTEGRATION_TESTS_PROFILE) $(REGISTRY_IMAGE) -Premote-sql -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-kafkasql-clustered-integration-tests ## Runs kafkasql clustered integration tests -run-kafkasql-clustered-integration-tests: build-integration-tests-common +.PHONY: run-sql-upgrade-tests ## Runs sql e2e tests +run-sql-upgrade-tests: @echo "----------------------------------------------------------------------" - @echo " Running KafkaSql clustered Integration Tests " + @echo " Running Sql Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pclustered -Pkafkasql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests -Psqlit $(REGISTRY_IMAGE) -Premote-sql -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-multitenancy-integration-tests ## Runs multitenancy integration tests -run-multitenancy-integration-tests: build-integration-tests-common +.PHONY: run-sql-auth-tests ## Runs sql auth integration tests +run-sql-auth-tests: @echo "----------------------------------------------------------------------" - @echo " Running Multitenancy Integration Tests " + @echo " Running SQL Auth Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pmultitenancy -Psql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false + ./mvnw verify -am --no-transfer-progress -Pintegration-tests -Pauth $(REGISTRY_IMAGE) -Premote-sql -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress .PHONY: run-sql-migration-integration-tests ## Runs sql migration integration tests -run-sql-migration-integration-tests: build-integration-tests-common +run-sql-migration-integration-tests: @echo "----------------------------------------------------------------------" @echo " Running SQL Migration Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pmigration -Psql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests $(REGISTRY_IMAGE) -Pmigration -Premote-sql -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-mssql-migration-integration-tests ## Runs mssql migration integration tests -run-mssql-migration-integration-tests: build-integration-tests-common +.PHONY: run-sql-multitenancy-integration-tests ## Runs multitenancy integration tests +run-sql-multitenancy-integration-tests: @echo "----------------------------------------------------------------------" - @echo " Running SQL Server Migration Integration Tests " + @echo " Running Multitenancy Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pmigration -mssql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests $(REGISTRY_IMAGE) -Pmultitenancy -Premote-sql -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress -DtrimStackTrace=false -.PHONY: run-mysql-migration-integration-tests ## Runs sql migration integration tests -run-mysql-migration-integration-tests: build-integration-tests-common - @echo "----------------------------------------------------------------------" - @echo " Running MySQL Migration Integration Tests " - @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pmigration -Pmysql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-kafkasql-migration-integration-tests ## Runs kafkasql migration integration tests -run-kafkasql-migration-integration-tests: build-integration-tests-common +############################################# KafkaSql Integration Tests ######################################################################### + + +.PHONY: run-kafkasql-integration-tests ## Runs kafkasql integration tests +run-kafkasql-integration-tests: @echo "----------------------------------------------------------------------" - @echo " Running KafkaSQL Migration Integration Tests " + @echo " Running KafkaSql Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pmigration -Pkafkasql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests $(REGISTRY_IMAGE) -P$(INTEGRATION_TESTS_PROFILE) -Premote-kafka -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-sql-auth-integration-tests ## Runs sql auth integration tests -run-sql-auth-integration-tests: build-integration-tests-common +.PHONY: run-kafkasql-upgrade-tests ## Runs sql e2e tests +run-kafkasql-upgrade-tests : @echo "----------------------------------------------------------------------" - @echo " Running SQL Auth Integration Tests " + @echo " Running KafkaSql Upgrade Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pauth -Psql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests $(REGISTRY_IMAGE) -Pkafkasqlit -Premote-kafka -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-mssql-auth-integration-tests ## Runs mssql auth integration tests -run-mssql-auth-integration-tests: build-integration-tests-common +.PHONY: run-kafkasql-migration-integration-tests ## Runs kafkasql migration integration tests +run-kafkasql-migration-integration-tests: @echo "----------------------------------------------------------------------" - @echo " Running SQL Server Auth Integration Tests " + @echo " Running KafkaSQL Migration Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pauth -mssql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests $(REGISTRY_IMAGE) -Pmigration -Premote-kafka -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-mysql-auth-integration-tests ## Runs mysql auth integration tests -run-mysql-auth-integration-tests: build-integration-tests-common +.PHONY: run-kafkasql-auth-tests ## Runs kafkasql auth integration tests +run-kafkasql-auth-tests: @echo "----------------------------------------------------------------------" - @echo " Running MySQL Auth Integration Tests " + @echo " Running KafkaSQL Auth Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pauth -Pmysql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests $(REGISTRY_IMAGE) -Pauth -Premote-kafka -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress + +############################################# MSSQL Integration Tests ######################################################################### -.PHONY: run-kafkasql-auth-integration-tests ## Runs kafkasql auth integration tests -run-kafkasql-auth-integration-tests: build-integration-tests-common +.PHONY: run-mssql-integration-tests ## Runs mssql integration tests +run-mssql-integration-tests: @echo "----------------------------------------------------------------------" - @echo " Running KafkaSQL Auth Integration Tests " + @echo " Running SQL Server Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -Pauth -Pkafkasql -pl integration-tests/testsuite -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests $(REGISTRY_IMAGE) -P$(INTEGRATION_TESTS_PROFILE) -Pmssql -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-sql-legacy-tests ## Runs sql legacy tests -run-sql-legacy-tests: build-integration-tests-common +.PHONY: run-mssql-clustered-integration-tests ## Runs mssql clustered integration tests +run-mssql-clustered-integration-tests: @echo "----------------------------------------------------------------------" - @echo " Running SQL Legacy Tests " + @echo " Running SQL Server clustered Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -P$(INTEGRATION_TESTS_PROFILE) -Psql -pl integration-tests/legacy-tests -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests $(REGISTRY_IMAGE) -Pclustered -Pmssql -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress .PHONY: run-mssql-legacy-tests ## Runs mssql legacy tests -run-mssql-legacy-tests: build-integration-tests-common +run-mssql-legacy-tests: @echo "----------------------------------------------------------------------" @echo " Running SQL Server Legacy Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -P$(INTEGRATION_TESTS_PROFILE) -mssql -pl integration-tests/legacy-tests -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests $(REGISTRY_IMAGE) -P$(INTEGRATION_TESTS_PROFILE) -mssql -pl integration-tests/legacy-tests -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-mysql-legacy-tests ## Runs mysql legacy tests -run-mysql-legacy-tests: build-integration-tests-common +.PHONY: run-mssql-auth-integration-tests ## Runs mssql auth integration tests +run-mssql-auth-integration-tests: @echo "----------------------------------------------------------------------" - @echo " Running MySQL Legacy Tests " + @echo " Running SQL Server Auth Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -P$(INTEGRATION_TESTS_PROFILE) -Pmysql -pl integration-tests/legacy-tests -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests $(REGISTRY_IMAGE) -Pauth -mssql -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress -.PHONY: run-kafkasql-legacy-tests ## Runs kafkasql legacy tests -run-kafkasql-legacy-tests: build-integration-tests-common +.PHONY: run-mssql-migration-integration-tests ## Runs mssql migration integration tests +run-mssql-migration-integration-tests: @echo "----------------------------------------------------------------------" - @echo " Running KafkaSQL Legacy Tests " + @echo " Running SQL Server Migration Integration Tests " @echo "----------------------------------------------------------------------" - ./mvnw verify --no-transfer-progress -Pintegration-tests -P$(INTEGRATION_TESTS_PROFILE) -Pkafkasql -pl integration-tests/legacy-tests -Dmaven.javadoc.skip=true --no-transfer-progress + ./mvnw verify -am --no-transfer-progress -Pintegration-tests $(REGISTRY_IMAGE) -Pmigration -mssql -pl integration-tests -Dmaven.javadoc.skip=true --no-transfer-progress + + .PHONY: integration-tests ## Runs all integration tests [SKIP_TESTS, BUILD_FLAGS] -integration-tests: build-all build-integration-tests-common run-ui-tests run-sql-integration-tests run-sql-clustered-integration-tests run-mssql-integration-tests run-mssql-clustered-integration-tests run-mysql-integration-tests run-mysql-clustered-integration-tests run-kafkasql-integration-tests run-kafkasql-clustered-integration-tests run-multitenancy-integration-tests run-sql-migration-integration-tests run-mssql-migration-integration-tests run-kafkasql-migration-integration-tests run-sql-auth-integration-tests run-mssql-auth-integration-tests run-kafkasql-auth-integration-tests run-sql-legacy-tests run-mssql-legacy-tests run-kafkasql-legacy-tests +integration-tests: build-all run-ui-tests run-sql-integration-tests run-mssql-integration-tests run-mssql-clustered-integration-tests run-kafkasql-integration-tests run-multitenancy-integration-tests run-sql-migration-integration-tests run-mssql-migration-integration-tests run-kafkasql-migration-integration-tests run-sql-auth-integration-tests run-mssql-auth-integration-tests run-kafkasql-auth-integration-tests run-sql-legacy-tests run-mssql-legacy-tests run-kafkasql-legacy-tests # Please declare your targets as .PHONY in the format shown below, so that the 'make help' parses the information correctly. # diff --git a/TESTING.md b/TESTING.md index 22d773a750..0596bd948d 100644 --- a/TESTING.md +++ b/TESTING.md @@ -19,47 +19,42 @@ make build-all ## Integration Tests -Located under `integration-tests`. We have a set of tests for the current version of Apicurio Registry located in `integration-tests/testsuite` and another set of tests used to test the compatibility of old clients with the current implementation of Apicurio Registry old API, this "legacy" compatibility tests are located in `integration-tests/legacy-tests` and are only executed in GitHub Actions as part of our [CI](.github/workflows/integration-tests.yaml). +Located under `integration-tests`. We have a set of tests for the current version of Apicurio Registry that are run in [CI](.github/workflows/integration-tests.yaml). This set of tests are mainly designed to work in two different modes: -+ Apicurio Registry and required infrastructure deployed locally (processes, docker containers, mocks, ...) by the testsuite ++ Apicurio Registry and required infrastructure deployed locally (processes, docker containers, mocks, ...) by the testsuite. This uses the @QuarkusIntegrationTest annotation to run the required infrastructure. This is useful for running the tests in the IDE for debugging purposes. It also + Apicurio Registry and required infrasturcture are deployed externally and connection details have to be provided in order to execute the tests. ### ITs with local infrastructure -This is the normal mode used when you execute the testsuite. Because Apicurio Registry supports various storage backends and various deployment time configurations(such as multitenancy, authentication, clustering,...) this tests deploy different components depending on the configuration provided. +This is the normal mode used when you execute the testsuite. Because Apicurio Registry supports various storage backends and various deployment time configurations(such as multitenancy, authentication,...) this tests deploy different components depending on the test executed. This is achieved using Quarkus profiles. For example, when a multitenancy test is executed, a tenant-manager instance will be deployed. + +When running from the terminal, the configuration is provided via maven profiles. You can find all the available maven profiles [here](integration-tests/pom.xml) -The configuration is provided via maven profiles. You can find all the available maven profiles [here](integration-tests/testsuite/pom.xml) When executing the testsuite you normally provide two profiles: -+ test profile (which determines the tests that will be executed), some options are acceptance , multitenancy ,... -+ storage variant to test (which determines the storage backend that will be deployed, and therefore tested), the available options are: inmemory , sql, mssql, mysql, kafkasql. ++ test profile (which determines the tests that will be executed), with the following options: all, ci, smoke, serdes, ui, acceptance, auth, multitenancy, migration, sqlit, kafkasqlit. ++ storage variant to test (which determines the storage backend that will be deployed, and therefore tested), the available options for running the test locally are: local-mem , local-sql, local-mssql , local-kafka. -You can find multiple examples of how to run the testsuite in this mode in our [Github Actions Workflows](.github/workflows/integration-tests.yaml) +As you might expect, this testsuite mode depends on the rest of the project to be built first, in order to have the application jars/images available or the serdes module to be available as well. -As you may have noticed in our Github Actions Workflows, this testsuite mode depends on the rest of the project to be built first, in order to have the application jars available or the serdes module to be available as well. - -Also we have several make goals for running the tests i.e: -``` -make run-sql-integration-tests -``` +For running the smoke tests group using the sql variant, first run `mvn clean install -Psql` (this command will execute the unit tests for the sql variant, you can skip them using `-DskipTests`) and then run mvn verify -Plocal-sql -Psmoke. ## ITs with infrastructure in Kubernetes/Openshift -The Integration Tests testsuite can be configured to expect Apicurio Registry, and it's required infrastructure, to be deployed externally. That can be Kubernetes/Openshift or somewhere else. +The Integration Tests testsuite can be configured to expect Apicurio Registry, and it's required infrastructure, to be deployed externally in a K8s cluster. -The testsuite accepts environment variables to configure this mode. The environment variables used are: -+ EXTERNAL_REGISTRY , boolean value to enable/disable this mode, false by default. -+ REGISTRY_HOST , host to access externally deployed Apicurio Registry -+ REGISTRY_PORT , port to access externally deployed Apicurio Registry +In this mode, the testsuite expects your kubeconfig file to be already configured pointing to the cluster that will be used for testing. The tests that will be executed are determined using the maven profile just as when running locally. +As for the storage variant, it will be determined using a similar approach as the one used for the local execution but with different names: remote-mem, remote-sql, remote-mssql, remote-kafka. -For this purpose the best example can be found in our [Github Actions Workflows](.github/workflows/kubernetes-tests.yaml) +We have make goals for all the deployment variants and you have examples for all the execution possibilities in our [Github Actions Workflows](.github/workflows/integration-tests.yaml) -We have another project in order to run Kubernetes/Openshift tests that combine testing for [Apicurio Registry Operator](https://github.com/Apicurio/apicurio-registry-operator) and functionality testing for [Apicurio Registry](https://github.com/Apicurio/apicurio-registry-operator). It is a [new testsuite](https://github.com/Apicurio/apicurio-registry-k8s-tests-e2e) that internally can execute the java Integration Tests that can be found in this repository. We often refer to this testsuite as the e2e testsuite. -## Integration Tests testsuite internall details +## Integration Tests testsuite internal details The Integration Tests testsuite is written in Java and we use JUnit 5 . -The main entry point for the testsuite is this class [`integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryDeploymentManager.java`](integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryFacade.java) . In that class we implemented our own custom JUnit extension that allows us to easily deploy several configurations for Apicurio Registry and required infrastructure depending on configuration parameters. The actual logic for all the deployment configurations is in this class [`integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryFacade.java`](integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryFacade.java) +The main entry point for the testsuite is this class [`integration-tests/src/test/java/io/apicurio/deployment/RegistryDeploymentManager.java`](integration-tests/src/test/java/io/apicurio/deployment/RegistryDeploymentManager.java). + +This is the class that, when running in remote mode, is responsible for deploying all the required infrastructure in K8s and making sure it remains available during the tests execution. diff --git a/app/pom.xml b/app/pom.xml index ea49bf6c67..db98744213 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -5,7 +5,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml @@ -273,11 +273,6 @@ test test-jar - - io.strimzi - strimzi-test-container - test - diff --git a/app/src/main/resources/application.properties b/app/src/main/resources/application.properties index 5de95672cf..b86e1a9094 100644 --- a/app/src/main/resources/application.properties +++ b/app/src/main/resources/application.properties @@ -1,5 +1,6 @@ # Global Properties -quarkus.native.resources.includes=io/apicurio/registry/storage/impl/sql/h2.ddl +quarkus.native.resources.includes=io/apicurio/registry/storage/impl/sql/h2.ddl,i18n/*.properties + ## Additional index dependencies quarkus.index-dependency.jaxrs.group-id=jakarta.ws.rs diff --git a/app/src/test/java/io/apicurio/registry/events/KafkaEventsTest.java b/app/src/test/java/io/apicurio/registry/events/KafkaEventsTest.java index a3aeeafb7b..e338070ea8 100644 --- a/app/src/test/java/io/apicurio/registry/events/KafkaEventsTest.java +++ b/app/src/test/java/io/apicurio/registry/events/KafkaEventsTest.java @@ -27,7 +27,6 @@ import java.util.Properties; import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; import org.apache.kafka.clients.CommonClientConfigs; @@ -41,7 +40,6 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; -import org.rnorth.ducttape.unreliables.Unreliables; import io.apicurio.registry.AbstractResourceTestBase; import io.apicurio.registry.events.dto.RegistryEventType; import io.apicurio.registry.types.ArtifactType; @@ -62,7 +60,7 @@ public class KafkaEventsTest extends AbstractResourceTestBase { @Test @Timeout(value = 60, unit = TimeUnit.SECONDS) - public void testKafkaEvents() throws TimeoutException { + public void testKafkaEvents() throws Exception { Consumer kafkaConsumer = createConsumer( Serdes.UUID().deserializer().getClass().getName(), @@ -89,7 +87,7 @@ public void testKafkaEvents() throws TimeoutException { List> allRecords = new ArrayList<>(); - Unreliables.retryUntilTrue(40, TimeUnit.SECONDS, () -> { + TestUtils.retry( () -> { kafkaConsumer.poll(Duration.ofMillis(50)) .iterator() .forEachRemaining(allRecords::add); @@ -103,10 +101,6 @@ public void testKafkaEvents() throws TimeoutException { }) .collect(Collectors.toList()); -// assertLinesMatch( -// Arrays.asList(RegistryEventType.ARTIFACT_CREATED.cloudEventType(), RegistryEventType.ARTIFACT_UPDATED.cloudEventType()), -// events); - assertTrue( events.containsAll(Arrays.asList(RegistryEventType.ARTIFACT_CREATED.cloudEventType(), RegistryEventType.ARTIFACT_UPDATED.cloudEventType())) ); diff --git a/app/src/test/java/io/apicurio/registry/noprofile/ccompat/rest/v6/ConfluentCompatApiTest.java b/app/src/test/java/io/apicurio/registry/noprofile/ccompat/rest/v6/ConfluentCompatApiTest.java deleted file mode 100644 index 75d2b972ae..0000000000 --- a/app/src/test/java/io/apicurio/registry/noprofile/ccompat/rest/v6/ConfluentCompatApiTest.java +++ /dev/null @@ -1,859 +0,0 @@ -/* - * Copyright 2022 Red Hat - * - * Licensed 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 io.apicurio.registry.noprofile.ccompat.rest.v6; - -import com.fasterxml.jackson.databind.ObjectMapper; -import io.apicurio.registry.AbstractResourceTestBase; -import io.apicurio.registry.ccompat.dto.CompatibilityLevelDto; -import io.apicurio.registry.ccompat.dto.CompatibilityLevelParamDto; -import io.apicurio.registry.ccompat.dto.SchemaContent; -import io.apicurio.registry.ccompat.rest.ContentTypes; -import io.apicurio.registry.rest.v1.beans.UpdateState; -import io.apicurio.registry.rest.v2.beans.VersionSearchResults; -import io.apicurio.registry.types.ArtifactState; -import io.apicurio.registry.types.RuleType; -import io.apicurio.registry.utils.tests.TestUtils; -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.path.json.JsonPath; -import io.restassured.response.ResponseBodyExtractionOptions; -import io.restassured.response.ValidatableResponse; -import org.hamcrest.Matchers; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.List; - -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.CONFIG_BACKWARD; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.JSON_SCHEMA_SIMPLE_WRAPPED_WITH_TYPE; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.PROTOBUF_SCHEMA_SIMPLE_WRAPPED_WITH_TYPE; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.SCHEMA_1_WRAPPED; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.SCHEMA_2_WRAPPED; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.SCHEMA_3_WRAPPED_TEMPLATE; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.SCHEMA_INVALID_WRAPPED; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.SCHEMA_SIMPLE; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.SCHEMA_SIMPLE_DEFAULT_QUOTED; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.SCHEMA_SIMPLE_JSON_QUOTED; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.SCHEMA_SIMPLE_WRAPPED; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.SCHEMA_SIMPLE_WRAPPED_WITH_DEFAULT_QUOTED; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.SCHEMA_SIMPLE_WRAPPED_WITH_JSON_DEFAULT; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.SCHEMA_SIMPLE_WRAPPED_WITH_TYPE; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.V6_BASE_PATH; -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.VALID_AVRO_SCHEMA; -import static io.restassured.RestAssured.given; -import static org.hamcrest.Matchers.anything; -import static org.hamcrest.Matchers.equalTo; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * Tests that the REST API exposed at endpoint "/ccompat/v6" follows the - * Confluent API specification, - * unless otherwise stated. - * - * @author Jakub Senko m@jsenko.net - */ -@QuarkusTest -public class ConfluentCompatApiTest extends AbstractResourceTestBase { - - - @NotNull - public String getBasePath() { - return V6_BASE_PATH; - } - - /** - * Endpoint: /subjects/(string: subject)/versions - */ - @Test - public void testCreateSubject() throws Exception { - final String SUBJECT = "subject1"; - // POST - ValidatableResponse res = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_SIMPLE_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))); - /*int id = */ - res.extract().jsonPath().getInt("id"); - - this.waitForArtifact(SUBJECT); - - // Verify - given() - .when() - .get("/registry/v1/artifacts/{artifactId}", SUBJECT) - .then() - .statusCode(200) - .body("", equalTo(new JsonPath(SCHEMA_SIMPLE).getMap(""))); - - // Verify - given() - .when() - .get(getBasePath() + "/subjects/").then().body(Matchers.containsString("subject1")); - } - - /** - * Endpoint: /subjects/(string: subject)/versions - */ - @Test - public void testDefaultQuoted() throws Exception { - final String SUBJECT = "subject1"; - // POST - ValidatableResponse res = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_SIMPLE_WRAPPED_WITH_DEFAULT_QUOTED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))); - - int id = res.extract().jsonPath().getInt("id"); - - this.waitForArtifact(SUBJECT); - - // Verify - given() - .when() - .get("/registry/v1/artifacts/{artifactId}", SUBJECT) - .then() - .statusCode(200) - .body("", equalTo(new JsonPath(SCHEMA_SIMPLE_DEFAULT_QUOTED).getMap(""))); - - // Verify - given() - .when() - .get(getBasePath() + "/schemas/ids/{id}", id) - .then() - .statusCode(200) - .body(Matchers.containsString("EloquaContactRecordData")); - } - - @Test - public void testJsonDefault() throws Exception { - final String SUBJECT = "subject1"; - // POST - ValidatableResponse res = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_SIMPLE_WRAPPED_WITH_JSON_DEFAULT) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))); - - int id = res.extract().jsonPath().getInt("id"); - - this.waitForArtifact(SUBJECT); - - // Verify - given() - .when() - .get("/registry/v1/artifacts/{artifactId}", SUBJECT) - .then() - .statusCode(200) - .body("", equalTo(new JsonPath(SCHEMA_SIMPLE_JSON_QUOTED).getMap(""))); - - // Verify - given() - .when() - .get(getBasePath() + "/schemas/ids/{id}", id) - .then() - .statusCode(200) - .body(Matchers.containsString("prefix4.public.my_table")); - } - - /** - * Endpoint: /subjects/(string: subject)/versions - */ - @Test - public void testCreateDuplicateContent() throws Exception { - final String SUBJECT = "testCreateDuplicateContent"; - // POST content1 - ValidatableResponse res = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_1_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))); - int id1 = res.extract().jsonPath().getInt("id"); - - this.waitForContentId(id1); - - // POST content2 - res = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_2_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))); - int id2 = res.extract().jsonPath().getInt("id"); - - this.waitForContentId(id2); - - // POST content3 (duplicate of content1) - res = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_1_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))); - int id3 = res.extract().jsonPath().getInt("id"); - - // ID1 and ID3 should be the same because they are the same content within the same subject. - Assertions.assertEquals(id1, id3); - } - - /** - * Endpoint: /compatibility/subjects/{subject}/versions/{version} - */ - @Test - public void testCompatibilityCheck() throws Exception { - final String SUBJECT = "testCompatibilityCheck"; - // Prepare - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_2_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body(anything()); - this.waitForArtifact(SUBJECT); - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(CONFIG_BACKWARD) - .put(getBasePath() + "/config/{subject}", SUBJECT) - .then() - .statusCode(200) - .body(anything()); - - // POST - TestUtils.retry(() -> { - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_1_WRAPPED) - .post(getBasePath() + "/compatibility/subjects/{subject}/versions/{version}", SUBJECT, "latest") - .then() - .statusCode(200) - .body("is_compatible", equalTo(true)); - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_SIMPLE_WRAPPED) - .post(getBasePath() + "/compatibility/subjects/{subject}/versions/{version}", SUBJECT, "latest") - .then() - .statusCode(200) - .body("is_compatible", equalTo(false)); - }); - } - - /** - * Endpoint: /compatibility/subjects/{subject}/versions/{version} - */ - @Test - public void testCompatibilityInvalidSchema() throws Exception { - - final String SUBJECT = "testCompatibilityInvalidSchema"; - - // Prepare - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(VALID_AVRO_SCHEMA) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body(anything()); - - this.waitForArtifact(SUBJECT); - - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(CONFIG_BACKWARD) - .put(getBasePath() + "/config/{subject}", SUBJECT) - .then() - .statusCode(200) - .body(anything()); - - this.waitForArtifactRule(SUBJECT, RuleType.COMPATIBILITY); - - // POST - TestUtils.retry(() -> { - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_INVALID_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(422) - .body("error_code", Matchers.allOf(Matchers.isA(Integer.class), Matchers.equalTo(42201))); - }); - } - - @Test - public void testDisabledStateCheck() throws Exception { - final String SUBJECT = "subject3"; - // Prepare - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_SIMPLE_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))); - - this.waitForArtifact(SUBJECT); - - //verify - given() - .when() - .get("/registry/v1/artifacts/{artifactId}", SUBJECT) - .then() - .statusCode(200) - .body("", equalTo(new JsonPath(SCHEMA_SIMPLE).getMap(""))); - - //Update state - UpdateState updateState = new UpdateState(); - updateState.setState(ArtifactState.DISABLED); - given() - .when() - .contentType(ContentTypes.JSON) - .body(updateState) - .put("/registry/v1/artifacts/{artifactId}/state", SUBJECT) - .then() - .statusCode(204); - - // GET - shouldn't return as the state has been changed to DISABLED - TestUtils.retry(() -> { - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/subjects/{subject}/versions/{version}", SUBJECT, "latest") - .then() - .statusCode(404) - .body("error_code", Matchers.allOf(Matchers.isA(Integer.class), Matchers.equalTo(40402))); - }); - - // GET schema only - shouldn't return as the state has been changed to DISABLED - TestUtils.retry(() -> { - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/subjects/{subject}/versions/{version}/schema", SUBJECT, "latest") - .then() - .statusCode(404) - .body("error_code", Matchers.allOf(Matchers.isA(Integer.class), Matchers.equalTo(40402))); - }); - } - - @Test - public void testSchemaTypes() throws Exception { - //verify - String[] types = given() - .when() - .get(getBasePath() + "/schemas/types") - .then() - .statusCode(200) - .extract().as(String[].class); - - assertEquals(3, types.length); - assertEquals("JSON", types[0]); - assertEquals("PROTOBUF", types[1]); - assertEquals("AVRO", types[2]); - } - - /** - * Endpoint: /subjects/{subject}/versions - */ - @Test - public void testRegisterWithType() throws Exception { - final String SUBJECT = "subjectRegisterWithType"; - - // POST - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_SIMPLE_WRAPPED_WITH_TYPE) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))); - } - - - /** - * Endpoint: /schemas/ids/{int: id} - */ - @Test - public void testGetSchemaById() throws Exception { - //VERIFY AVRO, no schema type should be returned - registerSchemaAndVerify(SCHEMA_SIMPLE_WRAPPED, "subject_test_avro", null); - //VERIFY JSON, JSON must be returned as schemaType - registerSchemaAndVerify(JSON_SCHEMA_SIMPLE_WRAPPED_WITH_TYPE, "subject_test_json", "JSON"); - //VERIFY PROTOBUF, PROTOBUF must be returned as schemaType - registerSchemaAndVerify(PROTOBUF_SCHEMA_SIMPLE_WRAPPED_WITH_TYPE, "subject_test_proto", "PROTOBUF"); - } - - private void registerSchemaAndVerify(String schema, String subject, String schemaTye) throws Exception { - registerSchemaInSubject(schema, subject); - this.waitForArtifact(subject); - final Integer avroSchemaGlobalId = given().when().get(getBasePath() + "/subjects/{subject}/versions/latest", subject).body().jsonPath().get("id"); - verifySchemaType(avroSchemaGlobalId, schemaTye); - } - - private void registerSchemaInSubject(String schema, String subject) { - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(schema) - .post(getBasePath() + "/subjects/{subject}/versions", subject) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))); - } - - private void verifySchemaType(long globalId, String schemaType) { - //Verify - Assertions.assertEquals(given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/schemas/ids/{id}", globalId) - .then() - .extract() - .body().jsonPath().get("schemaType"), schemaType); - } - - /** - * Endpoint: /schemas/ids/{int: id}/versions - */ - @Test - public void testGetSchemaVersions() throws Exception { - final String SUBJECT = "subjectTestSchemaVersions"; - final String SECOND_SUBJECT = "secondSubjectTestSchemaVersions"; - - //Create two versions of the same artifact - // POST - final Integer contentId1 = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_1_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))) - .extract().body().jsonPath().get("id"); - Assertions.assertNotNull(contentId1); - - this.waitForArtifact(SUBJECT); - - //Register different schema in second subject - // POST - final Integer contentId2 = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_2_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SECOND_SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))) - .extract().body().jsonPath().get("id"); - - Assertions.assertNotNull(contentId2); - - this.waitForArtifact(SECOND_SUBJECT); - this.waitForContentId(contentId2); - - //Register again schema 1 in different subject gives same contentId - // POST - final Integer contentId3 = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_1_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SECOND_SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))) - .extract().body().jsonPath().get("id"); - - Assertions.assertNotNull(contentId3); - - this.waitForArtifact(SECOND_SUBJECT); - this.waitForContentId(contentId3); - - TestUtils.retry(() -> { - //Verify - final ResponseBodyExtractionOptions body = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/schemas/ids/{id}/versions", contentId1) - .then() - .statusCode(200) - .extract().body(); - - assertEquals(contentId1, contentId3); - - final List subjects = body.jsonPath().get("subject"); - final List versions = body.jsonPath().get("version"); - Assertions.assertTrue(List.of("subjectTestSchemaVersions", "secondSubjectTestSchemaVersions").containsAll(subjects)); - Assertions.assertTrue(List.of(1, 2).containsAll(versions)); - }); - } - - /** - * Endpoint: /ccompat/v6/subjects/{subject}/versions/{version}/referencedby - */ - @Test - public void testGetSchemaReferencedVersions() throws Exception { - final String SUBJECT_1 = "testGetSchemaReferencedVersions1"; - final String SUBJECT_2 = "testGetSchemaReferencedVersions2"; - - // Create first artifact - // POST - final Integer contentId1 = given().when().contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_1_WRAPPED).post(getBasePath() + "/subjects/{subject}/versions", SUBJECT_1).then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))) - .extract().body().jsonPath().get("id"); - Assertions.assertNotNull(contentId1); - - this.waitForArtifact(SUBJECT_1); - this.waitForContentId(contentId1); - - // Create artifact that references the first one - // POST - System.out.printf((SCHEMA_3_WRAPPED_TEMPLATE) + "%n", SUBJECT_1, 1); - final Integer contentId2 = given().when().contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(String.format(SCHEMA_3_WRAPPED_TEMPLATE, SUBJECT_1, 1)).post(getBasePath() + "/subjects/{subject}/versions", SUBJECT_2).then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(1))) - .extract().body().jsonPath().get("id"); - Assertions.assertNotNull(contentId2); - - this.waitForArtifact(SUBJECT_2); - this.waitForContentId(contentId2); - - //Verify - Integer[] versions = given().when() - .get(getBasePath() + "/subjects/{subject}/versions/{version}/referencedby", SUBJECT_1, 1L).then().statusCode(200) - .extract().as(Integer[].class); - - assertEquals(1, versions.length); - assertTrue(Arrays.asList(versions).contains(contentId2)); - } - - /** - * Endpoint: /ccompat/v6/config PUT - * Endpoint: /ccompat/v6/config GET - */ - @Test - public void testConfigEndpoints() throws Exception { - - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(CONFIG_BACKWARD) - .put(getBasePath() + "/config/") - .then() - .statusCode(200) - .extract().as(CompatibilityLevelDto.class); - - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/config/") - .then() - .statusCode(200) - .extract().as(CompatibilityLevelParamDto.class); - } - - /** - * Endpoint: /ccompat/v6/config/{subject} PUT - * Endpoint: /ccompat/v6/config/{subject} GET - */ - @Test - public void testSubjectConfigEndpoints() throws Exception { - - final String SUBJECT = "subject2"; - // Prepare - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_2_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body(anything()); - this.waitForArtifact(SUBJECT); - - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(CONFIG_BACKWARD) - .put(getBasePath() + "/config/{subject}", SUBJECT) - .then() - .statusCode(200) - .extract().as(CompatibilityLevelDto.class); - - - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(CONFIG_BACKWARD) - .get(getBasePath() + "/config/{subject}", SUBJECT) - .then() - .statusCode(200) - .extract().as(CompatibilityLevelParamDto.class); - } - - @Test - public void validateAcceptHeaders() throws Exception { - - //Test application/json - String[] types = given() - .when() - .accept(ContentTypes.JSON) - .get(getBasePath() + "/schemas/types") - .then() - .statusCode(200) - .extract().as(String[].class); - - assertTypes(types); - - //Test application/vnd.schemaregistry.v1+jso - types = given() - .when() - .accept(ContentTypes.COMPAT_SCHEMA_REGISTRY_V1) - .get(getBasePath() + "/schemas/types") - .then() - .statusCode(200) - .extract().as(String[].class); - - assertTypes(types); - - //Test application/vnd.schemaregistry+json - types = given() - .when() - .accept(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/schemas/types") - .then() - .statusCode(200) - .extract().as(String[].class); - - assertTypes(types); - } - - public void assertTypes(String[] types) { - - assertEquals(3, types.length); - assertEquals("JSON", types[0]); - assertEquals("PROTOBUF", types[1]); - assertEquals("AVRO", types[2]); - } - - @Test - public void testDeleteSchemaVersion() throws Exception { - final String SUBJECT = "testDeleteSchemaVersion"; - final Integer contentId1 = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_1_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))) - .extract().body().jsonPath().get("id"); - Assertions.assertNotNull(contentId1); - - this.waitForArtifact(SUBJECT); - - final Integer contentId2 = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_2_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))) - .extract().body().jsonPath().get("id"); - - Assertions.assertNotNull(contentId2); - - this.waitForContentId(contentId2); - - //check versions list - var versionsConfluent = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .extract().as(Integer[].class); - - assertEquals(2, versionsConfluent.length); - - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/subjects/{subject}/versions/{version}", SUBJECT, "1") - .then() - .statusCode(200); - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/subjects/{subject}/versions/{version}", SUBJECT, "2") - .then() - .statusCode(200); - - - var versionsApicurio = given() - .when() - .get("/registry/v2/groups/default/artifacts/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .extract().as(VersionSearchResults.class) - .getVersions(); - - assertEquals(2, versionsApicurio.size()); - - //delete version 2 - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .delete(getBasePath() + "/subjects/{subject}/versions/{version}", SUBJECT, "2") - .then() - .statusCode(200); - - versionsConfluent = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .extract().as(Integer[].class); - - assertEquals(1, versionsConfluent.length); - - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/subjects/{subject}/versions/{version}", SUBJECT, "1") - .then() - .statusCode(200); - - versionsApicurio = given() - .when() - .get("/registry/v2/groups/default/artifacts/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .extract().as(VersionSearchResults.class) - .getVersions(); - - assertEquals(1, versionsApicurio.size()); - - given() - .when() - .get("/registry/v2/groups/default/artifacts/{subject}/versions/1", SUBJECT) - .then() - .statusCode(200); - given() - .when() - .get("/registry/v2/groups/default/artifacts/{subject}/versions/1/meta", SUBJECT) - .then() - .statusCode(200); - given() - .when() - .get("/registry/v2/groups/default/artifacts/{subject}/meta", SUBJECT) - .then() - .statusCode(200); - given() - .when() - .get("/registry/v2/groups/default/artifacts/{subject}", SUBJECT) - .then() - .statusCode(200); - } - - - /** - * Endpoint: /schemas/ids/{int: id}/versions - */ - @Test - public void testMinifiedSchema() throws Exception { - final String SUBJECT = "testMinifiedSchema"; - String testSchemaExpanded = resourceToString("../avro-expanded.avsc"); - - ObjectMapper objectMapper = new ObjectMapper(); - SchemaContent schemaContent = new SchemaContent(testSchemaExpanded); - - // POST - final Integer contentId1 = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(objectMapper.writeValueAsString(schemaContent)) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))) - .extract().body().jsonPath().get("id"); - - Assertions.assertNotNull(contentId1); - - this.waitForArtifact(SUBJECT); - - String minifiedSchema = resourceToString("../avro-minified.avsc"); - SchemaContent minifiedSchemaContent = new SchemaContent(minifiedSchema); - - //Without the canonical hash mode, this will fail with a 404 - //With the profile - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(objectMapper.writeValueAsString(minifiedSchemaContent)) - .post(getBasePath() + "/subjects/{subject}", SUBJECT) - .then() - .statusCode(404) - .body("error_code", Matchers.allOf(Matchers.isA(Integer.class), Matchers.equalTo(40401))); - - - // POST - //Create returns a different id, wrong behaviour with the canonical mode enabled since the schema is the same. - Assertions.assertNotEquals(contentId1, given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(objectMapper.writeValueAsString(minifiedSchemaContent)) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))) - .extract().body().jsonPath().get("id")); - } -} diff --git a/app/src/test/java/io/apicurio/registry/noprofile/ccompat/rest/v7/ConfluentCompatApiTest.java b/app/src/test/java/io/apicurio/registry/noprofile/ccompat/rest/v7/ConfluentCompatApiTest.java deleted file mode 100644 index 7c7b18005d..0000000000 --- a/app/src/test/java/io/apicurio/registry/noprofile/ccompat/rest/v7/ConfluentCompatApiTest.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright 2022 Red Hat - * - * Licensed 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 io.apicurio.registry.noprofile.ccompat.rest.v7; - -import com.fasterxml.jackson.databind.ObjectMapper; -import io.apicurio.registry.AbstractResourceTestBase; -import io.apicurio.registry.ccompat.dto.CompatibilityLevelDto; -import io.apicurio.registry.ccompat.dto.CompatibilityLevelParamDto; -import io.apicurio.registry.ccompat.dto.SchemaContent; -import io.apicurio.registry.ccompat.rest.ContentTypes; -import io.apicurio.registry.rest.v2.beans.VersionSearchResults; -import io.quarkus.test.junit.QuarkusTest; -import org.hamcrest.Matchers; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import jakarta.enterprise.inject.Typed; - -import static io.apicurio.registry.noprofile.ccompat.rest.CCompatTestConstants.*; -import static io.restassured.RestAssured.given; -import static org.hamcrest.Matchers.anything; -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Tests that the REST API exposed at endpoint "/ccompat/v7" follows the - * Confluent API specification, - * unless otherwise stated. - * - * @author Carles Arnal - */ -@QuarkusTest -@Typed(ConfluentCompatApiTest.class) -public class ConfluentCompatApiTest extends AbstractResourceTestBase { - - public static final String BASE_PATH = "/ccompat/v7"; - - @NotNull - public String getBasePath() { - return BASE_PATH; - } - - @Test - public void testSubjectConfigEndpoints() throws Exception { - final String SUBJECT = "subject2"; - // Prepare - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_2_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body(anything()); - this.waitForArtifact(SUBJECT); - - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(CONFIG_BACKWARD) - .put(getBasePath() + "/config/{subject}", SUBJECT) - .then() - .statusCode(200) - .extract().as(CompatibilityLevelDto.class); - - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(CONFIG_BACKWARD) - .get(getBasePath() + "/config/{subject}", SUBJECT) - .then() - .statusCode(200) - .extract().as(CompatibilityLevelParamDto.class); - - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .delete(getBasePath() + "/config/{subject}", SUBJECT) - .then() - .statusCode(200) - .extract().as(CompatibilityLevelParamDto.class); - - final CompatibilityLevelParamDto compatibilityLevel = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .delete(getBasePath() + "/config/{subject}", SUBJECT) - .then() - .statusCode(200) - .extract().as(CompatibilityLevelParamDto.class); - - assertEquals(compatibilityLevel.getCompatibilityLevel(), CompatibilityLevelDto.Level.NONE.name()); - } - - @Test - public void testDeleteSchemaVersion() throws Exception { - final String SUBJECT = "testDeleteSchemaVersion"; - final Integer contentId1 = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_1_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))) - .extract().body().jsonPath().get("id"); - Assertions.assertNotNull(contentId1); - - this.waitForArtifact(SUBJECT); - - final Integer contentId2 = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(SCHEMA_2_WRAPPED) - .post(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))) - .extract().body().jsonPath().get("id"); - - Assertions.assertNotNull(contentId2); - - this.waitForContentId(contentId2); - - //check versions list - var versionsConfluent = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .extract().as(Integer[].class); - - assertEquals(2, versionsConfluent.length); - - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/subjects/{subject}/versions/{version}", SUBJECT, "1") - .then() - .statusCode(200); - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/subjects/{subject}/versions/{version}", SUBJECT, "2") - .then() - .statusCode(200); - - - var versionsApicurio = given() - .when() - .get("/registry/v2/groups/default/artifacts/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .extract().as(VersionSearchResults.class) - .getVersions(); - - assertEquals(2, versionsApicurio.size()); - - //delete version 2, permanent is required so the version is hard deleted. - given() - .when() - .queryParam("permanent", true) - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .delete(getBasePath() + "/subjects/{subject}/versions/{version}", SUBJECT, "2") - .then() - .statusCode(200); - - versionsConfluent = given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .extract().as(Integer[].class); - - assertEquals(1, versionsConfluent.length); - - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .get(getBasePath() + "/subjects/{subject}/versions/{version}", SUBJECT, "1") - .then() - .statusCode(200); - - versionsApicurio = given() - .when() - .get("/registry/v2/groups/default/artifacts/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .extract().as(VersionSearchResults.class) - .getVersions(); - - assertEquals(1, versionsApicurio.size()); - - given() - .when() - .get("/registry/v2/groups/default/artifacts/{subject}/versions/1", SUBJECT) - .then() - .statusCode(200); - given() - .when() - .get("/registry/v2/groups/default/artifacts/{subject}/versions/1/meta", SUBJECT) - .then() - .statusCode(200); - given() - .when() - .get("/registry/v2/groups/default/artifacts/{subject}/meta", SUBJECT) - .then() - .statusCode(200); - given() - .when() - .get("/registry/v2/groups/default/artifacts/{subject}", SUBJECT) - .then() - .statusCode(200); - } - - /** - * This is the same test case as in - * @see io.apicurio.registry.ccompat.rest.CCompatCanonicalModeTest - * in v7, there is no need for the configuration option since the param is available at the API level. - */ - @Test - public void normalizedSchemasTest() throws Exception { - final String SUBJECT = "testSchemaExpanded"; - String testSchemaExpanded = resourceToString("../avro-expanded.avsc"); - - ObjectMapper objectMapper = new ObjectMapper(); - SchemaContent schemaContent = new SchemaContent(testSchemaExpanded); - - // POST - // creating the content normalized so it can be found later - final Integer contentId1 = given() - .when() - .queryParam("normalize", true) - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(objectMapper.writeValueAsString(schemaContent)) - .post(V7_BASE_PATH + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.greaterThanOrEqualTo(0))) - .extract().body().jsonPath().get("id"); - - Assertions.assertNotNull(contentId1); - - this.waitForArtifact(SUBJECT); - - SchemaContent minifiedSchemaContent = new SchemaContent(resourceToString("../avro-minified.avsc")); - - //without normalize the content, getting the schema by content does not work - given() - .when() - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(objectMapper.writeValueAsString(minifiedSchemaContent)) - .post(V7_BASE_PATH + "/subjects/{subject}", SUBJECT) - .then() - .statusCode(404); - - //normalizing the content, getting the schema by content works - given() - .when() - .queryParam("normalize", true) - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(objectMapper.writeValueAsString(minifiedSchemaContent)) - .post(V7_BASE_PATH + "/subjects/{subject}", SUBJECT) - .then() - .statusCode(200); - - // POST - //Create just returns the id from the existing schema, since the canonical hash is the same. - Assertions.assertEquals(contentId1, given() - .when() - .queryParam("normalize", true) - .contentType(ContentTypes.COMPAT_SCHEMA_REGISTRY_STABLE_LATEST) - .body(objectMapper.writeValueAsString(minifiedSchemaContent)) - .post(V7_BASE_PATH + "/subjects/{subject}/versions", SUBJECT) - .then() - .statusCode(200) - .body("id", Matchers.allOf(Matchers.isA(Integer.class), Matchers.equalTo(contentId1))) - .extract().body().jsonPath().get("id")); - } -} diff --git a/app/src/test/java/io/apicurio/registry/noprofile/maven/RegistryMojoTestBase.java b/app/src/test/java/io/apicurio/registry/noprofile/maven/RegistryMojoTestBase.java index 5f6170ffc4..b5672ad023 100644 --- a/app/src/test/java/io/apicurio/registry/noprofile/maven/RegistryMojoTestBase.java +++ b/app/src/test/java/io/apicurio/registry/noprofile/maven/RegistryMojoTestBase.java @@ -35,7 +35,8 @@ import java.util.Arrays; import java.util.List; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * @author Ales Justin diff --git a/app/src/test/java/io/apicurio/registry/rbac/AdminResourceTest.java b/app/src/test/java/io/apicurio/registry/rbac/AdminResourceTest.java index 06e2a1921d..4d2ef67531 100644 --- a/app/src/test/java/io/apicurio/registry/rbac/AdminResourceTest.java +++ b/app/src/test/java/io/apicurio/registry/rbac/AdminResourceTest.java @@ -23,9 +23,9 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayInputStream; diff --git a/app/src/test/java/io/apicurio/registry/rbac/RegistryClientTest.java b/app/src/test/java/io/apicurio/registry/rbac/RegistryClientTest.java index 62476333e8..8ce95287db 100644 --- a/app/src/test/java/io/apicurio/registry/rbac/RegistryClientTest.java +++ b/app/src/test/java/io/apicurio/registry/rbac/RegistryClientTest.java @@ -64,7 +64,6 @@ import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.IOUtils; import org.jetbrains.annotations.NotNull; -import org.junit.Assert; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -206,7 +205,7 @@ public void groupsCrud() throws Exception { assertTrue(groupIds.containsAll(List.of(groupId, group1Id, group2Id, group3Id))); clientV2.deleteArtifactGroup(groupId); - Assert.assertThrows(GroupNotFoundException.class, () -> clientV2.getArtifactGroup(groupId)); + assertThrows(GroupNotFoundException.class, () -> clientV2.getArtifactGroup(groupId)); } @Test diff --git a/client/pom.xml b/client/pom.xml index cfb25dd376..1784f7be72 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -21,7 +21,7 @@ apicurio-registry io.apicurio - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/client/src/main/java/io/apicurio/registry/rest/client/AdminClient.java b/client/src/main/java/io/apicurio/registry/rest/client/AdminClient.java index e923b9391e..7bbcb64c3a 100644 --- a/client/src/main/java/io/apicurio/registry/rest/client/AdminClient.java +++ b/client/src/main/java/io/apicurio/registry/rest/client/AdminClient.java @@ -16,6 +16,7 @@ package io.apicurio.registry.rest.client; +import io.apicurio.registry.rest.v2.beans.ArtifactTypeInfo; import io.apicurio.registry.rest.v2.beans.LogConfiguration; import io.apicurio.registry.rest.v2.beans.NamedLogConfiguration; import io.apicurio.registry.rest.v2.beans.RoleMapping; @@ -68,4 +69,6 @@ public interface AdminClient extends Closeable { void importData(InputStream data); void importData(InputStream data, boolean preserveGlobalIds, boolean preserveContentIds); + + List listArtifactTypes(); } diff --git a/client/src/main/java/io/apicurio/registry/rest/client/impl/AdminClientImpl.java b/client/src/main/java/io/apicurio/registry/rest/client/impl/AdminClientImpl.java index ac226cddf8..71682ec181 100644 --- a/client/src/main/java/io/apicurio/registry/rest/client/impl/AdminClientImpl.java +++ b/client/src/main/java/io/apicurio/registry/rest/client/impl/AdminClientImpl.java @@ -153,6 +153,11 @@ public void importData(InputStream data, boolean preserveGlobalIds, boolean pres apicurioHttpClient.sendRequest(AdminRequestsProvider.importData(data, preserveGlobalIds, preserveContentIds)); } + @Override + public List listArtifactTypes() { + return apicurioHttpClient.sendRequest(AdminRequestsProvider.listArtifactTypes()); + } + private static RestClientException parseSerializationError(JsonProcessingException ex) { final Error error = new Error(); diff --git a/client/src/main/java/io/apicurio/registry/rest/client/request/provider/AdminRequestsProvider.java b/client/src/main/java/io/apicurio/registry/rest/client/request/provider/AdminRequestsProvider.java index bd41949a61..243006b51c 100644 --- a/client/src/main/java/io/apicurio/registry/rest/client/request/provider/AdminRequestsProvider.java +++ b/client/src/main/java/io/apicurio/registry/rest/client/request/provider/AdminRequestsProvider.java @@ -21,6 +21,7 @@ import static io.apicurio.registry.rest.client.request.provider.Routes.CONFIG_PROPERTY_PATH; import static io.apicurio.registry.rest.client.request.provider.Routes.EXPORT_PATH; import static io.apicurio.registry.rest.client.request.provider.Routes.IMPORT_PATH; +import static io.apicurio.registry.rest.client.request.provider.Routes.LIST_ARTIFACT_PATH; import static io.apicurio.registry.rest.client.request.provider.Routes.LOGS_BASE_PATH; import static io.apicurio.registry.rest.client.request.provider.Routes.LOG_PATH; import static io.apicurio.registry.rest.client.request.provider.Routes.ROLE_MAPPINGS_BASE_PATH; @@ -42,6 +43,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.apicurio.registry.rest.Headers; +import io.apicurio.registry.rest.v2.beans.ArtifactTypeInfo; import io.apicurio.registry.rest.v2.beans.ConfigurationProperty; import io.apicurio.registry.rest.v2.beans.LogConfiguration; import io.apicurio.registry.rest.v2.beans.NamedLogConfiguration; @@ -180,6 +182,14 @@ public static Request importData(InputStream data, boolean preserveGlobalI .build(); } + public static Request> listArtifactTypes() { + return new Request.RequestBuilder>() + .operation(GET) + .path(LIST_ARTIFACT_PATH) + .responseType(new TypeReference>() {}) + .build(); + } + public static Request createRoleMapping(RoleMapping data) throws JsonProcessingException { return new Request.RequestBuilder() .operation(POST) diff --git a/client/src/main/java/io/apicurio/registry/rest/client/request/provider/Routes.java b/client/src/main/java/io/apicurio/registry/rest/client/request/provider/Routes.java index 24c70ee67f..de9eab5b71 100644 --- a/client/src/main/java/io/apicurio/registry/rest/client/request/provider/Routes.java +++ b/client/src/main/java/io/apicurio/registry/rest/client/request/provider/Routes.java @@ -71,4 +71,6 @@ public class Routes { protected static final String EXPORT_PATH = ADMIN_BASE_PATH + "/export"; protected static final String IMPORT_PATH = ADMIN_BASE_PATH + "/import"; + + protected static final String LIST_ARTIFACT_PATH = ADMIN_BASE_PATH + "/artifactTypes"; } diff --git a/common/pom.xml b/common/pom.xml index 324c9f0ffa..de44ba031c 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -7,7 +7,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml @@ -56,6 +56,12 @@ provided + + io.apicurio + apicurio-common-app-components-config-definitions + provided + + org.projectlombok lombok diff --git a/distro/connect-converter/pom.xml b/distro/connect-converter/pom.xml index 837650ab5c..5ad6f571b1 100644 --- a/distro/connect-converter/pom.xml +++ b/distro/connect-converter/pom.xml @@ -5,7 +5,7 @@ io.apicurio apicurio-registry-distro - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml diff --git a/distro/docker-compose/README.md b/distro/docker-compose/README.md index 3ecaea9003..4e44dd2e98 100644 --- a/distro/docker-compose/README.md +++ b/distro/docker-compose/README.md @@ -38,8 +38,6 @@ Here is the port mapping: - 8080 for Keycloak - 8081 for the Registry -``` - #### Starting the environment You can start the whole stack with these commands: diff --git a/distro/docker-compose/pom.xml b/distro/docker-compose/pom.xml index 08b1b99756..c70f9e5c84 100644 --- a/distro/docker-compose/pom.xml +++ b/distro/docker-compose/pom.xml @@ -5,7 +5,7 @@ io.apicurio apicurio-registry-distro - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml diff --git a/distro/docker-compose/src/main/resources/docker-compose.apicurio.yml b/distro/docker-compose/src/main/resources/docker-compose.apicurio.yml index bea8ab0708..d624f03b2b 100644 --- a/distro/docker-compose/src/main/resources/docker-compose.apicurio.yml +++ b/distro/docker-compose/src/main/resources/docker-compose.apicurio.yml @@ -6,38 +6,43 @@ volumes: services: keycloak-server: + container_name: keycloak-apicurio image: quay.io/keycloak/keycloak:19.0.2 environment: - QUARKUS_HTTP_PORT: 8090 KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin + KC_HOSTNAME_URL: http://localhost:8080 command: - start-dev - --import-realm + ports: + - 8080:8080 volumes: - ./config/keycloak/apicurio-realm.json:/opt/keycloak/data/import/realm.json - network_mode: host postgres: + container_name: database-apicurio image: postgres environment: POSTGRES_USER: apicurio-registry POSTGRES_PASSWORD: password - network_mode: host + app: image: apicurio/apicurio-registry-sql:latest-snapshot environment: - REGISTRY_DATASOURCE_URL: 'jdbc:postgresql://localhost:5432/apicurio-registry' + REGISTRY_DATASOURCE_URL: 'jdbc:postgresql://database-apicurio:5432/apicurio-registry' REGISTRY_DATASOURCE_USERNAME: apicurio-registry REGISTRY_DATASOURCE_PASSWORD: password AUTH_ENABLED: "true" KEYCLOAK_REALM: registry QUARKUS_HTTP_PORT: 8081 + LOG_LEVEL: "DEBUG" KEYCLOAK_URL: "http://localhost:8080" KEYCLOAK_API_CLIENT_ID: registry-api KEYCLOAK_UI_CLIENT_ID: apicurio-registry - REGISTRY_AUTH_URL_CONFIGURED: "http://localhost:8080/realms/registry" + REGISTRY_AUTH_URL_CONFIGURED: "http://host.docker.internal:8080/realms/registry" + ports: + - 8081:8081 depends_on: - postgres - keycloak-server - network_mode: host diff --git a/distro/docker/pom.xml b/distro/docker/pom.xml index a6c3cc4423..bf7425b28c 100644 --- a/distro/docker/pom.xml +++ b/distro/docker/pom.xml @@ -5,7 +5,7 @@ io.apicurio apicurio-registry-distro - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml diff --git a/distro/docker/src/main/docker/Dockerfile.native-scratch b/distro/docker/src/main/docker/Dockerfile.native-scratch new file mode 100644 index 0000000000..c4ef27d26e --- /dev/null +++ b/distro/docker/src/main/docker/Dockerfile.native-scratch @@ -0,0 +1,33 @@ +FROM quay.io/quarkus/ubi-quarkus-graalvmce-builder-image:22.3-java17 AS build + +USER root + +RUN microdnf install make gcc + +COPY --chown=quarkus:quarkus . /code + +RUN mkdir /musl && \ + curl -L -o musl.tar.gz https://more.musl.cc/11.2.1/x86_64-linux-musl/x86_64-linux-musl-native.tgz && \ + tar -xvzf musl.tar.gz -C /musl --strip-components 1 && \ + curl -L -o zlib.tar.gz https://www.zlib.net/zlib-1.2.13.tar.gz && \ + mkdir zlib && tar -xvzf zlib.tar.gz -C zlib --strip-components 1 && \ + cd zlib && ./configure --static --prefix=/musl && \ + make && make install && \ + cd .. && rm -rf zlib && rm -f zlib.tar.gz && rm -f musl.tar.gz +ENV PATH="/musl/bin:${PATH}" + +USER quarkus + +WORKDIR /code + +RUN ./mvnw clean install -DskipTests +RUN ./mvnw -T 1.5C package -B -Pnative -Pprod -DskipTests -Dquarkus.native.additional-build-args="--initialize-at-run-time=org.apache.kafka.common.security.authenticator.SaslClientAuthenticator","--allow-incomplete-classpath","--static","--libc=musl" -f ./app/pom.xml + +FROM scratch + +COPY --from=build /code/app/target/meta /work/meta +COPY --from=build /code/app/target/*-runner /application + +EXPOSE 8080 + +CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/distro/openshift-template/pom.xml b/distro/openshift-template/pom.xml index 4391395b59..39a64e7605 100644 --- a/distro/openshift-template/pom.xml +++ b/distro/openshift-template/pom.xml @@ -5,7 +5,7 @@ io.apicurio apicurio-registry-distro - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml diff --git a/distro/pom.xml b/distro/pom.xml index e1a2566d5f..374101ba05 100644 --- a/distro/pom.xml +++ b/distro/pom.xml @@ -4,7 +4,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml apicurio-registry-distro diff --git a/docs/modules/ROOT/partials/getting-started/ref-registry-security-configuration.adoc b/docs/modules/ROOT/partials/getting-started/ref-registry-security-configuration.adoc index b8915b70b8..72db879aa3 100644 --- a/docs/modules/ROOT/partials/getting-started/ref-registry-security-configuration.adoc +++ b/docs/modules/ROOT/partials/getting-started/ref-registry-security-configuration.adoc @@ -12,7 +12,7 @@ * Role-based authorization for default admin, write, and read-only user roles. * Content-based authorization for schema or API artifacts, where only the owner of the artifacts or artifact group can update or delete artifacts. -IMPORTANT: All authentication and authorization options in {registry} are disabled by default. Before enabling any of these options, you must first set the `AUTH_ENABLED` option to `true`. +IMPORTANT: All authentication and authorization options in {registry} are disabled by default. Before enabling any of these options, you must first set the `AUTH_ENABLED` option to `true`. This chapter provides details on the following configuration options: @@ -25,7 +25,7 @@ This chapter provides details on the following configuration options: [discrete] [id="registry-security-authn-keycloak"] -== {registry} authentication by using OpenID Connect with {keycloak} +== {registry} authentication by using OpenID Connect with {keycloak} You can set the following environment variables to configure authentication for the {registry} web console and API with {keycloak}: @@ -82,9 +82,9 @@ By default, {registry} supports authentication by using OpenID Connect. Users or |=== [discrete] -=== {registry} HTTP basic client credentials cache expiry +=== {registry} HTTP basic client credentials cache expiry -You can also configure the HTTP basic client credentials cache expiry time. By default, when using HTTP basic authentication, {registry} caches JWT tokens, and does not issue a new token when there is no need. You can configure the cache expiry time for JWT tokens, which is set to 10 mins by default. +You can also configure the HTTP basic client credentials cache expiry time. By default, when using HTTP basic authentication, {registry} caches JWT tokens, and does not issue a new token when there is no need. You can configure the cache expiry time for JWT tokens, which is set to 10 mins by default. When using {keycloak}, it is best to set this configuration to your {keycloak} JWT expiry time minus one minute. For example, if you have the expiry time set to `5` mins in {keycloak}, you should set the following configuration option to `4` mins: diff --git a/docs/modules/ROOT/partials/shared/attributes.adoc b/docs/modules/ROOT/partials/shared/attributes.adoc index 2033757bb7..7f5e0bc79c 100644 --- a/docs/modules/ROOT/partials/shared/attributes.adoc +++ b/docs/modules/ROOT/partials/shared/attributes.adoc @@ -25,7 +25,7 @@ ifndef::service-registry-downstream[] :registry-release: 2.4.3.Final :registry-docker-version: latest-release :registry-v1: 1.3 -:registry-v1-release: 1.3.2.Final +:registry-v1-release: 1.3.2.Final :operator-version: 1.0.0 :kafka-streams: Strimzi :registry-kafka-version: 3.1 @@ -88,7 +88,7 @@ include::attributes-links.adoc[] // Download URLs :download-url-registry-container-catalog: https://catalog.redhat.com/software/containers/search //:download-url-registry-distribution: https://access.redhat.com/jbossnetwork/restricted/listSoftware.html?product=rhboar&downloadType=distributions -:download-url-registry-distribution: https://access.redhat.com/jbossnetwork/restricted/listSoftware.html?downloadType=distributions&product=red.hat.integration +:download-url-registry-distribution: https://access.redhat.com/jbossnetwork/restricted/listSoftware.html?downloadType=distributions&product=red.hat.integration // internal links diff --git a/docs/pom.xml b/docs/pom.xml index bd0106629c..6fa48c1ede 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -8,7 +8,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml diff --git a/docs/rest-api/pom.xml b/docs/rest-api/pom.xml index ce7f9dfaf0..6e61751a95 100644 --- a/docs/rest-api/pom.xml +++ b/docs/rest-api/pom.xml @@ -8,7 +8,7 @@ io.apicurio apicurio-registry-docs - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml diff --git a/integration-tests/integration-tests-common/pom.xml b/integration-tests/integration-tests-common/pom.xml deleted file mode 100644 index 49da90fc07..0000000000 --- a/integration-tests/integration-tests-common/pom.xml +++ /dev/null @@ -1,197 +0,0 @@ - - - 4.0.0 - - io.apicurio - apicurio-registry - 2.4.13-SNAPSHOT - ../../pom.xml - - apicurio-registry-integration-tests-common - apicurio-registry-integration-tests-common - - - 17 - 17 - - true - - 5.10.0 - 1.9.1 - - 1.4.11 - 2.2 - 1.2 - 3.0.0-M5 - - - 4.13.2 - - 2.1.2.Final - - - - - OSSRH - OSS Sonatype - https://oss.sonatype.org/content/repositories/snapshots/ - - - - - - - io.apicurio - apicurio-registry-utils-tests - - - - io.apicurio - apicurio-common-rest-client-common - - - - org.hamcrest - hamcrest - ${hamcrest.version} - - - - org.apache.kafka - kafka-clients - - - - - org.junit.jupiter - junit-jupiter - ${junit.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit.version} - provided - - - org.junit.platform - junit-platform-launcher - ${junit.platform-launcher.version} - compile - - - - org.slf4j - slf4j-api - - - - ch.qos.logback - logback-classic - ${logback.version} - runtime - - - - org.testcontainers - testcontainers - ${test-containers.version} - - - junit - junit - ${junit4.version} - - - org.testcontainers - postgresql - ${test-containers.version} - - - org.testcontainers - kafka - - - compile - - - - io.rest-assured - rest-assured - - - - com.github.dasniko - testcontainers-keycloak - - - org.keycloak - keycloak-admin-client - - - io.quarkus - quarkus-smallrye-jwt-build - - - org.jboss.slf4j - slf4j-jboss-logmanager - - - - - - com.google.protobuf - protobuf-java - - - com.google.protobuf - protobuf-java-util - true - - - - io.zonky.test - embedded-postgres - ${embedded-postgres.version} - - - - - io.debezium - debezium-core - ${debezium.version} - compile - - - io.debezium - debezium-core - ${debezium.version} - test-jar - compile - - - - - - - - src/test/resources - true - - - - - org.apache.maven.plugins - maven-deploy-plugin - - true - - - - - - diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/ApicurioRegistryBaseIT.java b/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/ApicurioRegistryBaseIT.java deleted file mode 100644 index 9eaa88095e..0000000000 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/ApicurioRegistryBaseIT.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests.common; - -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.api.TestInstance.Lifecycle; -import org.junit.jupiter.api.extension.ExtendWith; - -import io.apicurio.registry.utils.tests.SimpleDisplayName; -import io.apicurio.tests.common.interfaces.TestSeparator; - -/** - * Base class for all base classes for integration tests or for integration tests directly. - * This class must not contain any functionality nor implement any beforeAll, beforeeEach,... - * the idea is to have this class only to register {@link RegistryDeploymentManager} in only one place. - * - * @author Fabian Martinez - */ -@DisplayNameGeneration(SimpleDisplayName.class) -@ExtendWith(RegistryDeploymentManager.class) -@TestInstance(Lifecycle.PER_CLASS) -public class ApicurioRegistryBaseIT implements TestSeparator, Constants { - -} diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/AuthServerInfo.java b/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/AuthServerInfo.java deleted file mode 100644 index 73d1c34493..0000000000 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/AuthServerInfo.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests.common; - -/** - * @author Fabian Martinez - */ -public class AuthServerInfo { - - String authServerUrl; - String realm; - - String adminClientId; - String adminClientSecret; - - String developerClientId; - String developerClientSecret; - - String readOnlyClientId; - String readOnlyClientSecret; - /** - * @return the authServerUrl - */ - public String getAuthServerUrl() { - return authServerUrl; - } - - /** - * @return the authServerUrl configured with the realm - */ - public String getAuthServerUrlConfigured() { - return authServerUrl + "/realms/" + realm + "/protocol/openid-connect/token"; - } - /** - * @param authServerUrl the authServerUrl to set - */ - public void setAuthServerUrl(String authServerUrl) { - this.authServerUrl = authServerUrl; - } - /** - * @return the realm - */ - public String getRealm() { - return realm; - } - /** - * @param realm the realm to set - */ - public void setRealm(String realm) { - this.realm = realm; - } - /** - * @return the adminClientId - */ - public String getAdminClientId() { - return adminClientId; - } - /** - * @param adminClientId the adminClientId to set - */ - public void setAdminClientId(String adminClientId) { - this.adminClientId = adminClientId; - } - /** - * @return the adminClientSecret - */ - public String getAdminClientSecret() { - return adminClientSecret; - } - /** - * @param adminClientSecret the adminClientSecret to set - */ - public void setAdminClientSecret(String adminClientSecret) { - this.adminClientSecret = adminClientSecret; - } - /** - * @return the developerClientId - */ - public String getDeveloperClientId() { - return developerClientId; - } - /** - * @param developerClientId the developerClientId to set - */ - public void setDeveloperClientId(String developerClientId) { - this.developerClientId = developerClientId; - } - /** - * @return the developerClientSecret - */ - public String getDeveloperClientSecret() { - return developerClientSecret; - } - /** - * @param developerClientSecret the developerClientSecret to set - */ - public void setDeveloperClientSecret(String developerClientSecret) { - this.developerClientSecret = developerClientSecret; - } - /** - * @return the readOnlyClientId - */ - public String getReadOnlyClientId() { - return readOnlyClientId; - } - /** - * @param readOnlyClientId the readOnlyClientId to set - */ - public void setReadOnlyClientId(String readOnlyClientId) { - this.readOnlyClientId = readOnlyClientId; - } - /** - * @return the readOnlyClientSecret - */ - public String getReadOnlyClientSecret() { - return readOnlyClientSecret; - } - /** - * @param readOnlyClientSecret the readOnlyClientSecret to set - */ - public void setReadOnlyClientSecret(String readOnlyClientSecret) { - this.readOnlyClientSecret = readOnlyClientSecret; - } - -} diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/KafkaFacade.java b/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/KafkaFacade.java deleted file mode 100644 index 17bc4e9d71..0000000000 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/KafkaFacade.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2020 Red Hat - * - * Licensed 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 io.apicurio.tests.common; - -import org.apache.kafka.clients.CommonClientConfigs; -import org.apache.kafka.clients.admin.AdminClient; -import org.apache.kafka.clients.admin.NewTopic; -import org.apache.kafka.common.config.SslConfigs; -import org.apache.kafka.common.security.auth.SecurityProtocol; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.KafkaContainer; -import org.testcontainers.containers.output.OutputFrame.OutputType; - -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.common.kafka.EmbeddedKafka; -import io.apicurio.tests.common.kafka.TrustAllSslEngineFactory; -import io.apicurio.tests.common.utils.RegistryUtils; -import java.util.Arrays; -import java.util.Properties; - -/** - * Facade class for simulate Kafka cluster - */ -public class KafkaFacade implements RegistryTestProcess { - static final Logger LOGGER = LoggerFactory.getLogger(KafkaFacade.class); - - private KafkaContainer kafkaContainer; - private EmbeddedKafka embeddedKafka; - private boolean sharedKafkaCluster = false; - private AdminClient client; - - private static KafkaFacade instance; - - public static KafkaFacade getInstance() { - if (instance == null) { - instance = new KafkaFacade(); - } - return instance; - } - - private KafkaFacade() { - //hidden constructor, singleton class - } - - public void createTopic(String topic, int partitions, int replicationFactor) { - adminClient().createTopics(Arrays.asList(new NewTopic(topic, partitions, (short) replicationFactor))); - } - - public String bootstrapServers() { - if (kafkaContainer != null) { - return kafkaContainer.getBootstrapServers(); - } - if (embeddedKafka != null) { - return embeddedKafka.bootstrapServers(); - } - if (sharedKafkaCluster) { - return System.getenv(Constants.TESTS_SHARED_KAFKA_ENV_VAR); - } - return null; - } - - public Properties connectionProperties() { - Properties properties = new Properties(); - properties.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers()); - properties.put(CommonClientConfigs.CONNECTIONS_MAX_IDLE_MS_CONFIG, 10000); - properties.put(CommonClientConfigs.REQUEST_TIMEOUT_MS_CONFIG, 5000); - //shared kafka cluster is deployed in k8s/ocp and exposed externally by using SSL - if (sharedKafkaCluster) { - properties.put(SslConfigs.SSL_ENGINE_FACTORY_CLASS_CONFIG, TrustAllSslEngineFactory.class.getName()); - properties.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, ""); -// properties.put(SslConfigs.SSL_KEYMANAGER_ALGORITHM_CONFIG, ""); -// properties.put(SslConfigs.SSL_TRUSTMANAGER_ALGORITHM_CONFIG, ""); - properties.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, SecurityProtocol.SSL.name); - properties.put("enable.ssl.certificate.verification", false); - } - return properties; - } - - public void startIfNeeded() { - if (!TestUtils.isExternalRegistry() && isKafkaBasedRegistry() && isRunning()) { - LOGGER.info("Skipping deployment of kafka, because it's already deployed as registry storage"); - } else { - start(); - } - } - - public void stopIfPossible() throws Exception { - if (!TestUtils.isExternalRegistry() && isKafkaBasedRegistry()) { - LOGGER.info("Skipping stopping of kafka, because it's needed for registry storage"); - } else { - if (isRunning()) { - close(); - } - } - } - - private boolean isRunning() { - return kafkaContainer != null || embeddedKafka != null || sharedKafkaCluster; - } - - private boolean isKafkaBasedRegistry() { - return RegistryUtils.REGISTRY_STORAGE == RegistryStorageType.kafkasql; - } - - public void start() { - if (isRunning()) { - throw new IllegalStateException("Kafka cluster is already running"); - } - - String useSharedKafka = System.getenv(Constants.TESTS_SHARED_KAFKA_ENV_VAR); - String noDocker = System.getenv(Constants.NO_DOCKER_ENV_VAR); - - if (useSharedKafka != null && !useSharedKafka.isEmpty()) { - LOGGER.info("Using pre-deployed shared kafka cluster"); - sharedKafkaCluster = true; - } else if (noDocker != null && noDocker.equals("true")) { - LOGGER.info("Starting kafka embedded"); - embeddedKafka = new EmbeddedKafka(); - embeddedKafka.start(); - } else { - LOGGER.info("Starting kafka container"); - kafkaContainer = new KafkaContainer(); - kafkaContainer.addEnv("KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR", "1"); - kafkaContainer.addEnv("KAFKA_TRANSACTION_STATE_LOG_MIN_ISR", "1"); - kafkaContainer.start(); - } - } - - public KafkaContainer startNewKafka() { - LOGGER.info("Starting new kafka container"); - KafkaContainer c = new KafkaContainer(); - c.addEnv("KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR", "1"); - c.addEnv("KAFKA_TRANSACTION_STATE_LOG_MIN_ISR", "1"); - c.start(); - return c; - } - - public AdminClient adminClient() { - if (client == null) { - client = AdminClient.create(connectionProperties()); - } - return client; - } - - @Override - public String getName() { - return "kafka-" + kafkaContainer == null ? embeddedKafka == null ? "pre-deployed" : "embedded" : "container"; - } - - @Override - public void close() throws Exception { - LOGGER.info("Stopping kafka container"); - if (client != null) { - client.close(); - client = null; - } - sharedKafkaCluster = false; - if (kafkaContainer != null) { - kafkaContainer.stop(); - kafkaContainer = null; - } - if (embeddedKafka != null) { - embeddedKafka.stop(); - embeddedKafka = null; - } - } - - @Override - public String getStdOut() { - if (kafkaContainer == null) { - return ""; - } - return kafkaContainer.getLogs(OutputType.STDOUT); - } - - @Override - public String getStdErr() { - if (kafkaContainer == null) { - return ""; - } - return kafkaContainer.getLogs(OutputType.STDERR); - } - - @Override - public boolean isContainer() { - return true; - } - -} diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryDeploymentManager.java b/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryDeploymentManager.java deleted file mode 100644 index d521065308..0000000000 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryDeploymentManager.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2020 Red Hat - * - * Licensed 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 io.apicurio.tests.common; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Path; -import java.util.UUID; -import org.junit.jupiter.api.extension.AfterAllCallback; -import org.junit.jupiter.api.extension.AfterEachCallback; -import org.junit.jupiter.api.extension.BeforeAllCallback; -import org.junit.jupiter.api.extension.BeforeEachCallback; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.api.extension.ExtensionContext.Namespace; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.common.utils.RegistryUtils; - -public class RegistryDeploymentManager implements BeforeEachCallback, AfterEachCallback, BeforeAllCallback, AfterAllCallback, ExtensionContext.Store.CloseableResource { - - private static final Logger LOGGER = LoggerFactory.getLogger(RegistryDeploymentManager.class); - - private static boolean suiteStarted = false; - - private static RegistryFacade registry = RegistryFacade.getInstance(); - - void startRegistryIfNeeded(ExtensionContext context) throws Exception { - if (!TestUtils.isExternalRegistry() && !registry.isRunning()) { - LOGGER.info("Starting registry"); - try { - registry.start(); - } catch (Exception e) { - throw new IllegalStateException(e); - } - } else { - LOGGER.info("Going to use already running registries on {}", TestUtils.getRegistryV1ApiUrl()); - } - if (!TestUtils.isExternalRegistry()) { - try { - registry.waitForRegistryReady(); - } catch (Exception e) { - try { - Path logsPath = RegistryUtils.getLogsPath(context.getRequiredTestClass(), context.getDisplayName()); - registry.stopAndCollectLogs(logsPath); - } catch (IOException e1) { - e.addSuppressed(e1); - } - throw new IllegalStateException(e); - } - } - } - - @Override - public void beforeAll(ExtensionContext context) throws Exception { - if (!suiteStarted) { - suiteStarted = true; - // The following line registers a callback hook when the root test context is shut down - context.getRoot().getStore(Namespace.GLOBAL).put(UUID.randomUUID().toString(), this); - } - - startRegistryIfNeeded(context); - LOGGER.info("Registry app is running on {}", TestUtils.getRegistryV2ApiUrl()); - } - - @Override - public void beforeEach(ExtensionContext context) throws Exception { - startRegistryIfNeeded(context); - } - - @Override - public void afterEach(ExtensionContext context) throws Exception { - if (context.getExecutionException().isPresent()) { - LOGGER.error("Test failed with error:", context.getExecutionException().get()); - } - if (!TestUtils.isExternalRegistry() && context.getExecutionException().isPresent()) { - Path logsPath = RegistryUtils.getLogsPath(context.getRequiredTestClass(), context.getDisplayName()); - registry.stopAndCollectLogs(logsPath); - } - } - - @Override - public void afterAll(ExtensionContext context) throws Exception { - // do nothing because we want to start registry one time for all test suite - } - - @Override - public void close() throws Throwable { - if (!TestUtils.isExternalRegistry() && registry.isRunning()) { - LOGGER.info("Tear down registry deployment"); - try { - registry.stopAndCollectLogs(null); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - } - -} diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryFacade.java b/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryFacade.java deleted file mode 100644 index d9c965806b..0000000000 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryFacade.java +++ /dev/null @@ -1,1039 +0,0 @@ -/* - * Copyright 2020 Red Hat - * - * Licensed 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 io.apicurio.tests.common; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.text.SimpleDateFormat; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Properties; -import java.util.TimeZone; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import io.apicurio.tests.common.auth.JWKSMockServer; -import org.apache.kafka.clients.admin.AdminClient; -import org.apache.kafka.clients.admin.CreateTopicsResult; -import org.apache.kafka.clients.admin.KafkaAdminClient; -import org.apache.kafka.clients.admin.NewTopic; -import org.junit.jupiter.api.function.ThrowingConsumer; -import org.keycloak.admin.client.Keycloak; -import org.keycloak.admin.client.KeycloakBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.containers.output.OutputFrame.OutputType; - -import dasniko.testcontainers.keycloak.KeycloakContainer; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.common.executor.Exec; -import io.apicurio.tests.common.utils.RegistryUtils; -import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; - -public class RegistryFacade { - static final Logger LOGGER = LoggerFactory.getLogger(RegistryFacade.class); - - private static final String REGISTRY_JAR_PATH_FORMAT = "../../storage/%s/target/apicurio-registry-storage-%s-%s-runner.jar"; - private static final String REGISTRY_JAR_PATH = System.getenv().get("REGISTRY_JAR_PATH"); - private static final String PROJECT_VERSION = System.getProperty("project.version"); - - private LinkedList processes = new LinkedList<>(); - - private KeycloakContainer keycloakContainer; - private JWKSMockServer keycloakMock; - - private String tenantManagerUrl = "http://localhost:8585"; - - private static RegistryFacade instance; - - public static RegistryFacade getInstance() { - if (instance == null) { - instance = new RegistryFacade(); - } - return instance; - } - - private RegistryFacade() { - //hidden constructor, singleton class - } - - public String getTenantManagerUrl() { - return this.tenantManagerUrl; - } - - public String getAuthServerUrl() { - return keycloakContainer.getAuthServerUrl(); - } - - public Keycloak getKeycloakAdminClient() { - return KeycloakBuilder.builder() - .serverUrl(keycloakContainer.getAuthServerUrl()) - .realm("master") - .clientId("admin-cli") - .grantType("password") - .username(keycloakContainer.getAdminUsername()) - .password(keycloakContainer.getAdminPassword()) - .build(); - } - - public AuthServerInfo getAuthServerInfo() { - AuthServerInfo info = new AuthServerInfo(); - info.setAuthServerUrl(getMandatoryExternalRegistryEnvVar("AUTH_SERVER_URL", keycloakContainer.getAuthServerUrl())); - //info hardcoded in test-realm.json - info.setRealm(getMandatoryExternalRegistryEnvVar("AUTH_REALM", "registry")); - - info.setAdminClientId(getMandatoryExternalRegistryEnvVar("AUTH_ADMIN_CLIENT_ID", "registry-api")); - info.setAdminClientSecret(getMandatoryExternalRegistryEnvVar("AUTH_ADMIN_CLIENT_SECRET", "test1")); - - info.setDeveloperClientId(getMandatoryExternalRegistryEnvVar("AUTH_DEV_CLIENT_ID", "registry-api-dev")); - info.setDeveloperClientSecret(getMandatoryExternalRegistryEnvVar("AUTH_DEV_CLIENT_SECRET", "test1")); - - info.setReadOnlyClientId(getMandatoryExternalRegistryEnvVar("AUTH_READONLY_CLIENT_ID", "registry-api-readonly")); - info.setReadOnlyClientSecret(getMandatoryExternalRegistryEnvVar("AUTH_READONLY_CLIENT_SECRET", "test1")); - return info; - } - - public String getSourceRegistryUrl() { - if (TestUtils.isExternalRegistry()) { - String host = System.getenv().get("SOURCE_REGISTRY_HOST"); - if (host == null) { - throw new IllegalStateException("missing SOURCE_REGISTRY_HOST env var"); - } - Integer port = Integer.parseInt(System.getenv().getOrDefault("SOURCE_REGISTRY_PORT", "0")); - if (port == 0) { - throw new IllegalStateException("missing SOURCE_REGISTRY_PORT env var"); - } - return "http://" + host + ":" + port + "/apis/registry/v2"; - } else { - return "http://localhost:" + TestUtils.getRegistryPort() + "/apis/registry/v2"; - } - } - - public String getDestRegistryUrl() { - if (TestUtils.isExternalRegistry()) { - String host = System.getenv().get("DEST_REGISTRY_HOST"); - if (host == null) { - throw new IllegalStateException("missing DEST_REGISTRY_HOST env var"); - } - Integer port = Integer.parseInt(System.getenv().getOrDefault("DEST_REGISTRY_PORT", "0")); - if (port == 0) { - throw new IllegalStateException("missing DEST_REGISTRY_PORT env var"); - } - return "http://" + host + ":" + port + "/apis/registry/v2"; - } else { - int port = TestUtils.getRegistryPort() + 1; - return "http://localhost:" + port + "/apis/registry/v2"; - } - } - - public List getClusteredRegistryNodes() { - int c2port = TestUtils.getRegistryPort() + 1; - int c3port = c2port + 1; - return Arrays.asList("http://localhost:" + TestUtils.getRegistryPort(), "http://localhost:" + c2port, "http://localhost:" + c3port); - } - - public JWKSMockServer getMTOnlyKeycloakMock() { - return this.keycloakMock; - } - - public boolean isRunning() { - return !processes.isEmpty(); - } - - /** - * Method for starting the registry from a runner jar file. New process is created. - */ - public void start() throws Exception { - if (!processes.isEmpty()) { - throw new IllegalStateException("Registry is already running"); - } - - if (RegistryUtils.REGISTRY_STORAGE == null) { - throw new IllegalStateException("REGISTRY_STORAGE is mandatory, have you specified a profile with the storage to test? is the class an integration test *IT.java ?"); - } - - if (RegistryUtils.REGISTRY_STORAGE != RegistryStorageType.sql && Constants.MULTITENANCY.equals(RegistryUtils.TEST_PROFILE)) { - throw new IllegalStateException("Only sql storage allowed for multitenancy tests"); - } - - LOGGER.info("Deploying registry using storage {}, test profile {}", RegistryUtils.REGISTRY_STORAGE.name(), RegistryUtils.TEST_PROFILE); - - Map appEnv = initRegistryAppEnv(); - - if (RegistryUtils.TEST_PROFILE.contains(Constants.MIGRATION)) { - Map registry1Env = new HashMap<>(appEnv); - deployStorage(registry1Env); - runRegistry(registry1Env, "node-1", String.valueOf(TestUtils.getRegistryPort())); - Map registry2Env = new HashMap<>(appEnv); - deployStorage(registry2Env); - runRegistry(registry2Env, "node-2", String.valueOf(TestUtils.getRegistryPort() + 1)); - - } else if (Constants.MULTITENANCY.equals(RegistryUtils.TEST_PROFILE)) { - - runMultitenancySetup(appEnv); - - } else { - - deployStorage(appEnv); - - if (RegistryUtils.TEST_PROFILE.contains(Constants.CLUSTERED)) { - - Map node1Env = new HashMap<>(appEnv); - runRegistry(node1Env, "node-1" ,String.valueOf(TestUtils.getRegistryPort())); - - int c2port = TestUtils.getRegistryPort() + 1; - - Map node2Env = new HashMap<>(appEnv); - runRegistry(node2Env, "node-2" ,String.valueOf(c2port)); - - int c3port = c2port + 1; - - Map node3Env = new HashMap<>(appEnv); - runRegistry(node3Env, "node-3" ,String.valueOf(c3port)); - - } else { - if (Constants.AUTH.equals(RegistryUtils.TEST_PROFILE)) { - runKeycloak(appEnv); - } - - runRegistry(appEnv, "default", "8081"); - } - } - - } - - public Map initRegistryAppEnv() { - Map appEnv = new HashMap<>(); - appEnv.put("LOG_LEVEL", "DEBUG"); - appEnv.put("REGISTRY_LOG_LEVEL", "TRACE"); - - loadProvidedAppEnv(appEnv); - - return appEnv; - } - - public void runMultitenancySetup(Map appEnv) throws Exception { - - runMultitenancyInfra(appEnv); - - runRegistry(appEnv, "default", "8081"); - - } - - public void runMultitenancyInfra(Map appEnv) throws Exception { - deployStorage(appEnv); - - appEnv.put("REGISTRY_ENABLE_MULTITENANCY", "true"); - appEnv.put("REGISTRY_MULTITENANCY_REAPER_EVERY", "3s"); - appEnv.put("REGISTRY_MULTITENANCY_REAPER_PERIOD_SECONDS", "5"); - - //auth is always enabled in multitenancy tests - runKeycloakMock(appEnv); - - runTenantManager(appEnv); - - TestUtils.waitFor("Cannot connect to Tenant Manager on " + this.tenantManagerUrl + " in timeout!", - Constants.POLL_INTERVAL, Constants.TIMEOUT_FOR_REGISTRY_START_UP, () -> TestUtils.isReachable("localhost", 8585, "Tenant Manager")); - - TestUtils.waitFor("Tenant Manager reports is ready", - Constants.POLL_INTERVAL, Duration.ofSeconds(25).toMillis(), - () -> TestUtils.isReady(this.tenantManagerUrl, "/q/health/ready", false, "Tenant Manager"), - () -> TestUtils.isReady(this.tenantManagerUrl, "/q/health/ready", true, "Tenant Manager")); - } - - private void deployStorage(Map appEnv) throws Exception { - deployStorage(appEnv, RegistryUtils.REGISTRY_STORAGE); - } - - public void deployStorage(Map appEnv, RegistryStorageType storage) throws Exception { - switch (storage) { - case inmemory: - break; - case sql: - setupSQLStorage(appEnv); - break; - case kafkasql: - setupKafkaStorage(appEnv); - break; - } - } - - public void waitForRegistryReady() throws Exception { - - ThrowingConsumer nodeIsReady = (port) -> { - TestUtils.waitFor("Cannot connect to registries on node :" + port + " in timeout!", - Constants.POLL_INTERVAL, Constants.TIMEOUT_FOR_REGISTRY_START_UP, () -> TestUtils.isReachable("localhost", port, "registry node")); - - TestUtils.waitFor("Registry reports is ready", - Constants.POLL_INTERVAL, Constants.TIMEOUT_FOR_REGISTRY_READY, - () -> TestUtils.isReady("http://localhost:" + port, "/health/ready", false, "registry node"), - () -> TestUtils.isReady("http://localhost:" + port, "/health/ready", true, "registry node")); - }; - - if (RegistryUtils.TEST_PROFILE.contains(Constants.CLUSTERED)) { - - try { - nodeIsReady.accept(TestUtils.getRegistryPort()); - int c2port = TestUtils.getRegistryPort() + 1; - nodeIsReady.accept(c2port); - int c3port = c2port + 1; - nodeIsReady.accept(c3port); - } catch (Throwable e) { - throw new Exception(e); - } - - } if (RegistryUtils.TEST_PROFILE.contains(Constants.MIGRATION)) { - - try { - nodeIsReady.accept(TestUtils.getRegistryPort()); - int c2port = TestUtils.getRegistryPort() + 1; - nodeIsReady.accept(c2port); - } catch (Throwable e) { - throw new Exception(e); - } - - } else { - TestUtils.waitFor("Cannot connect to registries on " + TestUtils.getRegistryV1ApiUrl() + " in timeout!", - Constants.POLL_INTERVAL, Constants.TIMEOUT_FOR_REGISTRY_START_UP, TestUtils::isReachable); - - TestUtils.waitFor("Registry reports is ready", - Constants.POLL_INTERVAL, Constants.TIMEOUT_FOR_REGISTRY_READY, () -> TestUtils.isReady(false), () -> TestUtils.isReady(true)); - } - - } - - private void runTenantManager(Map registryAppEnv) throws Exception { - Map appEnv = new HashMap<>(); - appEnv.put("DATASOURCE_URL", registryAppEnv.get("REGISTRY_DATASOURCE_URL")); - appEnv.put("DATASOURCE_USERNAME", registryAppEnv.get("REGISTRY_DATASOURCE_USERNAME")); - appEnv.put("DATASOURCE_PASSWORD", registryAppEnv.get("REGISTRY_DATASOURCE_PASSWORD")); - - //auth is always enabled in multitenancy tests - appEnv.put("AUTH_ENABLED", "true"); - appEnv.put("KEYCLOAK_URL", registryAppEnv.get("KEYCLOAK_URL")); - appEnv.put("KEYCLOAK_REALM", registryAppEnv.get("KEYCLOAK_REALM")); - appEnv.put("KEYCLOAK_API_CLIENT_ID", registryAppEnv.get("KEYCLOAK_API_CLIENT_ID")); - appEnv.put("QUARKUS_OIDC_TLS_VERIFICATION", "none"); - - //config only for test purposes - //for TenantReaperIT , to enable tenant status transition from DELETED to READY - appEnv.put("ENABLE_TEST_STATUS_TRANSITION", "true"); - - appEnv.put("REGISTRY_ROUTE_URL", TestUtils.getRegistryBaseUrl()); - appEnv.put("LOG_LEVEL", "DEBUG"); - - var nativeExec = getTenantManagerNativeExecutablePath(); - - Exec executor = new Exec(); - if (nativeExec.isPresent()) { - LOGGER.info("Starting Tenant Manager Native Executable app from: {}", nativeExec.get()); - CompletableFuture.supplyAsync(() -> { - try { - - List cmd = new ArrayList<>(); - cmd.add(nativeExec.get()); - int timeout = executor.execute(cmd, appEnv); - return timeout == 0; - } catch (Exception e) { - LOGGER.error("Failed to start native tenant-manager.", e); - System.exit(1); - return false; - } - }, runnable -> new Thread(runnable).start()); - } else { - String path = getTenantManagerJarPath(); - LOGGER.info("Starting Tenant Manager app from: {}", path); - CompletableFuture.supplyAsync(() -> { - try { - - List cmd = new ArrayList<>(); - cmd.add("java"); - cmd.addAll(Arrays.asList( - // "-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005", - "-jar", path)); - int timeout = executor.execute(cmd, appEnv); - return timeout == 0; - } catch (Exception e) { - LOGGER.error("Failed to start tenant manager (could not find runner JAR).", e); - System.exit(1); - return false; - } - }, runnable -> new Thread(runnable).start()); - } - - processes.add(new RegistryTestProcess() { - - @Override - public String getName() { - return "tenant-manager"; - } - - @Override - public void close() throws Exception { - executor.stop(); - } - - @Override - public String getStdOut() { - return executor.stdOut(); - } - - @Override - public String getStdErr() { - return executor.stdErr(); - } - - @Override - public boolean isContainer() { - return false; - } - - }); - } - - private void runKeycloakMock(Map appEnv) throws Exception { - keycloakMock = new JWKSMockServer(); - keycloakMock.start(); - - appEnv.put("AUTH_ENABLED", "true"); - appEnv.put("ROLE_BASED_AUTHZ_ENABLED", "true"); - appEnv.put("ROLE_BASED_AUTHZ_SOURCE", "application"); - - appEnv.put("KEYCLOAK_URL", keycloakMock.authServerUrl); - appEnv.put("KEYCLOAK_REALM", keycloakMock.realm); - appEnv.put("KEYCLOAK_API_CLIENT_ID", keycloakMock.clientId); - appEnv.put("QUARKUS_OIDC_TLS_VERIFICATION", "none"); - - appEnv.put("TENANT_MANAGER_AUTH_URL", keycloakMock.authServerUrl); - appEnv.put("TENANT_MANAGER_REALM", keycloakMock.realm); - appEnv.put("TENANT_MANAGER_CLIENT_ID", keycloakMock.clientId); - appEnv.put("TENANT_MANAGER_CLIENT_SECRET", keycloakMock.clientSecret); - - processes.add(new RegistryTestProcess() { - - @Override - public String getName() { - return "keycloak-mock"; - } - - @Override - public void close() throws Exception { - keycloakMock.stop(); - } - - @Override - public String getStdOut() { - return ""; - } - - @Override - public String getStdErr() { - return ""; - } - - @Override - public boolean isContainer() { - return false; - } - - }); - } - - private void runKeycloak(Map appEnv) throws Exception { - - keycloakContainer = new KeycloakContainer() - .withRealmImportFile("test-realm.json"); - keycloakContainer.start(); - TestUtils.waitFor("Keycloak is running", - Constants.POLL_INTERVAL, Constants.TIMEOUT_FOR_REGISTRY_START_UP, keycloakContainer::isRunning); - - appEnv.put("AUTH_ENABLED", "true"); - appEnv.put("ROLE_BASED_AUTHZ_ENABLED", "true"); - - appEnv.put("KEYCLOAK_URL", keycloakContainer.getAuthServerUrl()); - appEnv.put("KEYCLOAK_REALM", "registry"); - appEnv.put("KEYCLOAK_API_CLIENT_ID", "registry-api"); - appEnv.put("QUARKUS_OIDC_TLS_VERIFICATION", "none"); - - - processes.add(new RegistryTestProcess() { - - @Override - public String getName() { - return "keycloak"; - } - - @Override - public void close() throws Exception { - keycloakContainer.close(); - } - - @Override - public String getStdOut() { - return keycloakContainer.getLogs(OutputType.STDOUT); - } - - @Override - public String getStdErr() { - return keycloakContainer.getLogs(OutputType.STDERR); - } - - @Override - public boolean isContainer() { - return true; - } - - }); - } - - @SuppressWarnings("rawtypes") - public void setupSQLStorage(Map appEnv) throws Exception { - - String noDocker = System.getenv(Constants.NO_DOCKER_ENV_VAR); - String currentEnv = System.getenv("CURRENT_ENV"); - - if (currentEnv != null && "mas".equals(currentEnv)) { - - //postgresql running in a pre-deployed container - - appEnv.put("REGISTRY_DATASOURCE_URL", "jdbc:postgresql://localhost:5432/test"); - appEnv.put("REGISTRY_DATASOURCE_USERNAME", "test"); - appEnv.put("REGISTRY_DATASOURCE_PASSWORD", "test"); - - processes.add(new RegistryTestProcess() { - - @Override - public String getName() { - return "container-postgresql"; - } - - @Override - public void close() throws Exception { - } - - @Override - public String getStdOut() { - return ""; - } - - @Override - public String getStdErr() { - return ""; - } - - @Override - public boolean isContainer() { - return false; - } - }); - - } else if (noDocker != null && noDocker.equals("true")) { - EmbeddedPostgres database = EmbeddedPostgres.start(); - - - String datasourceUrl = database.getJdbcUrl("postgres", "postgres"); - - appEnv.put("REGISTRY_DATASOURCE_URL", datasourceUrl); - appEnv.put("REGISTRY_DATASOURCE_USERNAME", "postgres"); - appEnv.put("REGISTRY_DATASOURCE_PASSWORD", "postgres"); - processes.add(new RegistryTestProcess() { - - @Override - public String getName() { - return "postgresql"; - } - - @Override - public void close() throws Exception { - database.close(); - } - - @Override - public String getStdOut() { - return ""; - } - - @Override - public String getStdErr() { - return ""; - } - - @Override - public boolean isContainer() { - return false; - } - }); - - } else { - - PostgreSQLContainer database = new PostgreSQLContainer<>("postgres:10.12"); - database.start(); - TestUtils.waitFor("Database is running", - Constants.POLL_INTERVAL, Constants.TIMEOUT_FOR_REGISTRY_START_UP, database::isRunning); - - String datasourceUrl = "jdbc:postgresql://" + database.getContainerIpAddress() + ":" + - database.getMappedPort(PostgreSQLContainer.POSTGRESQL_PORT) + "/" + database.getDatabaseName(); - appEnv.put("REGISTRY_DATASOURCE_URL", datasourceUrl); - appEnv.put("REGISTRY_DATASOURCE_USERNAME", database.getUsername()); - appEnv.put("REGISTRY_DATASOURCE_PASSWORD", database.getPassword()); - processes.add(new RegistryTestProcess() { - - @Override - public String getName() { - return "postgresql"; - } - - @Override - public void close() throws Exception { - database.close(); - } - - @Override - public String getStdOut() { - return database.getLogs(OutputType.STDOUT); - } - - @Override - public String getStdErr() { - return database.getLogs(OutputType.STDERR); - } - - @Override - public boolean isContainer() { - return true; - } - }); - - } - - } - - private void setupKafkaStorage(Map appEnv) throws TimeoutException, InterruptedException, ExecutionException { - - if (RegistryUtils.TEST_PROFILE.contains(Constants.MIGRATION)) { - KafkaFacade kafkaFacade = KafkaFacade.getInstance(); - var c = kafkaFacade.startNewKafka(); - - appEnv.put("REGISTRY_KAFKASQL_CONSUMER_STARTUPLAG", "3000"); //Three seconds startup lag to give time to the nodes being created to create the db. - appEnv.put("KAFKA_BOOTSTRAP_SERVERS", c.getBootstrapServers()); - processes.add(new RegistryTestProcess() { - - @Override - public String getName() { - return "kafka-" + c.getContainerId(); - } - - @Override - public void close() throws Exception { - c.close(); - } - - @Override - public String getStdOut() { - return c.getLogs(OutputType.STDOUT); - } - - @Override - public String getStdErr() { - return c.getLogs(OutputType.STDERR); - } - - @Override - public boolean isContainer() { - return true; - } - }); - - return; - } - - KafkaFacade kafkaFacade = KafkaFacade.getInstance(); - kafkaFacade.start(); - - Properties properties = new Properties(); - properties.put("bootstrap.servers", kafkaFacade.bootstrapServers()); - properties.put("connections.max.idle.ms", 10000); - properties.put("request.timeout.ms", 5000); - try (AdminClient client = KafkaAdminClient.create(properties)) { - CreateTopicsResult result = client.createTopics(Arrays.asList( - new NewTopic("storage-topic", 1, (short) 1), - new NewTopic("global-id-topic", 1, (short) 1) - )); - result.all().get(15, TimeUnit.SECONDS); - LOGGER.info("Topics created"); - } - - appEnv.put("KAFKA_BOOTSTRAP_SERVERS", kafkaFacade.bootstrapServers()); - processes.add(kafkaFacade); - } - - public void runRegistry(Map appEnv, String nameSuffix, String port) throws IOException { - appEnv.put("QUARKUS_HTTP_PORT", port); - if (RegistryUtils.DEPLOY_NATIVE_IMAGES.equals("true")) { - runRegistryNativeImage(appEnv, nameSuffix); - return; - } - String path = getJarPath(); - Exec executor = new Exec(); - LOGGER.info("Starting Registry app from: {} env: {}", path, appEnv); - CompletableFuture.supplyAsync(() -> { - try { - - List cmd = new ArrayList<>(); - cmd.add("java"); - cmd.addAll(Arrays.asList( - // "-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005", -// "-Dquarkus.http.port=8081", - "-jar", path)); - int timeout = executor.execute(cmd, appEnv); - return timeout == 0; - } catch (Exception e) { - LOGGER.error("Failed to start registry (could not find runner JAR).", e); - System.exit(1); - return false; - } - }, runnable -> new Thread(runnable).start()); - processes.add(new RegistryTestProcess() { - - @Override - public String getName() { - return "registry-" + nameSuffix; - } - - @Override - public void close() throws Exception { - executor.stop(); - } - - @Override - public String getStdOut() { - return executor.stdOut(); - } - - @Override - public String getStdErr() { - return executor.stdErr(); - } - - @Override - public boolean isContainer() { - return false; - } - - }); - } - - public void runContainer(Map appEnv, String name, GenericContainer container) { - container.withEnv(appEnv); - container.start(); - processes.add(new RegistryTestProcess() { - - @Override - public String getName() { - return name; - } - - @Override - public void close() throws Exception { - container.stop(); - } - - @Override - public String getStdOut() { - return container.getLogs(OutputType.STDOUT); - } - - @Override - public String getStdErr() { - return container.getLogs(OutputType.STDERR); - } - - @Override - public boolean isContainer() { - return true; - } - - }); - } - - public void stopProcess(Path logsPath, String name) throws Exception { - var process = processes.stream() - .filter(p -> p.getName().equals(name)) - .findFirst() - .get(); - stopAndCollectProcessLogs(logsPath, process); - processes.remove(process); - } - - private void runRegistryNativeImage(Map appEnv, String nameSuffix) throws IOException { - String path = getNativeExecutablePath(); - Exec executor = new Exec(); - LOGGER.info("Starting Registry Native Executable app from: {}", path); - CompletableFuture.supplyAsync(() -> { - try { - - List cmd = new ArrayList<>(); - cmd.add(path); - int timeout = executor.execute(cmd, appEnv); - return timeout == 0; - } catch (Exception e) { - LOGGER.error("Failed to start registry.", e); - System.exit(1); - return false; - } - }, runnable -> new Thread(runnable).start()); - processes.add(new RegistryTestProcess() { - - @Override - public String getName() { - return "registry-native-" + nameSuffix; - } - - @Override - public void close() throws Exception { - executor.stop(); - } - - @Override - public String getStdOut() { - return executor.stdOut(); - } - - @Override - public String getStdErr() { - return executor.stdErr(); - } - - @Override - public boolean isContainer() { - return false; - } - - }); - } - - private String findTenantManagerJar() { - LOGGER.info("Attempting to find tenant manager runner. Starting at cwd: " + new File("").getAbsolutePath()); - return findRunner(findTenantManagerModuleDir(), "jar"); - } - - private String findInMemoryRunner() { - LOGGER.info("Attempting to find runner. Starting at cwd: " + new File("").getAbsolutePath()); - return findRunner(findAppModuleDir(), "jar"); - } - - private String findRunner(File mavenModuleDir, String extension) { - File targetDir = new File(mavenModuleDir, "target"); - if (targetDir.isDirectory()) { - File[] files = targetDir.listFiles(); - for (File file : files) { - if (extension != null) { - if (file.getName().contains("-runner") && file.getName().endsWith("." + extension)) { - return file.getAbsolutePath(); - } - } else if (file.getName().endsWith("-runner")) { - return file.getAbsolutePath(); - } - } - } - return null; - } - - private File findTenantManagerModuleDir() { - File file = new File("../../multitenancy/api"); - if (file.isDirectory()) { - return file; - } - file = new File("../multitenancy/api"); - if (file.isDirectory()) { - return file; - } - file = new File("./multitenancy/api"); - if (file.isDirectory()) { - return file; - } - return null; - } - - private File findAppModuleDir() { - File file = new File("../../app"); - if (file.isDirectory()) { - return file; - } - file = new File("../app"); - if (file.isDirectory()) { - return file; - } - file = new File("./app"); - if (file.isDirectory()) { - return file; - } - return null; - } - - private boolean runnerExists(String path) throws IOException { - if (path == null) { - return false; - } - File file = new File(path); - return file.isFile(); - } - - private String getNativeExecutablePath() throws IOException { - String execPath; - String path; - if (RegistryStorageType.inmemory.equals(RegistryUtils.REGISTRY_STORAGE)) { - execPath = "../../app/target/apicurio-registry-app-%s-runner"; - path = String.format(execPath, PROJECT_VERSION); - } else { - execPath = "../../storage/%s/target/apicurio-registry-storage-%s-%s-runner"; - path = String.format(execPath, RegistryUtils.REGISTRY_STORAGE, RegistryUtils.REGISTRY_STORAGE, PROJECT_VERSION); - } - if (!runnerExists(path)) { - LOGGER.info("No runner JAR found. Throwing an exception."); - throw new IllegalStateException("Could not determine where to find the executable jar for the server. " + - "This may happen if you are using an IDE to debug."); - } - return path; - } - - private String getJarPath() throws IOException { - String path = REGISTRY_JAR_PATH; - LOGGER.info("Checking runner JAR path (1): " + path); - if (!runnerExists(path)) { - if (PROJECT_VERSION != null) { - path = String.format(REGISTRY_JAR_PATH_FORMAT, RegistryUtils.REGISTRY_STORAGE, RegistryUtils.REGISTRY_STORAGE, PROJECT_VERSION); - LOGGER.info("Checking runner JAR path (2): " + path); - } - } - if (!runnerExists(path)) { - path = findInMemoryRunner(); - LOGGER.info("Checking runner JAR path (3): " + path); - } - if (!runnerExists(path)) { - LOGGER.info("No runner JAR found. Throwing an exception."); - throw new IllegalStateException("Could not determine where to find the executable jar for the server. " + - "This may happen if you are using an IDE to debug."); - } - return path; - } - - private Optional getTenantManagerNativeExecutablePath() throws IOException { - String path = findRunner(findTenantManagerModuleDir(), null); - if (runnerExists(path)) { - return Optional.of(path); - } - return Optional.empty(); - } - - private String getTenantManagerJarPath() throws IOException { - String path = findTenantManagerJar(); - LOGGER.info("Checking tenant manager runner JAR path: " + path); - if (!runnerExists(path)) { - LOGGER.info("No runner JAR found. Throwing an exception."); - throw new IllegalStateException("Could not determine where to find the executable jar for the tenant manager app. " + - "This may happen if you are using an IDE to debug."); - } - return path; - } - - public void stopAndCollectLogs(Path logsPath) throws IOException { - LOGGER.info("Stopping registry"); - if (logsPath != null) { - Files.createDirectories(logsPath); - } - - processes.descendingIterator().forEachRemaining(p -> { - stopAndCollectProcessLogs(logsPath, p); - }); - processes.clear(); - } - - private void stopAndCollectProcessLogs(Path logsPath, RegistryTestProcess p) { - //registry and tenant manager processes are not a container and have to be stopped before being able to read log output - if (!p.isContainer()) { - try { - p.close(); - Thread.sleep(3000); - } catch (Exception e) { - LOGGER.error("error stopping registry", e); - } - } - if (logsPath != null) { - final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm"); - simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); - String currentDate = simpleDateFormat.format(Calendar.getInstance().getTime()); - - Path filePath = logsPath.resolve(currentDate + "-" + p.getName() + "-" + "stdout.log"); - LOGGER.info("Storing registry logs to " + filePath.toString()); - TestUtils.writeFile(filePath, p.getStdOut()); - String stdErr = p.getStdErr(); - if (stdErr != null && !stdErr.isEmpty()) { - TestUtils.writeFile(logsPath.resolve(currentDate + "-" + p.getName() + "-" + "stderr.log"), stdErr); - } - } - if (!p.getName().equals("registry")) { - try { - p.close(); - } catch (Exception e) { - LOGGER.error("error stopping registry", e); - } - } - } - - private String getMandatoryExternalRegistryEnvVar(String envVar, String localValue) { - if (TestUtils.isExternalRegistry()) { - String var = System.getenv().get(envVar); - if (var == null) { - throw new IllegalStateException("missing " + envVar + " env var"); - } - return var; - } else { - return localValue; - } - } - - /** - * Reads environment variables with the prefix TEST_APP_ENV - */ - private void loadProvidedAppEnv(Map appEnv) { - - String envPrefix = "TEST_APP_ENV_"; - - System.getenv() - .entrySet() - .stream() - .filter(env -> env.getKey().startsWith(envPrefix)) - .forEach(env -> { - appEnv.put(env.getKey().substring(envPrefix.length()), env.getValue()); - }); - - } - -} \ No newline at end of file diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/auth/CustomJWTAuth.java b/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/auth/CustomJWTAuth.java deleted file mode 100644 index fd615a9023..0000000000 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/auth/CustomJWTAuth.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests.common.auth; - -import java.util.Map; - -import io.apicurio.rest.client.auth.Auth; -import io.smallrye.jwt.build.Jwt; - -/** - * @author Fabian Martinez - */ -public class CustomJWTAuth implements Auth { - - public static final String RH_ORG_ID_CLAIM = "rh-org-id"; - public static final String ORG_ID = "org_id"; - - private String username; - private String organizationId; - - public CustomJWTAuth(String username, String organizationId) { - this.username = username; - this.organizationId = organizationId; - } - - @Override - public void apply(Map requestHeaders) { - String token = Jwt.preferredUserName(username) - .claim(RH_ORG_ID_CLAIM, organizationId) - .claim(ORG_ID, organizationId) - .jws() - .keyId("1") - .sign(); - - requestHeaders.put("Authorization", "Bearer " + token); - } - -} diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/auth/JWKSMockServer.java b/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/auth/JWKSMockServer.java deleted file mode 100644 index b6a44896ed..0000000000 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/auth/JWKSMockServer.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests.common.auth; - -import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.*; -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.urlEqualTo; -import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; -import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; -import java.util.UUID; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.github.tomakehurst.wiremock.WireMockServer; -import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder; -import com.github.tomakehurst.wiremock.client.WireMock; -import io.smallrye.jwt.build.Jwt; - -/** - * @author Fabian Martinez - */ -public class JWKSMockServer { - - static final Logger LOGGER = LoggerFactory.getLogger(JWKSMockServer.class); - - private WireMockServer server; - - public String authServerUrl; - public String realm = "test"; - public String tokenEndpoint; - - public String clientId = UUID.randomUUID().toString(); - public String clientSecret = UUID.randomUUID().toString(); - - public void start() { - - server = new WireMockServer( - wireMockConfig() - .dynamicPort()); - server.start(); - - server.stubFor( - get(urlMatching("/auth/realms/" + realm + "/.well-known/uma2-configuration")) - .willReturn(wellKnownResponse())); - server.stubFor( - get(urlMatching("/auth/realms/" + realm + "/.well-known/openid-configuration")) - .willReturn(wellKnownResponse())); - - server.stubFor( - get(urlEqualTo("/auth/realms/" + realm + "/protocol/openid-connect/certs")) - .willReturn(aResponse() - .withHeader("Content-Type", "application/json") - .withBody("{\n" + - " \"keys\" : [\n" + - " {\n" + - " \"kid\": \"1\",\n" + - " \"kty\":\"RSA\",\n" + - " \"n\":\"iJw33l1eVAsGoRlSyo-FCimeOc-AaZbzQ2iESA3Nkuo3TFb1zIkmt0kzlnWVGt48dkaIl13Vdefh9hqw_r9yNF8xZqX1fp0PnCWc5M_TX_ht5fm9y0TpbiVmsjeRMWZn4jr3DsFouxQ9aBXUJiu26V0vd2vrECeeAreFT4mtoHY13D2WVeJvboc5mEJcp50JNhxRCJ5UkY8jR_wfUk2Tzz4-fAj5xQaBccXnqJMu_1C6MjoCEiB7G1d13bVPReIeAGRKVJIF6ogoCN8JbrOhc_48lT4uyjbgnd24beatuKWodmWYhactFobRGYo5551cgMe8BoxpVQ4to30cGA0qjQ\",\n" - + - " \"e\":\"AQAB\"\n" + - " }\n" + - " ]\n" + - "}"))); - - server.stubFor(WireMock.post("/auth/realms/" + realm + "/protocol/openid-connect/token/") -// .withQueryParam("grant_type", equalTo("client_credentials")) - -// .withBasicAuth(clientId, clientSecret) - -// .withRequestBody(containing(clientId)) -// .withRequestBody(containing(clientSecret)) - .withRequestBody(WireMock.containing("grant_type=client_credentials")) - .withRequestBody(WireMock.containing("client_id=" + clientId)) - .withRequestBody(WireMock.containing("client_secret=" + clientSecret)) - .willReturn(WireMock.aResponse() - .withHeader("Content-Type", "application/json") - .withBody("{\n" + - " \"access_token\": \"" - + getAccessToken(clientId) + "\",\n" + - " \"refresh_token\": \"07e08903-1263-4dd1-9fd1-4a59b0db5283\",\n" + - " \"token_type\": \"bearer\"\n" + - "}"))); - - this.authServerUrl = server.baseUrl() + "/auth"; - LOGGER.info("Keycloak started in mock mode: {}", authServerUrl); - this.tokenEndpoint = authServerUrl + "/realms/" + realm + "/protocol/openid-connect/token"; - } - - public void addStubForTenant(String tenantClientId, String tenantClientSecret, String organizationId) { - server.stubFor(WireMock.post("/auth/realms/" + realm + "/protocol/openid-connect/token/") - .withRequestBody(WireMock.containing("grant_type=client_credentials")) - .withRequestBody(WireMock.containing("client_id=" + tenantClientId)) - .withRequestBody(WireMock.containing("client_secret=" + tenantClientSecret)) - .willReturn(WireMock.aResponse() - .withHeader("Content-Type", "application/json") - .withBody("{\n" + - " \"access_token\": \"" - + generateJwtToken(tenantClientId, organizationId) + "\",\n" + - " \"refresh_token\": \"07e08903-1263-4dd1-9fd1-4a59b0db5283\",\n" + - " \"token_type\": \"bearer\"\n" + - "}"))); - } - - private ResponseDefinitionBuilder wellKnownResponse() { - return aResponse() - .withHeader("Content-Type", "application/json") - .withBody("{\n" + - " \"jwks_uri\": \"" + server.baseUrl() - + "/auth/realms/" + realm + "/protocol/openid-connect/certs\",\n" - + " \"token_endpoint\": \"" + server.baseUrl() + "/auth/realms/" + realm + "/protocol/openid-connect/token\" " - + "}"); - } - - - private String getAccessToken(String userName) { - return generateJwtToken(userName, null); - } - - private String generateJwtToken(String userName, String organizationId) { - var b = Jwt.preferredUserName(userName); - if (organizationId != null) { - b.claim(CustomJWTAuth.RH_ORG_ID_CLAIM, organizationId); - } - return b - .jws() - .keyId("1") - .sign(); - } - - public synchronized void stop() { - if (server != null) { - server.stop(); - LOGGER.info("Keycloak was shut down"); - server = null; - } - } - - -} diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/executor/Exec.java b/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/executor/Exec.java deleted file mode 100644 index b4855e4b9c..0000000000 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/executor/Exec.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright 2020 Red Hat - * - * Licensed 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 io.apicurio.tests.common.executor; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Scanner; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.regex.Pattern; - -import static java.lang.String.join; - -/** - * Class provide execution of external command - */ -public class Exec { - private static final Logger LOGGER = LoggerFactory.getLogger(Exec.class); - private static final Pattern PATH_SPLITTER = Pattern.compile(System.getProperty("path.separator")); - - public Process process; - private String stdOut; - private String stdErr; - private StreamGobbler stdOutReader; - private StreamGobbler stdErrReader; - private Path logPath; - private boolean appendLineSeparator; - - public Exec() { - this.appendLineSeparator = true; - } - - public Exec(Path logPath) { - this.appendLineSeparator = true; - this.logPath = logPath; - } - - public Exec(boolean appendLineSeparator) { - this.appendLineSeparator = appendLineSeparator; - } - - /** - * Getter for stdOutput - * - * @return string stdOut - */ - public String stdOut() { - return stdOut; - } - - /** - * Getter for stdErrorOutput - * - * @return string stdErr - */ - public String stdErr() { - return stdErr; - } - - public boolean isRunning() { - return process.isAlive(); - } - - public int getRetCode() { - LOGGER.info("Process: {}", process); - if (isRunning()) { - return -1; - } else { - return process.exitValue(); - } - } - - - /** - * Method executes external command - * - * @param command arguments for command - * @return execution results - */ - public int execute(String... command) throws InterruptedException, ExecutionException, IOException { - return execute(Arrays.asList(command)); - } - - /** - * Method executes external command - * - * @param command arguments for command - * @return execution results - */ - public int execute(List command) throws InterruptedException, ExecutionException, IOException { - return execute(command, null); - } - - /** - * Method executes external command - * - * @param command arguments for command - * @param environmentVariables environment variables to be set - * @return execution results - */ - public int execute(List command, Map environmentVariables) throws InterruptedException, ExecutionException, IOException { - return execute(null, command, environmentVariables, 0); - } - - /** - * Method executes external command - * - * @param command arguments for command - * @return execution results - */ - public int execute(String input, List command) throws InterruptedException, ExecutionException, IOException { - return execute(input, command, null, 0); - } - - /** - * Method executes external command - * - * @param commands arguments for command - * @param timeout timeout in ms for kill - * @return returns ecode of execution - * @throws IOException - * @throws InterruptedException - * @throws ExecutionException - */ - public int execute(String input, List commands, Map environmentVariables, int timeout) throws IOException, InterruptedException, ExecutionException { - LOGGER.trace("Running command - " + join(" ", commands.toArray(new String[0]))); - ProcessBuilder builder = new ProcessBuilder(); - builder.command(commands); - builder.directory(new File(System.getProperty("user.dir"))); - if (environmentVariables != null) { - builder.environment().putAll(environmentVariables); - } - process = builder.start(); - OutputStream outputStream = process.getOutputStream(); - if (input != null) { - LOGGER.trace("With stdin {}", input); - outputStream.write(input.getBytes(Charset.defaultCharset())); - } - // Close subprocess' stdin - outputStream.close(); - - Future output = readStdOutput(); - Future error = readStdError(); - - int retCode = 1; - if (timeout > 0) { - if (process.waitFor(timeout, TimeUnit.MILLISECONDS)) { - retCode = process.exitValue(); - } else { - process.destroyForcibly(); - } - } else { - retCode = process.waitFor(); - } - - try { - stdOut = output.get(500, TimeUnit.MILLISECONDS); - } catch (TimeoutException ex) { - output.cancel(true); - stdOut = stdOutReader.getData(); - } - - try { - stdErr = error.get(500, TimeUnit.MILLISECONDS); - } catch (TimeoutException ex) { - error.cancel(true); - stdErr = stdErrReader.getData(); - } - storeOutputsToFile(); - - return retCode; - } - - /** - * Method kills process - */ - public void stop() { - process.destroyForcibly(); - stdOut = stdOutReader.getData(); - stdErr = stdErrReader.getData(); - } - - /** - * Get standard output of execution - * - * @return future string output - */ - private Future readStdOutput() { - stdOutReader = new StreamGobbler(process.getInputStream()); - return stdOutReader.read(); - } - - /** - * Get standard error output of execution - * - * @return future string error output - */ - private Future readStdError() { - stdErrReader = new StreamGobbler(process.getErrorStream()); - return stdErrReader.read(); - } - - /** - * Get stdOut and stdErr and store it into files - */ - private void storeOutputsToFile() { - if (logPath != null) { - try { - Files.createDirectories(logPath); - Files.write(Paths.get(logPath.toString(), "stdOutput.log"), stdOut.getBytes(Charset.defaultCharset())); - Files.write(Paths.get(logPath.toString(), "stdError.log"), stdErr.getBytes(Charset.defaultCharset())); - } catch (Exception ex) { - LOGGER.warn("Cannot save output of execution: " + ex.getMessage()); - } - } - } - - /** - * Check if command is executable - * @param cmd command - * @return true.false - */ - public static boolean isExecutableOnPath(String cmd) { - for (String dir : PATH_SPLITTER.split(System.getenv("PATH"))) { - if (new File(dir, cmd).canExecute()) { - return true; - } - } - return false; - } - - /** - * Class represent async reader - */ - class StreamGobbler { - private InputStream is; - private StringBuilder data = new StringBuilder(); - - /** - * Constructor of StreamGobbler - * - * @param is input stream for reading - */ - StreamGobbler(InputStream is) { - this.is = is; - } - - /** - * Return data from stream sync - * - * @return string of data - */ - public String getData() { - return data.toString(); - } - - /** - * read method - * - * @return return future string of output - */ - public Future read() { - return CompletableFuture.supplyAsync(() -> { - Scanner scanner = new Scanner(is, StandardCharsets.UTF_8.name()); - try { - while (scanner.hasNextLine()) { - data.append(scanner.nextLine()); - if (appendLineSeparator) { - data.append(System.getProperty("line.separator")); - } - } - scanner.close(); - return data.toString(); - } catch (Exception e) { - throw new CompletionException(e); - } finally { - scanner.close(); - } - }, runnable -> new Thread(runnable).start()); - } - } - -} \ No newline at end of file diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/executor/ExecResult.java b/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/executor/ExecResult.java deleted file mode 100644 index 1012e53f5e..0000000000 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/executor/ExecResult.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020 Red Hat - * - * Licensed 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 io.apicurio.tests.common.executor; - -import java.io.Serializable; - -public class ExecResult implements Serializable { - - private static final long serialVersionUID = 1L; - - private final int returnCode; - private final String stdOut; - private final String stdErr; - - ExecResult(int returnCode, String stdOut, String stdErr) { - this.returnCode = returnCode; - this.stdOut = stdOut; - this.stdErr = stdErr; - } - - public int exitStatus() { - return returnCode; - } - - public String out() { - return stdOut; - } - - public String err() { - return stdErr; - } -} diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/kafka/EmbeddedKafka.java b/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/kafka/EmbeddedKafka.java deleted file mode 100644 index b5479d4b4c..0000000000 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/kafka/EmbeddedKafka.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests.common.kafka; - -import java.io.File; -import java.io.IOException; -import java.util.Properties; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.debezium.kafka.KafkaCluster; -import io.debezium.util.Testing; - -/** - * @author Fabian Martinez - */ -public class EmbeddedKafka { - static final Logger LOGGER = LoggerFactory.getLogger(EmbeddedKafka.class); - - protected static final int ZOOKEEPER_PORT = 2181; - protected static final int KAFKA_PORT = 9092; - protected static final String DATA_DIR = "cluster"; - - private static File dataDir; - private KafkaCluster kafkaCluster; - - public String bootstrapServers() { - return kafkaCluster.brokerList(); - } - - public void start() { - try { - dataDir = Testing.Files.createTestingDirectory(DATA_DIR); - - Properties props = new Properties(); - props.put("auto.create.topics.enable", "false"); - - kafkaCluster = new KafkaCluster() - .usingDirectory(dataDir) - .withPorts(ZOOKEEPER_PORT, KAFKA_PORT) - .withKafkaConfiguration(props) - .deleteDataPriorToStartup(true) - .addBrokers(1) - .startup(); - - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void stop() { - if (kafkaCluster != null) { - LOGGER.info("Shutting down Kafka cluster"); - kafkaCluster.shutdown(); - kafkaCluster = null; - boolean delete = dataDir.delete(); - // If files are still locked and a test fails: delete on exit to allow subsequent test execution - if (!delete) { - dataDir.deleteOnExit(); - } - LOGGER.info("Kafka cluster and all related data was deleted"); - } - } -} diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/kafka/TrustAllSslEngineFactory.java b/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/kafka/TrustAllSslEngineFactory.java deleted file mode 100644 index f6ad7bc8e7..0000000000 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/kafka/TrustAllSslEngineFactory.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests.common.kafka; - -import java.io.IOException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.NoSuchAlgorithmException; -import java.security.cert.X509Certificate; -import java.util.Map; -import java.util.Set; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import org.apache.kafka.common.security.auth.SslEngineFactory; - -/** - * @author Fabian Martinez - */ -public class TrustAllSslEngineFactory implements SslEngineFactory { - - @Override - public SSLEngine createClientSslEngine(String peerHost, int peerPort, String endpointIdentification) { - try { - TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { - @Override - public X509Certificate[] getAcceptedIssuers() { return null; } - @Override - public void checkClientTrusted(X509Certificate[] certs, String authType) { } - @Override - public void checkServerTrusted(X509Certificate[] certs, String authType) { } - }}; - SSLContext sc = SSLContext.getInstance("SSL"); - sc.init(null, trustAllCerts, new java.security.SecureRandom()); - SSLEngine sslEngine = sc.createSSLEngine(peerHost, peerPort); - sslEngine.setUseClientMode(true); - return sslEngine; - } catch (NoSuchAlgorithmException | KeyManagementException e) { - throw new RuntimeException(e); - } - } - - @Override - public SSLEngine createServerSslEngine(String peerHost, int peerPort) { - return null; - } - - @Override - public boolean shouldBeRebuilt(Map nextConfigs) { - return false; - } - - @Override - public Set reconfigurableConfigs() { - return null; - } - - @Override - public KeyStore keystore() { - return null; - } - - @Override - public KeyStore truststore() { - return null; - } - - @Override - public void close() throws IOException { - - } - - @Override - public void configure(Map configs) { - - } - -} diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/RegistryUtils.java b/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/RegistryUtils.java deleted file mode 100644 index c7b6310cc5..0000000000 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/RegistryUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2020 Red Hat - * - * Licensed 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 io.apicurio.tests.common.utils; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Optional; -import io.apicurio.tests.common.RegistryStorageType; - -public class RegistryUtils { - - public static RegistryStorageType REGISTRY_STORAGE = - Optional.ofNullable(System.getProperty("test.storage")) - .map(RegistryStorageType::valueOf) - .orElse(null); - - public static final String TEST_PROFILE = - Optional.ofNullable(System.getProperty("groups")) - .orElse(""); - - public static final String DEPLOY_NATIVE_IMAGES = - Optional.ofNullable(System.getProperty("testNative")) - .orElse(""); - - - private RegistryUtils() { - //utils class - } - - public static Path getLogsPath(Class testClass, String testName) { - return Paths.get("target/logs/", REGISTRY_STORAGE.name(), testClass.getName(), testName); - } - -} \ No newline at end of file diff --git a/integration-tests/integration-tests-common/src/main/resources/logback.xml b/integration-tests/integration-tests-common/src/main/resources/logback.xml deleted file mode 100644 index df7f8637cd..0000000000 --- a/integration-tests/integration-tests-common/src/main/resources/logback.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - %d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z',GMT} %highlight(%-5p) [%c{0}] %m%n - - - - - - - - \ No newline at end of file diff --git a/integration-tests/integration-tests-common/src/main/resources/test-realm.json b/integration-tests/integration-tests-common/src/main/resources/test-realm.json deleted file mode 100644 index 88053fdfa2..0000000000 --- a/integration-tests/integration-tests-common/src/main/resources/test-realm.json +++ /dev/null @@ -1,2491 +0,0 @@ -{ - "id": "registry", - "realm": "registry", - "notBefore": 1600933598, - "revokeRefreshToken": false, - "refreshTokenMaxReuse": 0, - "accessTokenLifespan": 300, - "accessTokenLifespanForImplicitFlow": 900, - "ssoSessionIdleTimeout": 1800, - "ssoSessionMaxLifespan": 36000, - "ssoSessionIdleTimeoutRememberMe": 0, - "ssoSessionMaxLifespanRememberMe": 0, - "offlineSessionIdleTimeout": 2592000, - "offlineSessionMaxLifespanEnabled": false, - "offlineSessionMaxLifespan": 5184000, - "clientSessionIdleTimeout": 0, - "clientSessionMaxLifespan": 0, - "accessCodeLifespan": 60, - "accessCodeLifespanUserAction": 300, - "accessCodeLifespanLogin": 1800, - "actionTokenGeneratedByAdminLifespan": 43200, - "actionTokenGeneratedByUserLifespan": 300, - "enabled": true, - "sslRequired": "external", - "registrationAllowed": true, - "registrationEmailAsUsername": false, - "rememberMe": true, - "verifyEmail": false, - "loginWithEmailAllowed": true, - "duplicateEmailsAllowed": false, - "resetPasswordAllowed": true, - "editUsernameAllowed": false, - "bruteForceProtected": false, - "permanentLockout": false, - "maxFailureWaitSeconds": 900, - "minimumQuickLoginWaitSeconds": 60, - "waitIncrementSeconds": 60, - "quickLoginCheckMilliSeconds": 1000, - "maxDeltaTimeSeconds": 43200, - "failureFactor": 30, - "roles": { - "realm": [ - { - "id": "91363f21-2a57-4d65-954b-b3cd45d9f69c", - "name": "sr-admin", - "composite": false, - "clientRole": false, - "containerId": "registry", - "attributes": {} - }, - { - "id": "b2a0eee7-c761-49a1-9426-441d467f3f98", - "name": "offline_access", - "description": "${role_offline-access}", - "composite": false, - "clientRole": false, - "containerId": "registry", - "attributes": {} - }, - { - "id": "1ffdda65-2476-4ad5-b1e8-9f8af44a897b", - "name": "uma_authorization", - "description": "${role_uma_authorization}", - "composite": false, - "clientRole": false, - "containerId": "registry", - "attributes": {} - }, - { - "id": "2c0937ba-7b1f-424c-927c-33cd2ccfdc62", - "name": "sr-developer", - "composite": false, - "clientRole": false, - "containerId": "registry", - "attributes": {} - }, - { - "id": "a06b0184-e5bc-44c2-ae5b-4315754405f1", - "name": "sr-readonly", - "composite": false, - "clientRole": false, - "containerId": "registry", - "attributes": {} - }, - { - "id": "43dd3a54-4447-4703-ad0e-cd558f78c803", - "name": "User", - "composite": false, - "clientRole": false, - "containerId": "registry", - "attributes": {} - } - ], - "client": { - "realm-management": [ - { - "id": "dcd9e6f5-3158-4e90-ba06-e5e80e0fa05c", - "name": "query-users", - "description": "${role_query-users}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "0b4d5891-c2d9-409d-b4bd-b5daa11e059e", - "name": "view-identity-providers", - "description": "${role_view-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "2fee03d5-f4da-418f-843e-0a70cba351c7", - "name": "view-clients", - "description": "${role_view-clients}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-clients" - ] - } - }, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "82e5542a-8ec4-4e76-aa2f-75c0eb707aad", - "name": "manage-realm", - "description": "${role_manage-realm}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "4d0d41a7-ac3f-47c6-a227-de0dc1c861de", - "name": "query-groups", - "description": "${role_query-groups}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "4d69772c-08d4-4735-954c-4115788cecbc", - "name": "view-events", - "description": "${role_view-events}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "8a79c5f9-2d14-44e4-b2bc-7e4cb955b721", - "name": "query-realms", - "description": "${role_query-realms}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "0b54c521-9672-49b5-89ab-603fe4da9693", - "name": "manage-events", - "description": "${role_manage-events}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "7a9c60b9-f2e6-4fec-ac85-7b3633a0f116", - "name": "realm-admin", - "description": "${role_realm-admin}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-users", - "view-identity-providers", - "view-clients", - "manage-realm", - "query-groups", - "view-events", - "query-realms", - "manage-events", - "view-users", - "manage-authorization", - "view-authorization", - "manage-identity-providers", - "impersonation", - "query-clients", - "view-realm", - "manage-clients", - "create-client", - "manage-users" - ] - } - }, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "f7c5550f-8233-4347-967d-4905cbd36cec", - "name": "view-users", - "description": "${role_view-users}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-users", - "query-groups" - ] - } - }, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "3fa4a674-d449-4576-b207-f89e556ba617", - "name": "manage-authorization", - "description": "${role_manage-authorization}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "05c8c44f-8554-4a91-b9cb-be6995144040", - "name": "view-authorization", - "description": "${role_view-authorization}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "a0c6b281-3915-45c2-9af7-d7d4f669419a", - "name": "manage-identity-providers", - "description": "${role_manage-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "e91f859e-d5c3-48d6-b0b0-5ff2710db3c9", - "name": "impersonation", - "description": "${role_impersonation}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "e6e6d63d-d161-444f-a58d-30875b076d16", - "name": "query-clients", - "description": "${role_query-clients}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "e50b557e-c79e-4e5a-92ee-a56b9c3925e1", - "name": "view-realm", - "description": "${role_view-realm}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "4c592e93-ba00-4661-af7d-bc50b800c060", - "name": "manage-clients", - "description": "${role_manage-clients}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "34b1cafe-ee16-42d0-9ec1-c6829e01f78c", - "name": "create-client", - "description": "${role_create-client}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - }, - { - "id": "7d1d9c1e-6c1c-41eb-b8d9-6460e4d243f0", - "name": "manage-users", - "description": "${role_manage-users}", - "composite": false, - "clientRole": true, - "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "attributes": {} - } - ], - "apicurio-registry": [], - "security-admin-console": [], - "admin-cli": [], - "registry-api-dev": [], - "account-console": [], - "registry-api-readonly": [], - "broker": [ - { - "id": "1ec1b34a-682d-44e7-b1fb-1d235b27b9d0", - "name": "read-token", - "description": "${role_read-token}", - "composite": false, - "clientRole": true, - "containerId": "717c272b-ed48-4d5a-a3cb-da5d3d3ba528", - "attributes": {} - } - ], - "account": [ - { - "id": "a49e7c09-b2df-4468-96f0-65b8591774ad", - "name": "manage-account-links", - "description": "${role_manage-account-links}", - "composite": false, - "clientRole": true, - "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", - "attributes": {} - }, - { - "id": "b6e07306-8781-4538-800b-32b2ffc5d57c", - "name": "view-applications", - "description": "${role_view-applications}", - "composite": false, - "clientRole": true, - "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", - "attributes": {} - }, - { - "id": "6b67af9e-5c96-4944-8189-7d6c7ecc1f80", - "name": "view-consent", - "description": "${role_view-consent}", - "composite": false, - "clientRole": true, - "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", - "attributes": {} - }, - { - "id": "aa763dea-9699-4899-95bc-f2cef6692b1d", - "name": "manage-consent", - "description": "${role_manage-consent}", - "composite": true, - "composites": { - "client": { - "account": [ - "view-consent" - ] - } - }, - "clientRole": true, - "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", - "attributes": {} - }, - { - "id": "aad246c6-eb26-4cfd-b840-e113021f5b9b", - "name": "view-profile", - "description": "${role_view-profile}", - "composite": false, - "clientRole": true, - "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", - "attributes": {} - }, - { - "id": "de065b56-c31c-41df-b110-186a798d7f17", - "name": "manage-account", - "description": "${role_manage-account}", - "composite": true, - "composites": { - "client": { - "account": [ - "manage-account-links" - ] - } - }, - "clientRole": true, - "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", - "attributes": {} - } - ], - "registry-api": [ - { - "id": "e35b5b5f-8203-4f4c-8e9c-57cf1f0e86f5", - "name": "registry-user", - "composite": false, - "clientRole": true, - "containerId": "69afe60b-7329-440a-9b4c-0ebec33d8902", - "attributes": {} - }, - { - "id": "355ceac5-add9-4db2-a997-39ca80baf58d", - "name": "registry-admin", - "composite": false, - "clientRole": true, - "containerId": "69afe60b-7329-440a-9b4c-0ebec33d8902", - "attributes": {} - } - ] - } - }, - "groups": [], - "defaultRoles": [ - "offline_access", - "uma_authorization", - "User" - ], - "requiredCredentials": [ - "password" - ], - "otpPolicyType": "totp", - "otpPolicyAlgorithm": "HmacSHA1", - "otpPolicyInitialCounter": 0, - "otpPolicyDigits": 6, - "otpPolicyLookAheadWindow": 1, - "otpPolicyPeriod": 30, - "otpSupportedApplications": [ - "FreeOTP", - "Google Authenticator" - ], - "webAuthnPolicyRpEntityName": "keycloak", - "webAuthnPolicySignatureAlgorithms": [ - "ES256" - ], - "webAuthnPolicyRpId": "", - "webAuthnPolicyAttestationConveyancePreference": "not specified", - "webAuthnPolicyAuthenticatorAttachment": "not specified", - "webAuthnPolicyRequireResidentKey": "not specified", - "webAuthnPolicyUserVerificationRequirement": "not specified", - "webAuthnPolicyCreateTimeout": 0, - "webAuthnPolicyAvoidSameAuthenticatorRegister": false, - "webAuthnPolicyAcceptableAaguids": [], - "webAuthnPolicyPasswordlessRpEntityName": "keycloak", - "webAuthnPolicyPasswordlessSignatureAlgorithms": [ - "ES256" - ], - "webAuthnPolicyPasswordlessRpId": "", - "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified", - "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified", - "webAuthnPolicyPasswordlessRequireResidentKey": "not specified", - "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified", - "webAuthnPolicyPasswordlessCreateTimeout": 0, - "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false, - "webAuthnPolicyPasswordlessAcceptableAaguids": [], - "users": [ - { - "id": "70dbaf4a-fcef-449c-9184-121b6cedb115", - "createdTimestamp": 1607594319706, - "username": "service-account-registry-api", - "enabled": true, - "totp": false, - "emailVerified": false, - "serviceAccountClientId": "registry-api", - "disableableCredentialTypes": [], - "requiredActions": [], - "realmRoles": [ - "sr-admin", - "offline_access", - "uma_authorization", - "User" - ], - "clientRoles": { - "account": [ - "view-applications", - "view-profile", - "manage-account" - ] - }, - "notBefore": 0, - "groups": [] - }, - { - "id": "0f1c31e8-a357-4f05-90cc-3374973b6088", - "createdTimestamp": 1608543288931, - "username": "service-account-registry-api-dev", - "enabled": true, - "totp": false, - "emailVerified": false, - "serviceAccountClientId": "registry-api-dev", - "disableableCredentialTypes": [], - "requiredActions": [], - "realmRoles": [ - "offline_access", - "uma_authorization", - "sr-developer", - "User" - ], - "clientRoles": { - "account": [ - "view-applications", - "view-profile", - "manage-account" - ] - }, - "notBefore": 0, - "groups": [] - }, - { - "id": "06fec980-2e11-4c7f-a8fb-3d285f30b0b0", - "createdTimestamp": 1608543552621, - "username": "service-account-registry-api-readonly", - "enabled": true, - "totp": false, - "emailVerified": false, - "serviceAccountClientId": "registry-api-readonly", - "disableableCredentialTypes": [], - "requiredActions": [], - "realmRoles": [ - "offline_access", - "uma_authorization", - "sr-readonly", - "User" - ], - "clientRoles": { - "account": [ - "view-applications", - "view-profile", - "manage-account" - ] - }, - "notBefore": 0, - "groups": [] - } - ], - "scopeMappings": [ - { - "clientScope": "offline_access", - "roles": [ - "offline_access" - ] - } - ], - "clientScopeMappings": { - "account": [ - { - "client": "account-console", - "roles": [ - "manage-account" - ] - } - ] - }, - "clients": [ - { - "id": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", - "clientId": "account", - "name": "${client_account}", - "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/registry/account/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "test1", - "defaultRoles": [ - "view-applications", - "view-profile", - "manage-account" - ], - "redirectUris": [ - "/realms/registry/account/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "ae8d8aa5-5991-42a1-8ca8-eec12b6717f7", - "clientId": "account-console", - "name": "${client_account-console}", - "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/registry/account/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [ - "/realms/registry/account/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "pkce.code.challenge.method": "S256" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - "id": "b852b0a0-768e-4f42-badd-14cf7d2d227a", - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": {} - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "80b79538-8665-4188-921d-f4d0ad1f3113", - "clientId": "admin-cli", - "name": "${client_admin-cli}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "test1", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": false, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "1fa15256-6427-47fa-a144-b0b784e834c6", - "clientId": "apicurio-registry", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "test1", - "redirectUris": [ - "*" - ], - "webOrigins": [ - "*" - ], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "saml.assertion.signature": "false", - "saml.force.post.binding": "false", - "saml.multivalued.roles": "false", - "saml.encrypt": "false", - "saml.server.signature": "false", - "saml.server.signature.keyinfo.ext": "false", - "exclude.session.state.from.auth.response": "false", - "saml_force_name_id_format": "false", - "saml.client.signature": "false", - "tls.client.certificate.bound.access.tokens": "false", - "saml.authnstatement": "false", - "display.on.consent.screen": "false", - "saml.onetimeuse.condition": "false" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "717c272b-ed48-4d5a-a3cb-da5d3d3ba528", - "clientId": "broker", - "name": "${client_broker}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", - "clientId": "realm-management", - "name": "${client_realm-management}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": true, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "69afe60b-7329-440a-9b4c-0ebec33d8902", - "clientId": "registry-api", - "rootUrl": "", - "adminUrl": "http://localhost:8080", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "test1", - "redirectUris": [ - "*" - ], - "webOrigins": [ - "http://localhost:8080" - ], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": true, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": true, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "saml.assertion.signature": "false", - "saml.force.post.binding": "false", - "saml.multivalued.roles": "false", - "saml.encrypt": "false", - "login_theme": "keycloak", - "saml.server.signature": "false", - "saml.server.signature.keyinfo.ext": "false", - "exclude.session.state.from.auth.response": "false", - "saml_force_name_id_format": "false", - "saml.client.signature": "false", - "tls.client.certificate.bound.access.tokens": "false", - "saml.authnstatement": "false", - "display.on.consent.screen": "false", - "saml.onetimeuse.condition": "false" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, - "protocolMappers": [ - { - "id": "83a4a269-207b-4818-bbbb-a04abebb2997", - "name": "Client IP Address", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientAddress", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientAddress", - "jsonType.label": "String" - } - }, - { - "id": "20241caf-ebb6-467f-acae-7543b143c289", - "name": "Client ID", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientId", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientId", - "jsonType.label": "String" - } - }, - { - "id": "eb3a14a2-5c4c-4dd7-99dc-e2734c8c5d98", - "name": "Client Host", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientHost", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientHost", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "af889033-76c2-41ae-a368-67d5789f4b87", - "clientId": "registry-api-dev", - "rootUrl": "", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "test1", - "redirectUris": [ - "*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": true, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": true, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "saml.assertion.signature": "false", - "saml.force.post.binding": "false", - "saml.multivalued.roles": "false", - "saml.encrypt": "false", - "login_theme": "keycloak", - "saml.server.signature": "false", - "saml.server.signature.keyinfo.ext": "false", - "exclude.session.state.from.auth.response": "false", - "saml_force_name_id_format": "false", - "saml.client.signature": "false", - "tls.client.certificate.bound.access.tokens": "false", - "saml.authnstatement": "false", - "display.on.consent.screen": "false", - "saml.onetimeuse.condition": "false" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, - "protocolMappers": [ - { - "id": "aeb67b03-0bbd-432c-a329-0a04363e974a", - "name": "Client ID", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientId", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientId", - "jsonType.label": "String" - } - }, - { - "id": "7c29a433-d724-4b5b-86fe-d9cf9f6b7ba1", - "name": "Client IP Address", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientAddress", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientAddress", - "jsonType.label": "String" - } - }, - { - "id": "d2bda4a4-e2cc-498e-838e-60a7840ccad9", - "name": "Client Host", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientHost", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientHost", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "57e89899-9c1a-498d-96fd-c9bcbd3f3121", - "clientId": "registry-api-readonly", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "test1", - "redirectUris": [ - "*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": true, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": true, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "saml.assertion.signature": "false", - "saml.force.post.binding": "false", - "saml.multivalued.roles": "false", - "saml.encrypt": "false", - "login_theme": "keycloak", - "saml.server.signature": "false", - "saml.server.signature.keyinfo.ext": "false", - "exclude.session.state.from.auth.response": "false", - "saml_force_name_id_format": "false", - "saml.client.signature": "false", - "tls.client.certificate.bound.access.tokens": "false", - "saml.authnstatement": "false", - "display.on.consent.screen": "false", - "saml.onetimeuse.condition": "false" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, - "protocolMappers": [ - { - "id": "574cef06-3ccf-4ed0-9001-edd83606ff57", - "name": "Client Host", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientHost", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientHost", - "jsonType.label": "String" - } - }, - { - "id": "eae693c7-5b00-4c10-bf8c-c8959925659a", - "name": "Client ID", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientId", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientId", - "jsonType.label": "String" - } - }, - { - "id": "c1861851-a5ae-4da0-9110-469abc9bd64d", - "name": "Client IP Address", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientAddress", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientAddress", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "f1beca1a-0756-4dc6-9719-9234cd9b779f", - "clientId": "security-admin-console", - "name": "${client_security-admin-console}", - "rootUrl": "${authAdminUrl}", - "baseUrl": "/admin/registry/console/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [ - "/admin/registry/console/*" - ], - "webOrigins": [ - "+" - ], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "pkce.code.challenge.method": "S256" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - "id": "cb9b9e1a-63a0-460e-a42f-14d1ace49da3", - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - } - ], - "clientScopes": [ - { - "id": "65eabc09-c5a1-4a0e-830c-44a430c129f0", - "name": "offline_access", - "description": "OpenID Connect built-in scope: offline_access", - "protocol": "openid-connect", - "attributes": { - "consent.screen.text": "${offlineAccessScopeConsentText}", - "display.on.consent.screen": "true" - } - }, - { - "id": "5074f873-23f3-4d03-9b75-6c6af91fb7ed", - "name": "role_list", - "description": "SAML role list", - "protocol": "saml", - "attributes": { - "consent.screen.text": "${samlRoleListScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "ab3d0106-d086-4813-930b-5a27ddfe038b", - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, - "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" - } - } - ] - }, - { - "id": "9f0f742e-6202-4543-80e3-80fb2fbfc042", - "name": "profile", - "description": "OpenID Connect built-in scope: profile", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${profileScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "033dab17-488c-400d-b603-f75ebe1949b7", - "name": "family name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "lastName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "family_name", - "jsonType.label": "String" - } - }, - { - "id": "c87aca2f-23dd-4fc7-b79f-a9b061c165e4", - "name": "nickname", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "nickname", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "nickname", - "jsonType.label": "String" - } - }, - { - "id": "4361eae6-7021-49e1-a387-3d8bc4f50247", - "name": "birthdate", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "birthdate", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "birthdate", - "jsonType.label": "String" - } - }, - { - "id": "35c03d95-ce9d-4fd2-823b-23e896dbb105", - "name": "gender", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "gender", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "gender", - "jsonType.label": "String" - } - }, - { - "id": "0ff4cd3c-6567-4935-bbe8-0191a9bcdd72", - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - }, - { - "id": "8e087dfd-2978-4ea5-9ed2-32efca9a98c5", - "name": "given name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "firstName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "given_name", - "jsonType.label": "String" - } - }, - { - "id": "31a3c477-3aab-46cd-81e3-2b76b2c8c21c", - "name": "profile", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "profile", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "profile", - "jsonType.label": "String" - } - }, - { - "id": "a3606512-379b-4bcb-999d-29cf17812012", - "name": "website", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "website", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "website", - "jsonType.label": "String" - } - }, - { - "id": "2f535da7-ea99-4f8d-acbe-988a3691034b", - "name": "username", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "preferred_username", - "jsonType.label": "String" - } - }, - { - "id": "2fbfe26c-b175-4b16-97ea-edea4072181a", - "name": "picture", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "picture", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "picture", - "jsonType.label": "String" - } - }, - { - "id": "17e5a7d4-2e77-4ff4-8c71-b93e41e4e1bb", - "name": "full name", - "protocol": "openid-connect", - "protocolMapper": "oidc-full-name-mapper", - "consentRequired": false, - "config": { - "id.token.claim": "true", - "access.token.claim": "true", - "userinfo.token.claim": "true" - } - }, - { - "id": "ca64060a-1d26-43ca-aae7-23c62ed805d4", - "name": "zoneinfo", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "zoneinfo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "zoneinfo", - "jsonType.label": "String" - } - }, - { - "id": "beaddf45-8040-42cd-9236-55fe2134f5df", - "name": "middle name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "middleName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "middle_name", - "jsonType.label": "String" - } - }, - { - "id": "043c162e-e0ba-418b-b965-157f6a52db46", - "name": "updated at", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "updatedAt", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "updated_at", - "jsonType.label": "String" - } - } - ] - }, - { - "id": "a2766301-ac7f-42f4-bfbe-87d2fdcef382", - "name": "email", - "description": "OpenID Connect built-in scope: email", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${emailScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "35bbe3f0-d5a3-4785-b3dc-d187330b699d", - "name": "email", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "email", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email", - "jsonType.label": "String" - } - }, - { - "id": "d439a3d1-c6da-4138-87df-c1b851e7b9c8", - "name": "email verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "emailVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email_verified", - "jsonType.label": "boolean" - } - } - ] - }, - { - "id": "5539a2b5-6e75-4533-aaaa-800101d0df4d", - "name": "address", - "description": "OpenID Connect built-in scope: address", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${addressScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "f7c31e38-1dda-4dcc-82b6-c7d958416962", - "name": "address", - "protocol": "openid-connect", - "protocolMapper": "oidc-address-mapper", - "consentRequired": false, - "config": { - "user.attribute.formatted": "formatted", - "user.attribute.country": "country", - "user.attribute.postal_code": "postal_code", - "userinfo.token.claim": "true", - "user.attribute.street": "street", - "id.token.claim": "true", - "user.attribute.region": "region", - "access.token.claim": "true", - "user.attribute.locality": "locality" - } - } - ] - }, - { - "id": "90c61a9b-39ac-4dbd-af49-9123739f98f9", - "name": "phone", - "description": "OpenID Connect built-in scope: phone", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${phoneScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "9170cc7f-5624-4a15-b50d-cd1b9a0ffb6f", - "name": "phone number verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "phoneNumberVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number_verified", - "jsonType.label": "boolean" - } - }, - { - "id": "f2d44f21-de2f-47d8-b0d5-4e46f9de581b", - "name": "phone number", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "phoneNumber", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number", - "jsonType.label": "String" - } - } - ] - }, - { - "id": "db64f4f6-e562-4e43-9f17-255b8a21c5ca", - "name": "roles", - "description": "OpenID Connect scope for add user roles to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "true", - "consent.screen.text": "${rolesScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "bfdfc98c-59eb-4a05-9a74-dd1bb4dea691", - "name": "client roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-client-role-mapper", - "consentRequired": false, - "config": { - "user.attribute": "foo", - "access.token.claim": "true", - "claim.name": "resource_access.${client_id}.roles", - "jsonType.label": "String", - "multivalued": "true" - } - }, - { - "id": "e285b5a4-2854-46d8-bd06-6ca2911dde8a", - "name": "realm roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "user.attribute": "foo", - "access.token.claim": "true", - "claim.name": "realm_access.roles", - "jsonType.label": "String", - "multivalued": "true" - } - }, - { - "id": "c6da4bb5-fc32-4e34-88ac-72ca671afd3f", - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": {} - } - ] - }, - { - "id": "ab66a766-4d9d-40ac-bcc9-264cd5471b92", - "name": "web-origins", - "description": "OpenID Connect scope for add allowed web origins to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "false", - "consent.screen.text": "" - }, - "protocolMappers": [ - { - "id": "1b1867ba-1a17-412d-ab97-0ae88963d5b5", - "name": "allowed web origins", - "protocol": "openid-connect", - "protocolMapper": "oidc-allowed-origins-mapper", - "consentRequired": false, - "config": {} - } - ] - }, - { - "id": "d6f896d6-b31b-487e-b4a8-af921d3d04eb", - "name": "microprofile-jwt", - "description": "Microprofile - JWT built-in scope", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "false" - }, - "protocolMappers": [ - { - "id": "c7831e59-070e-4d77-8382-d5ef4f60ddd4", - "name": "upn", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "upn", - "jsonType.label": "String" - } - }, - { - "id": "3456b5e1-4852-48ac-8420-79568ffd9a89", - "name": "groups", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "multivalued": "true", - "userinfo.token.claim": "true", - "user.attribute": "foo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "groups", - "jsonType.label": "String" - } - } - ] - } - ], - "defaultDefaultClientScopes": [ - "role_list", - "profile", - "email", - "roles", - "web-origins" - ], - "defaultOptionalClientScopes": [ - "offline_access", - "address", - "phone", - "microprofile-jwt" - ], - "browserSecurityHeaders": { - "contentSecurityPolicyReportOnly": "", - "xContentTypeOptions": "nosniff", - "xRobotsTag": "none", - "xFrameOptions": "SAMEORIGIN", - "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", - "xXSSProtection": "1; mode=block", - "strictTransportSecurity": "max-age=31536000; includeSubDomains" - }, - "smtpServer": {}, - "loginTheme": "keycloak", - "accountTheme": "keycloak", - "adminTheme": "keycloak", - "emailTheme": "keycloak", - "eventsEnabled": false, - "eventsListeners": [ - "jboss-logging" - ], - "enabledEventTypes": [], - "adminEventsEnabled": false, - "adminEventsDetailsEnabled": false, - "components": { - "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ - { - "id": "6b7d0997-665b-4567-b955-f41029b1f7c6", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - "id": "b2062994-7819-4b5b-bcaf-bd565e0261f7", - "name": "Trusted Hosts", - "providerId": "trusted-hosts", - "subType": "anonymous", - "subComponents": {}, - "config": { - "host-sending-registration-request-must-match": [ - "true" - ], - "client-uris-must-match": [ - "true" - ] - } - }, - { - "id": "e28102af-287e-40d3-a64d-636f9d0af6c0", - "name": "Consent Required", - "providerId": "consent-required", - "subType": "anonymous", - "subComponents": {}, - "config": {} - }, - { - "id": "7ea991c6-db4b-4989-87c1-2cf0b2e2b371", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - "id": "c2aa0c17-6405-441a-96d8-7174001b1f6e", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-sha256-pairwise-sub-mapper", - "oidc-usermodel-attribute-mapper", - "saml-role-list-mapper", - "oidc-address-mapper", - "oidc-full-name-mapper", - "saml-user-property-mapper", - "oidc-usermodel-property-mapper", - "saml-user-attribute-mapper" - ] - } - }, - { - "id": "f1d9cee9-fa10-451a-a96f-486c1abc9184", - "name": "Full Scope Disabled", - "providerId": "scope", - "subType": "anonymous", - "subComponents": {}, - "config": {} - }, - { - "id": "398d86a9-4247-4923-b3bf-a94ef18974f2", - "name": "Max Clients Limit", - "providerId": "max-clients", - "subType": "anonymous", - "subComponents": {}, - "config": { - "max-clients": [ - "200" - ] - } - }, - { - "id": "fd8139d0-82ee-453e-a9aa-0bbd10538eff", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-address-mapper", - "oidc-full-name-mapper", - "saml-user-property-mapper", - "oidc-usermodel-property-mapper", - "saml-role-list-mapper", - "oidc-sha256-pairwise-sub-mapper", - "saml-user-attribute-mapper", - "oidc-usermodel-attribute-mapper" - ] - } - } - ], - "org.keycloak.keys.KeyProvider": [ - { - "id": "9ec415cf-5494-4823-a83d-cc38441b088c", - "name": "aes-generated", - "providerId": "aes-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "cd2dc9b1-a252-4f70-93c0-5bdb51532236", - "name": "hmac-generated", - "providerId": "hmac-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "HS256" - ] - } - }, - { - "id": "2dc91aa5-3084-4ceb-973e-24d78e78777a", - "name": "rsa-generated", - "providerId": "rsa-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - } - ] - }, - "internationalizationEnabled": false, - "supportedLocales": [ - "" - ], - "authenticationFlows": [ - { - "id": "1aa74e78-dd73-4720-83a7-551ac77e7e36", - "alias": "Account verification options", - "description": "Method with which to verity the existing account", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-email-verification", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 20, - "flowAlias": "Verify Existing Account by Re-authentication", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "e03fd7f8-464c-4efc-a194-ab2d2c6aee5e", - "alias": "Authentication Options", - "description": "Authentication options.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "basic-auth", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "basic-auth-otp", - "requirement": "DISABLED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "cf1a2a31-eb98-41b9-b5fe-32e4b0fef8ae", - "alias": "Browser - Conditional OTP", - "description": "Flow to determine if the OTP is required for the authentication", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "83234500-3b5c-4768-8a4e-88e5e747d9d6", - "alias": "Direct Grant - Conditional OTP", - "description": "Flow to determine if the OTP is required for the authentication", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "direct-grant-validate-otp", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "2f8b99e4-3e73-4f5f-bb3e-bd982ca0c1a8", - "alias": "First broker login - Conditional OTP", - "description": "Flow to determine if the OTP is required for the authentication", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "520738c7-5d97-4b94-98eb-c2990dad2869", - "alias": "Handle Existing Account", - "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-confirm-link", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "REQUIRED", - "priority": 20, - "flowAlias": "Account verification options", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "4c6fdef4-369e-4d40-a9be-9012e47cba82", - "alias": "Reset - Conditional OTP", - "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-otp", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "39d80944-cb90-42b1-a05b-f3fe1eaf9555", - "alias": "User creation or linking", - "description": "Flow for the existing/non-existing user alternatives", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticatorConfig": "create unique user config", - "authenticator": "idp-create-user-if-unique", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 20, - "flowAlias": "Handle Existing Account", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "bc1d70fe-a10a-4b37-a084-ecec09e9b0d5", - "alias": "Verify Existing Account by Re-authentication", - "description": "Reauthentication of existing account", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 20, - "flowAlias": "First broker login - Conditional OTP", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "552ecf0a-7308-4ac1-8fd4-0917613b1eb9", - "alias": "browser", - "description": "browser based authentication", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-cookie", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "identity-provider-redirector", - "requirement": "ALTERNATIVE", - "priority": 25, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 30, - "flowAlias": "forms", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "b8a5d0a7-5a56-421e-b7a4-77ee2fa2d70c", - "alias": "clients", - "description": "Base authentication for clients", - "providerId": "client-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "client-secret", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-jwt", - "requirement": "ALTERNATIVE", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-secret-jwt", - "requirement": "ALTERNATIVE", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-x509", - "requirement": "ALTERNATIVE", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "3ef0d683-fe26-4cb8-b9e6-210ced68912d", - "alias": "direct grant", - "description": "OpenID Connect Resource Owner Grant", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "direct-grant-validate-username", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "direct-grant-validate-password", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 30, - "flowAlias": "Direct Grant - Conditional OTP", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "c3cdccbf-94d5-4f49-ba48-efecca2b3754", - "alias": "docker auth", - "description": "Used by Docker clients to authenticate against the IDP", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "docker-http-basic-authenticator", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "6de6fa4f-9d37-4402-8637-5aead0b69791", - "alias": "first broker login", - "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticatorConfig": "review profile config", - "authenticator": "idp-review-profile", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "REQUIRED", - "priority": 20, - "flowAlias": "User creation or linking", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "5d3451e2-63b0-4077-bc9e-4dda89469eb2", - "alias": "forms", - "description": "Username, password, otp and other auth forms.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 20, - "flowAlias": "Browser - Conditional OTP", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "c241f49e-8df0-43d6-8ea4-f34487e72efb", - "alias": "http challenge", - "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "no-cookie-redirect", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "REQUIRED", - "priority": 20, - "flowAlias": "Authentication Options", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "be036899-5c4f-470d-b59b-32b384cceb23", - "alias": "registration", - "description": "registration flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-page-form", - "requirement": "REQUIRED", - "priority": 10, - "flowAlias": "registration form", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "e5b7df23-2a3b-4ad5-a209-cb6ab50f482d", - "alias": "registration form", - "description": "registration form", - "providerId": "form-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-user-creation", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-profile-action", - "requirement": "REQUIRED", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-password-action", - "requirement": "REQUIRED", - "priority": 50, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-recaptcha-action", - "requirement": "DISABLED", - "priority": 60, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "e5547216-29e2-4ef4-92f9-db764adde708", - "alias": "reset credentials", - "description": "Reset credentials for a user if they forgot their password or something", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "reset-credentials-choose-user", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-credential-email", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-password", - "requirement": "REQUIRED", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 40, - "flowAlias": "Reset - Conditional OTP", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "3fb4d56b-5949-4ccb-9413-ba39740572a8", - "alias": "saml ecp", - "description": "SAML ECP Profile Authentication Flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "http-basic-authenticator", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - } - ], - "authenticatorConfig": [ - { - "id": "debe33ad-2458-4a82-9e7f-b4cd0f6245f0", - "alias": "create unique user config", - "config": { - "require.password.update.after.registration": "false" - } - }, - { - "id": "71018d10-59df-4d07-a074-f0f2cbb7e8ff", - "alias": "review profile config", - "config": { - "update.profile.on.first.login": "missing" - } - } - ], - "requiredActions": [ - { - "alias": "CONFIGURE_TOTP", - "name": "Configure OTP", - "providerId": "CONFIGURE_TOTP", - "enabled": true, - "defaultAction": false, - "priority": 10, - "config": {} - }, - { - "alias": "terms_and_conditions", - "name": "Terms and Conditions", - "providerId": "terms_and_conditions", - "enabled": false, - "defaultAction": false, - "priority": 20, - "config": {} - }, - { - "alias": "UPDATE_PASSWORD", - "name": "Update Password", - "providerId": "UPDATE_PASSWORD", - "enabled": true, - "defaultAction": false, - "priority": 30, - "config": {} - }, - { - "alias": "UPDATE_PROFILE", - "name": "Update Profile", - "providerId": "UPDATE_PROFILE", - "enabled": true, - "defaultAction": false, - "priority": 40, - "config": {} - }, - { - "alias": "VERIFY_EMAIL", - "name": "Verify Email", - "providerId": "VERIFY_EMAIL", - "enabled": true, - "defaultAction": false, - "priority": 50, - "config": {} - }, - { - "alias": "update_user_locale", - "name": "Update User Locale", - "providerId": "update_user_locale", - "enabled": true, - "defaultAction": false, - "priority": 1000, - "config": {} - } - ], - "browserFlow": "browser", - "registrationFlow": "registration", - "directGrantFlow": "direct grant", - "resetCredentialsFlow": "reset credentials", - "clientAuthenticationFlow": "clients", - "dockerAuthenticationFlow": "docker auth", - "attributes": { - "clientSessionIdleTimeout": "0", - "clientSessionMaxLifespan": "0" - }, - "keycloakVersion": "10.0.2", - "userManagedAccessAllowed": true -} \ No newline at end of file diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml new file mode 100644 index 0000000000..bddb8c6565 --- /dev/null +++ b/integration-tests/pom.xml @@ -0,0 +1,700 @@ + + + 4.0.0 + + io.apicurio + apicurio-registry + 2.5.0-SNAPSHOT + + apicurio-registry-integration-tests + + + true + localhost + 0 + + + + + io.quarkus + quarkus-junit5 + + + io.fabric8 + kubernetes-client + + + io.fabric8 + openshift-client + + + org.junit.platform + junit-platform-launcher + + + jakarta.ws.rs + jakarta.ws.rs-api + + + io.apicurio + apicurio-registry-client + + + io.apicurio + apicurio-tenant-manager-client + test + + + io.apicurio + apicurio-registry-utils-kafka + test-jar + test + + + io.apicurio + apicurio-registry-utils-tests + + + io.apicurio + apicurio-registry-maven-plugin + maven-plugin + test + + + io.apicurio + apicurio-registry-serdes-avro-serde + test + + + io.apicurio + apicurio-registry-serdes-protobuf-serde + test + + + io.apicurio + apicurio-registry-serdes-jsonschema-serde + test + + + io.apicurio + apicurio-registry-utils-converter + test + + + + io.confluent + kafka-avro-serializer + provided + + + io.confluent + kafka-connect-avro-converter + test + + + io.rest-assured + rest-assured + test + + + org.testcontainers + redpanda + + + io.zonky.test + embedded-postgres + test + + + + + org.seleniumhq.selenium + selenium-java + 3.141.59 + test + + + org.testcontainers + selenium + test + + + commons-io + commons-io + test + + + io.apicurio + apicurio-registry-utils-import-export + test + + + io.vertx + vertx-core + test + + + + + + + maven-jar-plugin + + + + test-jar + + + + + + maven-failsafe-plugin + + + org.jboss.logmanager.LogManager + ${maven.home} + ${groups} + + + + + + integration-test + verify + + + + + + io.quarkus + quarkus-maven-plugin + + + + build + + + + + + + + + + + local-mem + + false + + + + + maven-dependency-plugin + + + unpack-static-resources + generate-resources + + unpack + + + + + ${project.groupId} + apicurio-registry-app + ${project.version} + jar + true + **/web.xml,**/application.properties + + + ${project.build.outputDirectory} + false + true + + + + unpack-test-dependencies + process-test-classes + + unpack-dependencies + + + io.apicurio + test-jar + test + ${project.build.directory}/test-classes + **/*IT.class, **/*.properties + false + true + + + + + + org.codehaus.mojo + properties-maven-plugin + + + + set-system-properties + + + + + quarkus.http.test-host + ${quarkus.http.test-host} + + + quarkus.http.test-port + ${quarkus.http.test-port} + + + + + + + + + + + io.apicurio + apicurio-registry-app + + + io.apicurio + apicurio-registry-app + test-jar + + + io.apicurio + apicurio-registry-schema-util-provider + + + + + + + + local-sql + + false + + + + + maven-dependency-plugin + + + unpack-static-resources + generate-resources + + unpack + + + + + ${project.groupId} + apicurio-registry-storage-sql + ${project.version} + jar + true + **/web.xml,**/application.properties + + + ${project.build.outputDirectory} + false + true + + + + unpack-test-dependencies + process-test-classes + + unpack-dependencies + + + io.apicurio + test-jar + test + ${project.build.directory}/test-classes + **/*SqlStorageTestResources.class, **/*.properties + false + true + + + + + + org.codehaus.mojo + properties-maven-plugin + + + + set-system-properties + + + + + quarkus.http.test-host + ${quarkus.http.test-host} + + + quarkus.http.test-port + ${quarkus.http.test-port} + + + + + + + + + + + io.apicurio + apicurio-registry-storage-sql + + + io.apicurio + apicurio-registry-storage-sql + test-jar + + + io.apicurio + apicurio-registry-schema-util-provider + + + + + + + + local-kafka + + false + + + + + maven-dependency-plugin + + + unpack-static-resources + generate-resources + + unpack + + + + + ${project.groupId} + apicurio-registry-storage-kafkasql + ${project.version} + jar + true + **/web.xml,**/application.properties + + + ${project.build.outputDirectory} + false + true + + + + + + org.codehaus.mojo + properties-maven-plugin + + + + set-system-properties + + + + + quarkus.http.test-host + ${quarkus.http.test-host} + + + quarkus.http.test-port + ${quarkus.http.test-port} + + + + + + + + + + + io.apicurio + apicurio-registry-storage-kafkasql + + + io.apicurio + apicurio-registry-storage-kafkasql + test-jar + + + io.apicurio + apicurio-registry-schema-util-provider + + + + + + + + + remote-mem + + false + + + + + maven-failsafe-plugin + + + + integration-test + + + + + quay.io/apicurio/apicurio-registry-mem:latest-snapshot + + true + true + localhost + 8080 + + + + + + + + + + + remote-kafka + + false + + + + + maven-failsafe-plugin + + + + integration-test + + + + + quay.io/apicurio/apicurio-registry-kafkasql:latest-snapshot + + true + true + localhost + 8080 + + + + + + + + + + + remote-sql + + false + + + + + maven-failsafe-plugin + + + + integration-test + + + + quay.io/apicurio/apicurio-registry-sql:latest-snapshot + + true + true + localhost + 8080 + + + + + + + + + + + + + all + + false + ( smoke | serdes | acceptance | ui) + + + + + ci + + false + ( smoke | serdes | acceptance ) + + + + + smoke + + smoke + false + + + + + serdes + + serdes + false + + + + + ui + + ui + false + + + + + acceptance + + false + acceptance & !multitenancy + + + + + auth + + auth + false + + + + + multitenancy + + multitenancy + false + + + + + maven-failsafe-plugin + + + + integration-test + + + + true + + + + + + + + + + + migration + + false + migration + + + + + sqlit + + false + sqlit + + + + + maven-failsafe-plugin + + + + integration-test + + + + true + + + + + + + + + + + kafkasqlit + + false + kafkasqlit + + + + + openshift + + + + maven-failsafe-plugin + + + + integration-test + + + + true + + + + + + + + + + + diff --git a/integration-tests/src/main/java/io/apicurio/deployment/Constants.java b/integration-tests/src/main/java/io/apicurio/deployment/Constants.java new file mode 100644 index 0000000000..a6f0ea9390 --- /dev/null +++ b/integration-tests/src/main/java/io/apicurio/deployment/Constants.java @@ -0,0 +1,57 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.deployment; + +import java.util.Optional; + +public class Constants { + + /** + * Registry image placeholder + */ + static final String REGISTRY_IMAGE = "registry-image"; + + /** + * Tag for migration tests, the suite will deploy two registries and perform data migration between the two + */ + static final String MULTITENANCY = "multitenancy"; + + /** + * Tag for auth tests profile. + */ + static final String AUTH = "auth"; + + /** + * Tag for sql db upgrade tests profile. + */ + static final String KAFKA_SQL = "kafkasqlit"; + + /** + * Tag for sql db upgrade tests profile. + */ + static final String SQL = "sqlit"; + + /** + * Tag for ui tests profile. + */ + static final String UI = "ui"; + + + public static final String TEST_PROFILE = + Optional.ofNullable(System.getProperty("groups")) + .orElse(""); +} diff --git a/integration-tests/src/test/java/io/apicurio/deployment/InMemoryDeploymentManager.java b/integration-tests/src/test/java/io/apicurio/deployment/InMemoryDeploymentManager.java new file mode 100644 index 0000000000..a74d6b4bea --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/deployment/InMemoryDeploymentManager.java @@ -0,0 +1,39 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.deployment; + +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_IN_MEMORY_MULTITENANT_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_IN_MEMORY_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_IN_MEMORY_SECURED_RESOURCES; +import static io.apicurio.deployment.RegistryDeploymentManager.prepareTestsInfra; + +public class InMemoryDeploymentManager { + + static void deployInMemoryApp(String registryImage) throws Exception { + switch (Constants.TEST_PROFILE) { + case Constants.AUTH: + prepareTestsInfra(null, APPLICATION_IN_MEMORY_SECURED_RESOURCES, true, registryImage, false); + break; + case Constants.MULTITENANCY: + prepareTestsInfra(null, APPLICATION_IN_MEMORY_MULTITENANT_RESOURCES, false, registryImage, true); + break; + default: + prepareTestsInfra(null, APPLICATION_IN_MEMORY_RESOURCES, false, registryImage, false); + break; + } + } +} diff --git a/integration-tests/src/test/java/io/apicurio/deployment/KafkaSqlDeploymentManager.java b/integration-tests/src/test/java/io/apicurio/deployment/KafkaSqlDeploymentManager.java new file mode 100644 index 0000000000..daa47c95cd --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/deployment/KafkaSqlDeploymentManager.java @@ -0,0 +1,99 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.deployment; + +import io.apicurio.registry.rest.client.RegistryClientFactory; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.dbupgrade.UpgradeTestsDataInitializer; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.client.dsl.RollableScalableResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_DEPLOYMENT; +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_KAFKA_MULTITENANT_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_KAFKA_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_KAFKA_SECURED_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_OLD_KAFKA_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.KAFKA_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.TEST_NAMESPACE; +import static io.apicurio.deployment.RegistryDeploymentManager.kubernetesClient; +import static io.apicurio.deployment.RegistryDeploymentManager.prepareTestsInfra; + +public class KafkaSqlDeploymentManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(KafkaSqlDeploymentManager.class); + + static void deployKafkaApp(String registryImage) throws Exception { + switch (Constants.TEST_PROFILE) { + case Constants.AUTH: + prepareTestsInfra(KAFKA_RESOURCES, APPLICATION_KAFKA_SECURED_RESOURCES, true, registryImage, false); + break; + case Constants.MULTITENANCY: + prepareTestsInfra(KAFKA_RESOURCES, APPLICATION_KAFKA_MULTITENANT_RESOURCES, false, registryImage, true); + break; + case Constants.KAFKA_SQL: + prepareKafkaDbUpgradeTests(registryImage); + break; + default: + prepareTestsInfra(KAFKA_RESOURCES, APPLICATION_KAFKA_RESOURCES, false, registryImage, false); + break; + } + } + + private static void prepareKafkaDbUpgradeTests(String registryImage) throws Exception { + LOGGER.info("Preparing data for KafkaSQL DB Upgrade migration tests..."); + + //For the migration tests first we deploy the in-memory variant, add some data and then the appropriate variant is deployed. + prepareTestsInfra(KAFKA_RESOURCES, APPLICATION_OLD_KAFKA_RESOURCES, false, null, false); + prepareKafkaSqlMigrationData(ApicurioRegistryBaseIT.getRegistryBaseUrl()); + + final RollableScalableResource deploymentResource = kubernetesClient.apps().deployments().inNamespace(TEST_NAMESPACE).withName(APPLICATION_DEPLOYMENT); + + kubernetesClient.apps().deployments().inNamespace(TEST_NAMESPACE).withName(APPLICATION_DEPLOYMENT).delete(); + + //Wait for the deployment to be deleted + CompletableFuture> deployment = deploymentResource + .informOnCondition(Collection::isEmpty); + + try { + deployment.get(60, TimeUnit.SECONDS); + } catch (ExecutionException | InterruptedException | TimeoutException e) { + LOGGER.warn("Error waiting for namespace deletion", e); + } finally { + deployment.cancel(true); + } + + LOGGER.info("Finished preparing data for the KafkaSQL DB Upgrade tests."); + prepareTestsInfra(null, APPLICATION_KAFKA_RESOURCES, false, registryImage, false); + } + + private static void prepareKafkaSqlMigrationData(String registryBaseUrl) throws Exception { + var registryClient = RegistryClientFactory.create(registryBaseUrl); + + UpgradeTestsDataInitializer.prepareProtobufHashUpgradeTest(registryClient); + UpgradeTestsDataInitializer.prepareReferencesUpgradeTest(registryClient); + UpgradeTestsDataInitializer.prepareLogCompactionTests(registryClient); + } +} diff --git a/integration-tests/src/test/java/io/apicurio/deployment/KubernetesTestResources.java b/integration-tests/src/test/java/io/apicurio/deployment/KubernetesTestResources.java new file mode 100644 index 0000000000..27756983e3 --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/deployment/KubernetesTestResources.java @@ -0,0 +1,54 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.deployment; + +public class KubernetesTestResources { + + protected static final String E2E_NAMESPACE_RESOURCE = "/infra/e2e-namespace.yml"; + protected static final String REGISTRY_OPENSHIFT_ROUTE = "/infra/openshift/registry-route.yml"; + + protected static final String TENANT_MANAGER_OPENSHIFT_ROUTE = "/infra/openshift/tenant-manager-route.yml"; + + protected static final String APPLICATION_IN_MEMORY_RESOURCES = "/infra/in-memory/registry-in-memory.yml"; + protected static final String APPLICATION_SQL_RESOURCES = "/infra/sql/registry-sql.yml"; + protected static final String APPLICATION_KAFKA_RESOURCES = "/infra/kafka/registry-kafka.yml"; + + protected static final String APPLICATION_IN_MEMORY_SECURED_RESOURCES = "/infra/in-memory/registry-in-memory-secured.yml"; + protected static final String APPLICATION_SQL_SECURED_RESOURCES = "/infra/sql/registry-sql-secured.yml"; + protected static final String APPLICATION_KAFKA_SECURED_RESOURCES = "/infra/kafka/registry-kafka-secured.yml"; + + protected static final String APPLICATION_IN_MEMORY_MULTITENANT_RESOURCES = "/infra/in-memory/registry-multitenant-in-memory.yml"; + protected static final String APPLICATION_SQL_MULTITENANT_RESOURCES = "/infra/sql/registry-multitenant-sql.yml"; + protected static final String APPLICATION_KAFKA_MULTITENANT_RESOURCES = "/infra/kafka/registry-multitenant-kafka.yml"; + + protected static final String APPLICATION_OLD_SQL_RESOURCES = "/infra/sql/registry-sql-old.yml"; + protected static final String APPLICATION_OLD_KAFKA_RESOURCES = "/infra/kafka/registry-kafka-old.yml"; + + protected static final String TENANT_MANAGER_RESOURCES = "/infra/tenant-manager/tenant-manager.yml"; + protected static final String TENANT_MANAGER_DATABASE = "/infra/tenant-manager/tenant-manager-database.yml"; + + protected static final String KAFKA_RESOURCES = "/infra/kafka/kafka.yml"; + protected static final String DATABASE_RESOURCES = "/infra/sql/postgresql.yml"; + protected static final String KEYCLOAK_RESOURCES = "/infra/auth/keycloak.yml"; + + protected static final String TEST_NAMESPACE = "apicurio-registry-e2e"; + + protected static final String APPLICATION_SERVICE = "apicurio-registry-service"; + protected static final String APPLICATION_DEPLOYMENT = "apicurio-registry-deployment"; + protected static final String KEYCLOAK_SERVICE = "keycloak-service"; + protected static final String TENANT_MANAGER_SERVICE = "tenant-manager-service"; +} diff --git a/integration-tests/src/test/java/io/apicurio/deployment/PortForwardManager.java b/integration-tests/src/test/java/io/apicurio/deployment/PortForwardManager.java new file mode 100644 index 0000000000..f831424322 --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/deployment/PortForwardManager.java @@ -0,0 +1,88 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.deployment; + +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClientBuilder; +import io.fabric8.kubernetes.client.LocalPortForward; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +import static io.apicurio.deployment.KubernetesTestResources.KEYCLOAK_SERVICE; +import static io.apicurio.deployment.KubernetesTestResources.TEST_NAMESPACE; + +public class PortForwardManager implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback { + + KubernetesClient kubernetesClient; + static LocalPortForward keycloakPortForward; + + private static final Logger logger = LoggerFactory.getLogger(PortForwardManager.class); + + public PortForwardManager() { + if (Boolean.parseBoolean(System.getProperty("cluster.tests"))) { + kubernetesClient = new KubernetesClientBuilder() + .build(); + } + } + + @Override + public void beforeAll(ExtensionContext context) throws Exception { + if (Boolean.parseBoolean(System.getProperty("cluster.tests"))) { + if (Constants.TEST_PROFILE.equals(Constants.AUTH)) { + startKeycloakPortForward(); + } + } + } + + @Override + public void afterAll(ExtensionContext context) throws Exception { + if (Boolean.parseBoolean(System.getProperty("cluster.tests"))) { + if (Constants.TEST_PROFILE.equals(Constants.AUTH)) { + if (keycloakPortForward != null) { + keycloakPortForward.close(); + } + } + } + } + + + private void startKeycloakPortForward() { + try { + if (keycloakPortForward != null) { + keycloakPortForward.close(); + } + //Create the keycloak port forward so the tests can reach it to get tokens + keycloakPortForward = kubernetesClient.services() + .inNamespace(TEST_NAMESPACE) + .withName(KEYCLOAK_SERVICE) + .portForward(8090, 8090); + } catch (IllegalStateException | IOException ex) { + logger.warn("Error found forwarding tenant manager port, the port forwarding might be running already, continuing...", ex); + } + } + + @Override + public void beforeEach(ExtensionContext context) { + + } +} diff --git a/integration-tests/src/test/java/io/apicurio/deployment/RegistryDeploymentManager.java b/integration-tests/src/test/java/io/apicurio/deployment/RegistryDeploymentManager.java new file mode 100644 index 0000000000..f13fdc27fe --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/deployment/RegistryDeploymentManager.java @@ -0,0 +1,233 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.deployment; + +import io.fabric8.kubernetes.api.model.Namespace; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClientBuilder; +import io.fabric8.kubernetes.client.LocalPortForward; +import io.fabric8.kubernetes.client.dsl.Resource; +import io.fabric8.openshift.api.model.Route; +import io.fabric8.openshift.client.DefaultOpenShiftClient; +import io.fabric8.openshift.client.OpenShiftClient; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.shaded.org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import static io.apicurio.deployment.Constants.REGISTRY_IMAGE; +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_SERVICE; +import static io.apicurio.deployment.KubernetesTestResources.E2E_NAMESPACE_RESOURCE; +import static io.apicurio.deployment.KubernetesTestResources.KEYCLOAK_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.REGISTRY_OPENSHIFT_ROUTE; +import static io.apicurio.deployment.KubernetesTestResources.TENANT_MANAGER_DATABASE; +import static io.apicurio.deployment.KubernetesTestResources.TENANT_MANAGER_OPENSHIFT_ROUTE; +import static io.apicurio.deployment.KubernetesTestResources.TENANT_MANAGER_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.TENANT_MANAGER_SERVICE; +import static io.apicurio.deployment.KubernetesTestResources.TEST_NAMESPACE; + +public class RegistryDeploymentManager implements TestExecutionListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(RegistryDeploymentManager.class); + + static KubernetesClient kubernetesClient; + static LocalPortForward registryPortForward; + + @Override + public void testPlanExecutionStarted(TestPlan testPlan) { + if (Boolean.parseBoolean(System.getProperty("cluster.tests"))) { + + kubernetesClient = new KubernetesClientBuilder() + .build(); + + try { + handleInfraDeployment(); + } catch (Exception e) { + LOGGER.error("Error starting registry deployment", e); + } + + LOGGER.info("Test suite started ##################################################"); + } + } + + @Override + public void testPlanExecutionFinished(TestPlan testPlan) { + LOGGER.info("Test suite ended ##################################################"); + + //Finally, once the testsuite is done, cleanup all the resources in the cluster + if (kubernetesClient != null && !(Boolean.parseBoolean(System.getProperty("preserveNamespace")))) { + LOGGER.info("Closing test resources ##################################################"); + + if (registryPortForward != null) { + try { + registryPortForward.close(); + } catch (IOException e) { + LOGGER.warn("Error closing registry port forward", e); + } + } + + final Resource namespaceResource = kubernetesClient.namespaces() + .withName(TEST_NAMESPACE); + namespaceResource.delete(); + + // wait the namespace to be deleted + CompletableFuture> namespace = namespaceResource + .informOnCondition(Collection::isEmpty); + + try { + namespace.get(60, TimeUnit.SECONDS); + } catch (ExecutionException | InterruptedException | TimeoutException e) { + LOGGER.warn("Error waiting for namespace deletion", e); + } finally { + namespace.cancel(true); + } + kubernetesClient.close(); + } + } + + private void handleInfraDeployment() throws Exception { + //First, create the namespace used for the test. + kubernetesClient.load(getClass().getResourceAsStream(E2E_NAMESPACE_RESOURCE)) + .create(); + + //Based on the configuration, deploy the appropriate variant + if (Boolean.parseBoolean(System.getProperty("deployInMemory"))) { + LOGGER.info("Deploying In Memory Registry Variant with image: {} ##################################################", System.getProperty("registry-in-memory-image")); + InMemoryDeploymentManager.deployInMemoryApp(System.getProperty("registry-in-memory-image")); + } else if (Boolean.parseBoolean(System.getProperty("deploySql"))) { + LOGGER.info("Deploying SQL Registry Variant with image: {} ##################################################", System.getProperty("registry-sql-image")); + SqlDeploymentManager.deploySqlApp(System.getProperty("registry-sql-image")); + } else if (Boolean.parseBoolean(System.getProperty("deployKafka"))) { + LOGGER.info("Deploying Kafka SQL Registry Variant with image: {} ##################################################", System.getProperty("registry-kafkasql-image")); + KafkaSqlDeploymentManager.deployKafkaApp(System.getProperty("registry-kafkasql-image")); + } + } + + static void prepareTestsInfra(String externalResources, String registryResources, boolean startKeycloak, String + registryImage, boolean startTenantManager) throws IOException { + if (startKeycloak) { + LOGGER.info("Deploying Keycloak resources ##################################################"); + deployResource(KEYCLOAK_RESOURCES); + } + + if (startTenantManager) { + LOGGER.info("Deploying Tenant Manager resources ##################################################"); + deployResource(TENANT_MANAGER_DATABASE); + deployResource(TENANT_MANAGER_RESOURCES); + } + + if (externalResources != null) { + LOGGER.info("Deploying external dependencies for Registry ##################################################"); + deployResource(externalResources); + } + + final InputStream resourceAsStream = RegistryDeploymentManager.class.getResourceAsStream(registryResources); + + assert resourceAsStream != null; + + String registryLoadedResources = IOUtils.toString(resourceAsStream, StandardCharsets.UTF_8.name()); + + if (registryImage != null) { + registryLoadedResources = registryLoadedResources.replace(REGISTRY_IMAGE, registryImage); + } + + try { + //Deploy all the resources associated to the registry variant + kubernetesClient.load(IOUtils.toInputStream(registryLoadedResources, StandardCharsets.UTF_8.name())) + .create(); + } catch (Exception ex) { + LOGGER.warn("Error creating registry resources:", ex); + } + + //Wait for all the pods of the variant to be ready + kubernetesClient.pods() + .inNamespace(TEST_NAMESPACE).waitUntilReady(360, TimeUnit.SECONDS); + + setupTestNetworking(startTenantManager); + } + + private static void setupTestNetworking(boolean startTenantManager) { + if (Constants.TEST_PROFILE.equals(Constants.UI)) { + //In the UI tests we use a port forward to make the application available to the testsuite. + registryPortForward = kubernetesClient.services() + .inNamespace(TEST_NAMESPACE) + .withName(APPLICATION_SERVICE) + .portForward(8080, 8080); + } else { + + //For openshift, a route to the application is created we use it to set up the networking needs. + if (Boolean.parseBoolean(System.getProperty("openshift.resources"))) { + + try (OpenShiftClient openShiftClient = new DefaultOpenShiftClient()) { + + try { + final Route registryRoute = openShiftClient.routes() + .load(RegistryDeploymentManager.class.getResourceAsStream(REGISTRY_OPENSHIFT_ROUTE)) + .create(); + System.setProperty("quarkus.http.test-host", registryRoute.getSpec().getHost()); + System.setProperty("quarkus.http.test-port", "80"); + + } catch (Exception ex) { + LOGGER.warn("The registry route already exists: ", ex); + } + + try { + final Route tenantManagerRoute = openShiftClient.routes() + .load(RegistryDeploymentManager.class.getResourceAsStream(TENANT_MANAGER_OPENSHIFT_ROUTE)) + .create(); + + System.setProperty("tenant.manager.external.endpoint", tenantManagerRoute.getSpec().getHost()); + } catch (Exception ex) { + LOGGER.warn("The tenant manger route already exists: ", ex); + } + } + + } else { + //If we're running the cluster tests but no external endpoint has been provided, set the value of the load balancer. + if (System.getProperty("quarkus.http.test-host").equals("localhost") && !System.getProperty("os.name").contains("Mac OS")) { + System.setProperty("quarkus.http.test-host", kubernetesClient.services().inNamespace(TEST_NAMESPACE).withName(APPLICATION_SERVICE).get().getSpec().getClusterIP()); + } + + //If we're running the cluster tests but no external endpoint has been provided, set the value of the load balancer. + if (startTenantManager && System.getProperty("tenant.manager.external.endpoint") == null) { + System.setProperty("tenant.manager.external.endpoint", kubernetesClient.services().inNamespace(TEST_NAMESPACE).withName(TENANT_MANAGER_SERVICE).get().getSpec().getClusterIP()); + } + } + } + } + + private static void deployResource(String resource) { + //Deploy all the resources associated to the external requirements + kubernetesClient.load(RegistryDeploymentManager.class.getResourceAsStream(resource)) + .create(); + + //Wait for all the external resources pods to be ready + kubernetesClient.pods() + .inNamespace(TEST_NAMESPACE).waitUntilReady(60, TimeUnit.SECONDS); + } +} \ No newline at end of file diff --git a/integration-tests/src/test/java/io/apicurio/deployment/SqlDeploymentManager.java b/integration-tests/src/test/java/io/apicurio/deployment/SqlDeploymentManager.java new file mode 100644 index 0000000000..4ae625b6af --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/deployment/SqlDeploymentManager.java @@ -0,0 +1,127 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.deployment; + +import io.apicurio.registry.utils.tests.TestUtils; +import io.apicurio.tenantmanager.api.datamodel.SortBy; +import io.apicurio.tenantmanager.api.datamodel.SortOrder; +import io.apicurio.tenantmanager.api.datamodel.TenantStatusValue; +import io.apicurio.tenantmanager.client.TenantManagerClientImpl; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.dbupgrade.SqlStorageUpgradeIT; +import io.apicurio.tests.dbupgrade.UpgradeTestsDataInitializer; +import io.apicurio.tests.multitenancy.MultitenancySupport; +import io.apicurio.tests.multitenancy.TenantUser; +import io.apicurio.tests.multitenancy.TenantUserClient; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.client.dsl.RollableScalableResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_DEPLOYMENT; +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_OLD_SQL_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_SQL_MULTITENANT_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_SQL_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.APPLICATION_SQL_SECURED_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.DATABASE_RESOURCES; +import static io.apicurio.deployment.KubernetesTestResources.TEST_NAMESPACE; +import static io.apicurio.deployment.RegistryDeploymentManager.kubernetesClient; +import static io.apicurio.deployment.RegistryDeploymentManager.prepareTestsInfra; + +public class SqlDeploymentManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(SqlDeploymentManager.class); + + protected static void deploySqlApp(String registryImage) throws Exception { + switch (Constants.TEST_PROFILE) { + case Constants.AUTH: + prepareTestsInfra(DATABASE_RESOURCES, APPLICATION_SQL_SECURED_RESOURCES, true, registryImage, false); + break; + case Constants.MULTITENANCY: + prepareTestsInfra(DATABASE_RESOURCES, APPLICATION_SQL_MULTITENANT_RESOURCES, false, registryImage, true); + break; + case Constants.SQL: + prepareSqlDbUpgradeTests(registryImage); + break; + default: + prepareTestsInfra(DATABASE_RESOURCES, APPLICATION_SQL_RESOURCES, false, registryImage, false); + break; + } + } + + private static void prepareSqlDbUpgradeTests(String registryImage) throws Exception { + LOGGER.info("Preparing data for SQL DB Upgrade migration tests..."); + + //For the migration tests first we deploy the in-memory variant, add some data and then the appropriate variant is deployed. + prepareTestsInfra(DATABASE_RESOURCES, APPLICATION_OLD_SQL_RESOURCES, false, null, true); + + prepareSqlMigrationData(ApicurioRegistryBaseIT.getTenantManagerUrl(), ApicurioRegistryBaseIT.getRegistryBaseUrl()); + + final RollableScalableResource deploymentResource = kubernetesClient.apps().deployments().inNamespace(TEST_NAMESPACE).withName(APPLICATION_DEPLOYMENT); + + kubernetesClient.apps().deployments().inNamespace(TEST_NAMESPACE).withName(APPLICATION_DEPLOYMENT).delete(); + + //Wait for the deployment to be deleted + CompletableFuture> deployment = deploymentResource + .informOnCondition(Collection::isEmpty); + + try { + deployment.get(60, TimeUnit.SECONDS); + } catch (ExecutionException | InterruptedException | TimeoutException e) { + LOGGER.warn("Error waiting for namespace deletion", e); + } finally { + deployment.cancel(true); + } + + LOGGER.info("Finished preparing data for the SQL DB Upgrade tests."); + prepareTestsInfra(null, APPLICATION_SQL_MULTITENANT_RESOURCES, false, registryImage, false); + } + + private static void prepareSqlMigrationData(String tenantManagerUrl, String registryBaseUrl) throws Exception { + final TenantManagerClientImpl tenantManagerClient = new TenantManagerClientImpl(tenantManagerUrl, Collections.emptyMap(), null); + + //Warm up until the tenant manager is ready. + TestUtils.retry(() -> tenantManagerClient.listTenants(TenantStatusValue.READY, 0, 1, SortOrder.asc, SortBy.tenantId)); + + LOGGER.info("Tenant manager is ready, filling registry with test data..."); + + UpgradeTestsDataInitializer.prepareTestStorageUpgrade(SqlStorageUpgradeIT.class.getSimpleName(), tenantManagerUrl, registryBaseUrl); + + TestUtils.waitFor("Waiting for tenant data to be available...", 3000, 180000, () -> tenantManagerClient.listTenants(TenantStatusValue.READY, 0, 51, SortOrder.asc, SortBy.tenantId).getCount() == 10); + + LOGGER.info("Done filling registry with test data..."); + + MultitenancySupport mt = new MultitenancySupport(tenantManagerUrl, registryBaseUrl); + TenantUser tenantUser = new TenantUser(UUID.randomUUID().toString(), UUID.randomUUID().toString(), "storageUpgrade", UUID.randomUUID().toString()); + final TenantUserClient tenantUpgradeClient = mt.createTenant(tenantUser); + + //Prepare the data for the content and canonical hash upgraders using an isolated tenant so we don't have data conflicts. + UpgradeTestsDataInitializer.prepareProtobufHashUpgradeTest(tenantUpgradeClient.client); + UpgradeTestsDataInitializer.prepareReferencesUpgradeTest(tenantUpgradeClient.client); + + SqlStorageUpgradeIT.upgradeTenantClient = tenantUpgradeClient.client; + } +} diff --git a/integration-tests/src/test/java/io/apicurio/tests/ApicurioRegistryBaseIT.java b/integration-tests/src/test/java/io/apicurio/tests/ApicurioRegistryBaseIT.java new file mode 100644 index 0000000000..0dbe3062fb --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/ApicurioRegistryBaseIT.java @@ -0,0 +1,735 @@ +/* + * Copyright 2021 Red Hat + * + * Licensed 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 io.apicurio.tests; + +import io.apicurio.deployment.PortForwardManager; +import io.apicurio.registry.rest.client.RegistryClient; +import io.apicurio.registry.rest.client.RegistryClientFactory; +import io.apicurio.registry.rest.client.exception.ArtifactNotFoundException; +import io.apicurio.registry.rest.client.exception.RestClientException; +import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; +import io.apicurio.registry.rest.v2.beans.ArtifactSearchResults; +import io.apicurio.registry.rest.v2.beans.IfExists; +import io.apicurio.registry.rest.v2.beans.SearchedArtifact; +import io.apicurio.registry.rest.v2.beans.SearchedVersion; +import io.apicurio.registry.rest.v2.beans.VersionMetaData; +import io.apicurio.registry.utils.tests.SimpleDisplayName; +import io.apicurio.registry.utils.tests.TestUtils; +import io.apicurio.tests.utils.Constants; +import io.apicurio.tests.utils.LoadBalanceRegistryClient; +import io.apicurio.tests.utils.RegistryWaitUtils; +import io.apicurio.tests.utils.RestConstants; +import io.apicurio.tests.utils.TestSeparator; +import io.quarkus.test.common.http.TestHTTPResource; +import io.restassured.RestAssured; +import io.restassured.parsing.Parser; +import io.restassured.response.Response; +import org.eclipse.microprofile.config.ConfigProvider; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.io.UncheckedIOException; +import java.io.UnsupportedEncodingException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeoutException; +import java.util.function.BooleanSupplier; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static io.restassured.RestAssured.given; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Base class for all base classes for integration tests or for integration tests directly. + * This class must not contain any functionality nor implement any beforeAll, beforeEach. + * + * @author Carles Arnal + */ +@DisplayNameGeneration(SimpleDisplayName.class) +@TestInstance(Lifecycle.PER_CLASS) +@ExtendWith(PortForwardManager.class) +public class ApicurioRegistryBaseIT implements TestSeparator, Constants { + + private static final Logger log = LoggerFactory.getLogger(TestUtils.class); + + @TestHTTPResource + static URL REGISTRY_URL; + + protected final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + protected Function errorCodeExtractor = e -> ((RestClientException) e).getError().getErrorCode(); + + protected RegistryClient registryClient; + + protected String authServerUrlConfigured; + + protected RegistryClient createRegistryClient() { + return RegistryClientFactory.create(getRegistryBaseUrl()); + } + + @BeforeAll + void prepareRestAssured() { + authServerUrlConfigured = Optional.ofNullable(ConfigProvider.getConfig().getConfigValue("registry.auth.token.endpoint").getValue()) + .orElse("http://localhost:8090/realms/registry/protocol/openid-connect/token"); + registryClient = createRegistryClient(); + RestAssured.baseURI = getRegistryV2ApiUrl(); + logger.info("RestAssured configured with {}", RestAssured.baseURI); + RestAssured.defaultParser = Parser.JSON; + RestAssured.urlEncodingEnabled = false; + } + + @AfterEach + public void cleanArtifacts() throws Exception { + logger.info("Removing all artifacts"); + // Retrying to delete artifacts can solve the problem with bad order caused by artifacts references + // TODO: Solve problem with artifact references circle - maybe use of deleteAllUserData for cleaning artifacts after IT + retry(() -> { + ArtifactSearchResults artifacts = registryClient.searchArtifacts(null, null, null, null, null, null, null, null, null); + for (SearchedArtifact artifact : artifacts.getArtifacts()) { + try { + registryClient.deleteArtifact(artifact.getGroupId(), artifact.getId()); + registryClient.deleteArtifactsInGroup(null); + } catch (ArtifactNotFoundException e) { + //because of async storage artifact may be already deleted but listed anyway + logger.info(e.getMessage()); + } catch (Exception e) { + logger.error("", e); + } + } + ensureClusterSync(client -> assertTrue(client.searchArtifacts(null, null, null, null, null, null, null, null, null).getCount() == 0)); + }, "CleanArtifacts", 5); + } + + protected ArtifactMetaData createArtifact(String groupId, String artifactId, String artifactType, InputStream artifact) throws Exception { + ArtifactMetaData amd = registryClient.createArtifact(groupId, artifactId, null, artifactType, IfExists.FAIL, false, artifact); + + // make sure we have schema registered + ensureClusterSync(amd.getGlobalId()); + ensureClusterSync(amd.getGroupId(), amd.getId(), String.valueOf(amd.getVersion())); + + return amd; + } + + protected ArtifactMetaData createArtifact(String groupId, String artifactId, String version, IfExists ifExists, String artifactType, InputStream artifact) throws Exception { + ArtifactMetaData amd = registryClient.createArtifact(groupId, artifactId, version, artifactType, ifExists, false, artifact); + + // make sure we have schema registered + ensureClusterSync(amd.getGlobalId()); + ensureClusterSync(amd.getGroupId(), amd.getId(), String.valueOf(amd.getVersion())); + + return amd; + } + + protected VersionMetaData createArtifactVersion(String groupId, String artifactId, InputStream artifact) throws Exception { + VersionMetaData meta = registryClient.createArtifactVersion(groupId, artifactId, null, artifact); + + //wait for storage + ensureClusterSync(meta.getGlobalId()); + ensureClusterSync(meta.getGroupId(), meta.getId(), String.valueOf(meta.getVersion())); + + return meta; + } + + protected ArtifactMetaData updateArtifact(String groupId, String artifactId, InputStream artifact) throws Exception { + ArtifactMetaData meta = registryClient.updateArtifact(groupId, artifactId, artifact); + + //wait for storage + ensureClusterSync(meta.getGlobalId()); + ensureClusterSync(meta.getGroupId(), meta.getId(), String.valueOf(meta.getVersion())); + + return meta; + } + + //DO NOT USE FOR CREATE OR UPDATE OPERATIONS + protected void retryOp(RegistryWaitUtils.ConsumerExc registryOp) throws Exception { + RegistryWaitUtils.retry(registryClient, registryOp); + } + + //DO NOT USE FOR CREATE OR UPDATE OPERATIONS + protected void retryAssertClientError(String expectedErrorName, int expectedCode, RegistryWaitUtils.ConsumerExc registryOp, Function errorCodeExtractor) throws Exception { + RegistryWaitUtils.retry(registryClient, (rc) -> { + assertClientError(expectedErrorName, expectedCode, () -> registryOp.run(rc), errorCodeExtractor); + }); + } + + private void ensureClusterSync(Long globalId) throws Exception { + if (registryClient instanceof LoadBalanceRegistryClient) { + LoadBalanceRegistryClient loadBalanceRegistryClient = (LoadBalanceRegistryClient) registryClient; + + var nodes = loadBalanceRegistryClient.getRegistryNodes(); + + retry(() -> { + for (LoadBalanceRegistryClient.RegistryClientHolder target : nodes) { + target.client.getContentByGlobalId(globalId); + } + }); + } else { + retry(() -> registryClient.getContentByGlobalId(globalId)); + } + } + + private void ensureClusterSync(String groupId, String artifactId, String version) throws Exception { + if (registryClient instanceof LoadBalanceRegistryClient) { + LoadBalanceRegistryClient loadBalanceRegistryClient = (LoadBalanceRegistryClient) registryClient; + + var nodes = loadBalanceRegistryClient.getRegistryNodes(); + + retry(() -> { + for (LoadBalanceRegistryClient.RegistryClientHolder target : nodes) { + target.client.getArtifactVersionMetaData(groupId, artifactId, version); + } + }); + } else { + retry(() -> registryClient.getArtifactVersionMetaData(groupId, artifactId, version)); + } + } + + private void ensureClusterSync(Consumer function) throws Exception { + if (registryClient instanceof LoadBalanceRegistryClient) { + LoadBalanceRegistryClient loadBalanceRegistryClient = (LoadBalanceRegistryClient) registryClient; + + var nodes = loadBalanceRegistryClient.getRegistryNodes(); + + retry(() -> { + for (LoadBalanceRegistryClient.RegistryClientHolder target : nodes) { + function.accept(target.client); + } + }); + } else { + retry(() -> function.accept(registryClient)); + } + } + + protected List listArtifactVersions(RegistryClient rc, String groupId, String artifactId) { + return rc.listArtifactVersions(groupId, artifactId, 0, 10) + .getVersions() + .stream() + .map(SearchedVersion::getVersion) + .collect(Collectors.toList()); + } + + public static String resourceToString(String resourceName) { + try (InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName)) { + Assertions.assertNotNull(stream, "Resource not found: " + resourceName); + return new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n")); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static String getRegistryHost() { + if (REGISTRY_URL != null) { + return REGISTRY_URL.getHost(); + } else { + return System.getProperty("quarkus.http.test-host"); + } + } + + public static int getRegistryPort() { + return Integer.parseInt(System.getProperty("quarkus.http.test-port")); + } + + public static String getRegistryUIUrl() { + return getRegistryBaseUrl().concat("/ui"); + } + + public static String getRegistryApiUrl() { + return getRegistryBaseUrl().concat("/apis"); + } + + public static String getRegistryApiUrl(int port) { + return getRegistryBaseUrl(port).concat("/apis"); + } + + public static String getRegistryV1ApiUrl() { + return getRegistryApiUrl().concat("/registry/v1"); + } + + public static String getRegistryV2ApiUrl() { + return getRegistryApiUrl().concat("/registry/v2"); + } + + public static String getRegistryV2ApiUrl(int testPort) { + return getRegistryApiUrl(testPort).concat("/registry/v2"); + } + + public static String getRegistryBaseUrl() { + if (REGISTRY_URL != null) { + return String.format("http://%s:%s", REGISTRY_URL.getHost(), REGISTRY_URL.getPort()); + } else { + return String.format("http://%s:%s", System.getProperty("quarkus.http.test-host"), System.getProperty("quarkus.http.test-port")); + } + } + + public static String getRegistryBaseUrl(int port) { + if (REGISTRY_URL != null) { + return String.format("http://%s:%s", REGISTRY_URL.getHost(), port); + } else { + return String.format("http://%s:%s", System.getProperty("quarkus.http.test-host"), port); + } + } + + public static String getTenantManagerUrl() { + if (System.getProperty("tenant.manager.external.endpoint") != null) { + return String.format("http://%s:%s", System.getProperty("tenant.manager.external.endpoint"), 8585); + } + + return "http://localhost:8585"; + } + + public static String getKeycloakBaseUrl() { + if (System.getProperty("keycloak.external.endpoint") != null) { + return String.format("http://%s:%s", System.getProperty("keycloak.external.endpoint"), 8090); + } + + return "http://localhost:8090"; + } + + /** + * Method which try connection to registries. It's used as a initial check for registries availability. + * + * @return true if registries are ready for use, false in other cases + */ + public boolean isReachable() { + try (Socket socket = new Socket()) { + String host = REGISTRY_URL.getHost(); + int port = REGISTRY_URL.getPort(); + log.info("Trying to connect to {}:{}", host, port); + socket.connect(new InetSocketAddress(host, port), 5_000); + log.info("Client is able to connect to Registry instance"); + return true; + } catch (IOException ex) { + log.warn("Cannot connect to Registry instance: {}", ex.getMessage()); + return false; // Either timeout or unreachable or failed DNS lookup. + } + } + // --- + + /** + * Poll the given {@code ready} function every {@code pollIntervalMs} milliseconds until it returns true, + * or throw a TimeoutException if it doesn't returns true within {@code timeoutMs} milliseconds. + * (helpful if you have several calls which need to share a common timeout) + * + * @return The remaining time left until timeout occurs + */ + public long waitFor(String description, long pollIntervalMs, long timeoutMs, BooleanSupplier ready) throws TimeoutException { + return waitFor(description, pollIntervalMs, timeoutMs, ready, () -> { + }); + } + + public long waitFor(String description, long pollIntervalMs, long timeoutMs, BooleanSupplier ready, Runnable onTimeout) throws TimeoutException { + log.debug("Waiting for {}", description); + long deadline = System.currentTimeMillis() + timeoutMs; + while (true) { + boolean result; + try { + result = ready.getAsBoolean(); + } catch (Throwable e) { + result = false; + } + long timeLeft = deadline - System.currentTimeMillis(); + if (result) { + return timeLeft; + } + if (timeLeft <= 0) { + onTimeout.run(); + TimeoutException exception = new TimeoutException("Timeout after " + timeoutMs + " ms waiting for " + description); + exception.printStackTrace(); + throw exception; + } + long sleepTime = Math.min(pollIntervalMs, timeLeft); + if (log.isTraceEnabled()) { + log.trace("{} not ready, will try again in {} ms ({}ms till timeout)", description, sleepTime, timeLeft); + } + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + return deadline - System.currentTimeMillis(); + } + } + } + + /** + * Method to create and write String content file. + * + * @param filePath path to file + * @param text content + */ + public void writeFile(String filePath, String text) { + try { + Files.write(new File(filePath).toPath(), text.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + log.info("Exception during writing text in file"); + } + } + + public void writeFile(Path filePath, String text) { + try { + Files.write(filePath, text.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + log.info("Exception during writing text in file"); + } + } + + public String generateTopic() { + return generateTopic("topic-"); + } + + public String generateTopic(String prefix) { + return prefix + UUID.randomUUID().toString(); + } + + public String generateSubject() { + return "s" + generateArtifactId().replace("-", "x"); + } + + public String generateArtifactId() { + return UUID.randomUUID().toString(); + } + + public String generateGroupId() { + return UUID.randomUUID().toString(); + } + + @FunctionalInterface + public interface RunnableExc { + void run() throws Exception; + + } + + public void retry(TestUtils.RunnableExc runnable) throws Exception { + retry(() -> { + runnable.run(); + return null; + }); + } + + public void retry(TestUtils.RunnableExc runnable, long delta) throws Exception { + retry(() -> { + runnable.run(); + return null; + }, delta); + } + + public T retry(Callable callable) throws Exception { + return retry(callable, "Action #" + System.currentTimeMillis(), 20); + } + + public T retry(Callable callable, long delta) throws Exception { + return retry(callable, "Action #" + System.currentTimeMillis(), 20, delta); + } + + public void retry(TestUtils.RunnableExc runnable, String name, int maxRetries) throws Exception { + retry(() -> { + runnable.run(); + return null; + }, name, maxRetries); + } + + private T retry(Callable callable, String name, int maxRetries) throws Exception { + return retry(callable, name, maxRetries, 100L); + } + + private T retry(Callable callable, String name, int maxRetries, long delta) throws Exception { + Throwable error = null; + int tries = maxRetries; + int attempt = 1; + while (tries > 0) { + try { + if (attempt > 1) { + log.debug("Retrying action [{}]. Attempt #{}", name, attempt); + } + return callable.call(); + } catch (Throwable t) { + if (error == null) { + error = t; + } else { + error.addSuppressed(t); + } + Thread.sleep(delta * attempt); + tries--; + attempt++; + } + } + log.debug("Action [{}] failed after {} attempts.", name, attempt); + Assertions.assertTrue(tries > 0, String.format("Failed handle callable: %s [%s]", callable, error)); + throw new IllegalStateException("Should not be here!"); + } + + public void assertClientError(String expectedErrorName, int expectedCode, TestUtils.RunnableExc runnable, Function errorCodeExtractor) throws Exception { + try { + internalAssertClientError(expectedErrorName, expectedCode, runnable, errorCodeExtractor); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + public void assertClientError(String expectedErrorName, int expectedCode, TestUtils.RunnableExc runnable, boolean retry, Function errorCodeExtractor) throws Exception { + if (retry) { + retry(() -> internalAssertClientError(expectedErrorName, expectedCode, runnable, errorCodeExtractor)); + } else { + internalAssertClientError(expectedErrorName, expectedCode, runnable, errorCodeExtractor); + } + } + + private void internalAssertClientError(String expectedErrorName, int expectedCode, TestUtils.RunnableExc runnable, Function errorCodeExtractor) { + try { + runnable.run(); + Assertions.fail("Expected (but didn't get) a registry client application exception with code: " + expectedCode); + } catch (Exception e) { + Assertions.assertEquals(expectedErrorName, e.getClass().getSimpleName(), () -> "e: " + e); + Assertions.assertEquals(expectedCode, errorCodeExtractor.apply(e)); + } + } + + // some impl details ... + + public void waitForSchema(Predicate schemaFinder, byte[] bytes) throws Exception { + waitForSchema(schemaFinder, bytes, ByteBuffer::getLong); + } + + public void waitForSchema(Predicate schemaFinder, byte[] bytes, Function globalIdExtractor) throws Exception { + waitForSchemaCustom(schemaFinder, bytes, input -> { + ByteBuffer buffer = ByteBuffer.wrap(input); + buffer.get(); // magic byte + return globalIdExtractor.apply(buffer); + }); + } + + // we can have non-default Apicurio serialization; e.g. ExtJsonConverter + public void waitForSchemaCustom(Predicate schemaFinder, byte[] bytes, Function globalIdExtractor) throws Exception { + long id = globalIdExtractor.apply(bytes); + boolean schemaExists = retry(() -> schemaFinder.test(id)); + Assertions.assertTrue(schemaExists); // wait for global id to populate + } + + public final String normalizeMultiLineString(String value) throws Exception { + StringBuilder builder = new StringBuilder(); + BufferedReader reader = new BufferedReader(new StringReader(value)); + String line = reader.readLine(); + while (line != null) { + builder.append(line); + builder.append("\n"); + line = reader.readLine(); + } + return builder.toString(); + } + + + public Response getArtifact(String groupId, String artifactId) { + return getArtifact(groupId, artifactId, "", 200); + } + + public Response getArtifact(String groupId, String artifactId, int returnCode) { + return getArtifact(groupId, artifactId, "", returnCode); + } + + public Response getArtifact(String groupId, String artifactId, String version, int returnCode) { + return + getRequest(RestConstants.JSON, "/groups/" + encodeURIComponent(groupId) + "/artifacts/" + encodeURIComponent(artifactId) + "/" + version, returnCode); + } + + public Response createArtifact(String groupId, String artifactId, String artifact, int returnCode) { + return artifactPostRequest(artifactId, RestConstants.JSON, artifact, "/groups/" + encodeURIComponent(groupId) + "/artifacts", returnCode); + } + + private String encodeURIComponent(String value) { + try { + return URLEncoder.encode(value, StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + throw new UncheckedIOException(e); + } + } + + public Response getRequest(String contentType, String endpoint, int returnCode) { + return given() + .when() + .contentType(contentType) + .get(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } + + public Response getRequest(String contentType, URL endpoint, int returnCode) { + return given() + .when() + .contentType(contentType) + .get(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } + + public Response postRequest(String contentType, String body, String endpoint, int returnCode) { + return given() + .when() + .contentType(contentType) + .body(body) + .post(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } + + public Response postRequest(String contentType, String body, URL endpoint, int returnCode) { + return given() + .when() + .contentType(contentType) + .body(body) + .post(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } + + public Response putRequest(String contentType, String body, String endpoint, int returnCode) { + return given() + .when() + .contentType(contentType) + .body(body) + .put(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } + + public Response putRequest(String contentType, String body, URL endpoint, int returnCode) { + return given() + .when() + .contentType(contentType) + .body(body) + .put(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } + + public Response deleteRequest(String contentType, String endpoint, int returnCode) { + return given() + .when() + .contentType(contentType) + .delete(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } + + public Response rulesPostRequest(String contentType, String rule, String endpoint, int returnCode) { + return given() + .when() + .contentType(contentType) + .body(rule) + .post(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } + + public Response rulesPostRequest(String contentType, String rule, URL endpoint, int returnCode) { + return given() + .when() + .contentType(contentType) + .body(rule) + .post(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } + + public Response rulesGetRequest(String contentType, String endpoint, int returnCode) { + return given() + .when() + .contentType(contentType) + .get(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } + + public Response rulesPutRequest(String contentType, String rule, String endpoint, int returnCode) { + return given() + .when() + .contentType(contentType) + .body(rule) + .put(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } + + public Response rulesDeleteRequest(String contentType, String endpoint, int returnCode) { + return given() + .when() + .contentType(contentType) + .delete(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } + + public Response artifactPostRequest(String artifactId, String contentType, String body, String endpoint, int returnCode) { + return given() + .when() + .header("X-Registry-Artifactid", artifactId) + .contentType(contentType) + .body(body) + .post(getRegistryV2ApiUrl() + endpoint) + .then() + .statusCode(returnCode) + .extract() + .response(); + } +} diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ConfluentBaseIT.java b/integration-tests/src/test/java/io/apicurio/tests/ConfluentBaseIT.java similarity index 94% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/ConfluentBaseIT.java rename to integration-tests/src/test/java/io/apicurio/tests/ConfluentBaseIT.java index 0825461ed2..f31e6cbf77 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ConfluentBaseIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ConfluentBaseIT.java @@ -15,31 +15,30 @@ */ package io.apicurio.tests; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.io.IOException; -import java.util.concurrent.TimeoutException; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.TestInfo; - +import io.apicurio.tests.utils.Constants; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.common.Constants; import io.confluent.kafka.schemaregistry.ParsedSchema; import io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient; import io.confluent.kafka.schemaregistry.client.SchemaRegistryClient; import io.confluent.kafka.schemaregistry.client.rest.exceptions.RestClientException; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInfo; + +import java.io.IOException; +import java.util.concurrent.TimeoutException; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; -public abstract class ConfluentBaseIT extends ApicurioV2BaseIT { +public abstract class ConfluentBaseIT extends ApicurioRegistryBaseIT { protected SchemaRegistryClient confluentService; @BeforeAll void confluentBeforeAll(TestInfo info) throws Exception { - confluentService = new CachedSchemaRegistryClient(TestUtils.getRegistryApiUrl() + "/ccompat/v6", 3); + confluentService = new CachedSchemaRegistryClient(ApicurioRegistryBaseIT.getRegistryApiUrl() + "/ccompat/v6", 3); clearAllConfluentSubjects(); } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/auth/SimpleAuthIT.java b/integration-tests/src/test/java/io/apicurio/tests/auth/SimpleAuthIT.java similarity index 78% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/auth/SimpleAuthIT.java rename to integration-tests/src/test/java/io/apicurio/tests/auth/SimpleAuthIT.java index d806bf58c2..d4450cd7ea 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/auth/SimpleAuthIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/auth/SimpleAuthIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,18 @@ package io.apicurio.tests.auth; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.io.ByteArrayInputStream; -import java.util.Collections; -import java.util.UUID; - +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.Constants; +import io.apicurio.registry.rest.client.RegistryClient; +import io.apicurio.registry.rest.client.RegistryClientFactory; +import io.apicurio.registry.rest.client.exception.ArtifactNotFoundException; +import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; +import io.apicurio.registry.rest.v2.beans.Rule; +import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.types.RuleType; +import io.apicurio.registry.utils.tests.AuthTestProfile; +import io.apicurio.registry.utils.tests.JWKSMockServer; +import io.apicurio.registry.utils.tests.TestUtils; import io.apicurio.rest.client.auth.Auth; import io.apicurio.rest.client.auth.OidcAuth; import io.apicurio.rest.client.auth.exception.AuthErrorHandler; @@ -29,49 +35,52 @@ import io.apicurio.rest.client.auth.exception.NotAuthorizedException; import io.apicurio.rest.client.spi.ApicurioHttpClient; import io.apicurio.rest.client.spi.ApicurioHttpClientFactory; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import io.quarkus.test.junit.TestProfile; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import io.apicurio.registry.rest.client.RegistryClient; -import io.apicurio.registry.rest.client.RegistryClientFactory; -import io.apicurio.registry.rest.client.exception.ArtifactNotFoundException; -import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; -import io.apicurio.registry.rest.v2.beans.Rule; -import io.apicurio.registry.types.ArtifactType; -import io.apicurio.registry.types.RuleType; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.common.ApicurioRegistryBaseIT; -import io.apicurio.tests.common.AuthServerInfo; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.RegistryFacade; +import java.io.ByteArrayInputStream; +import java.util.Collections; + +import static org.junit.jupiter.api.Assertions.assertNotNull; /** - * @author Fabian Martinez + * @author Carles Arnal */ @Tag(Constants.AUTH) +@TestProfile(AuthTestProfile.class) +@QuarkusIntegrationTest public class SimpleAuthIT extends ApicurioRegistryBaseIT { - private RegistryFacade facade = RegistryFacade.getInstance(); - ApicurioHttpClient httpClient; protected ApicurioHttpClient getHttpClient() { - AuthServerInfo authServerInfo = facade.getAuthServerInfo(); if (httpClient == null) { - httpClient = ApicurioHttpClientFactory.create(authServerInfo.getAuthServerUrlConfigured(), new AuthErrorHandler()); + httpClient = ApicurioHttpClientFactory.create(authServerUrlConfigured, new AuthErrorHandler()); } return httpClient; } + @Override + public void cleanArtifacts() throws Exception { + //Don't clean + } + + @Override + protected RegistryClient createRegistryClient() { + Auth auth = new OidcAuth(getHttpClient(), JWKSMockServer.ADMIN_CLIENT_ID, "test1"); + return createClient(auth); + } + private RegistryClient createClient(Auth auth) { - return RegistryClientFactory.create(TestUtils.getRegistryBaseUrl(), Collections.emptyMap(), auth); + return RegistryClientFactory.create(getRegistryBaseUrl(), Collections.emptyMap(), auth); } @Test public void testWrongCreds() throws Exception { - AuthServerInfo authServerInfo = facade.getAuthServerInfo(); - Auth auth = new OidcAuth(getHttpClient(), authServerInfo.getReadOnlyClientId(), UUID.randomUUID().toString()); + Auth auth = new OidcAuth(getHttpClient(), JWKSMockServer.WRONG_CREDS_CLIENT_ID, "test55"); RegistryClient client = createClient(auth); Assertions.assertThrows(NotAuthorizedException.class, () -> { client.listArtifactsInGroup("foo"); @@ -80,8 +89,7 @@ public void testWrongCreds() throws Exception { @Test public void testReadOnly() throws Exception { - AuthServerInfo authServerInfo = facade.getAuthServerInfo(); - Auth auth = new OidcAuth(getHttpClient(), authServerInfo.getReadOnlyClientId(), authServerInfo.getReadOnlyClientSecret()); + Auth auth = new OidcAuth(getHttpClient(), JWKSMockServer.READONLY_CLIENT_ID, "test1"); RegistryClient client = createClient(auth); String groupId = TestUtils.generateGroupId(); @@ -93,7 +101,7 @@ public void testReadOnly() throws Exception { client.createArtifact("ccc", artifactId, ArtifactType.JSON, new ByteArrayInputStream("{}".getBytes())); }); { - Auth devAuth = new OidcAuth(getHttpClient(), authServerInfo.getDeveloperClientId(), authServerInfo.getDeveloperClientSecret()); + Auth devAuth = new OidcAuth(getHttpClient(), JWKSMockServer.DEVELOPER_CLIENT_ID, "test1"); RegistryClient devClient = createClient(devAuth); ArtifactMetaData meta = devClient.createArtifact(groupId, artifactId, ArtifactType.JSON, new ByteArrayInputStream("{}".getBytes())); TestUtils.retry(() -> devClient.getArtifactMetaData(groupId, meta.getId())); @@ -103,8 +111,7 @@ public void testReadOnly() throws Exception { @Test public void testDevRole() throws Exception { - AuthServerInfo authServerInfo = facade.getAuthServerInfo(); - Auth devAuth = new OidcAuth(getHttpClient(), authServerInfo.getDeveloperClientId(), authServerInfo.getDeveloperClientSecret()); + Auth devAuth = new OidcAuth(getHttpClient(), JWKSMockServer.DEVELOPER_CLIENT_ID, "test1"); RegistryClient client = createClient(devAuth); String groupId = TestUtils.generateGroupId(); @@ -132,8 +139,7 @@ public void testDevRole() throws Exception { @Test public void testAdminRole() throws Exception { - AuthServerInfo authServerInfo = facade.getAuthServerInfo(); - Auth auth = new OidcAuth(getHttpClient(), authServerInfo.getAdminClientId(), authServerInfo.getAdminClientSecret()); + Auth auth = new OidcAuth(getHttpClient(), JWKSMockServer.ADMIN_CLIENT_ID, "test1"); RegistryClient client = createClient(auth); String groupId = TestUtils.generateGroupId(); @@ -153,5 +159,4 @@ public void testAdminRole() throws Exception { client.deleteArtifact(groupId, artifactId); } } - } \ No newline at end of file diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/TestObject.java b/integration-tests/src/test/java/io/apicurio/tests/common/serdes/TestObject.java similarity index 98% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/TestObject.java rename to integration-tests/src/test/java/io/apicurio/tests/common/serdes/TestObject.java index 379a77d13d..4de2415d2a 100644 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/TestObject.java +++ b/integration-tests/src/test/java/io/apicurio/tests/common/serdes/TestObject.java @@ -20,7 +20,7 @@ /** - * @author Fabian Martinez + * @author Carles Arnal */ public class TestObject { diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/json/InvalidMessage.java b/integration-tests/src/test/java/io/apicurio/tests/common/serdes/json/InvalidMessage.java similarity index 100% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/json/InvalidMessage.java rename to integration-tests/src/test/java/io/apicurio/tests/common/serdes/json/InvalidMessage.java diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/json/Msg.java b/integration-tests/src/test/java/io/apicurio/tests/common/serdes/json/Msg.java similarity index 100% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/json/Msg.java rename to integration-tests/src/test/java/io/apicurio/tests/common/serdes/json/Msg.java diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/json/ValidMessage.java b/integration-tests/src/test/java/io/apicurio/tests/common/serdes/json/ValidMessage.java similarity index 100% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/json/ValidMessage.java rename to integration-tests/src/test/java/io/apicurio/tests/common/serdes/json/ValidMessage.java diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/proto/MsgTypes.java b/integration-tests/src/test/java/io/apicurio/tests/common/serdes/proto/MsgTypes.java similarity index 74% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/proto/MsgTypes.java rename to integration-tests/src/test/java/io/apicurio/tests/common/serdes/proto/MsgTypes.java index 23dff40cc5..6fc8d49c7b 100644 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/proto/MsgTypes.java +++ b/integration-tests/src/test/java/io/apicurio/tests/common/serdes/proto/MsgTypes.java @@ -39,7 +39,7 @@ public interface MsgOrBuilder extends * string what = 1; * @return The what. */ - java.lang.String getWhat(); + String getWhat(); /** * string what = 1; * @return The bytes for what. @@ -69,14 +69,14 @@ private Msg() { what_ = ""; } - @java.lang.Override + @Override @SuppressWarnings({"unused"}) - protected java.lang.Object newInstance( + protected Object newInstance( UnusedPrivateParameter unused) { return new Msg(); } - @java.lang.Override + @Override public final com.google.protobuf.UnknownFieldSet getUnknownFields() { return this.unknownFields; @@ -87,7 +87,7 @@ private Msg( throws com.google.protobuf.InvalidProtocolBufferException { this(); if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); + throw new NullPointerException(); } com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet.newBuilder(); @@ -100,7 +100,7 @@ private Msg( done = true; break; case 10: { - java.lang.String s = input.readStringRequireUtf8(); + String s = input.readStringRequireUtf8(); what_ = s; break; @@ -131,31 +131,31 @@ private Msg( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.apicurio.tests.common.serdes.proto.MsgTypes.internal_static_io_apicurio_tests_serdes_proto_Msg_descriptor; + return MsgTypes.internal_static_io_apicurio_tests_serdes_proto_Msg_descriptor; } - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + @Override + protected FieldAccessorTable internalGetFieldAccessorTable() { - return io.apicurio.tests.common.serdes.proto.MsgTypes.internal_static_io_apicurio_tests_serdes_proto_Msg_fieldAccessorTable + return MsgTypes.internal_static_io_apicurio_tests_serdes_proto_Msg_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.apicurio.tests.common.serdes.proto.MsgTypes.Msg.class, io.apicurio.tests.common.serdes.proto.MsgTypes.Msg.Builder.class); + MsgTypes.Msg.class, MsgTypes.Msg.Builder.class); } public static final int WHAT_FIELD_NUMBER = 1; - private volatile java.lang.Object what_; + private volatile Object what_; /** * string what = 1; * @return The what. */ - public java.lang.String getWhat() { - java.lang.Object ref = what_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; + public String getWhat() { + Object ref = what_; + if (ref instanceof String) { + return (String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); what_ = s; return s; } @@ -166,11 +166,11 @@ public java.lang.String getWhat() { */ public com.google.protobuf.ByteString getWhatBytes() { - java.lang.Object ref = what_; - if (ref instanceof java.lang.String) { + Object ref = what_; + if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); what_ = b; return b; } else { @@ -189,7 +189,7 @@ public long getWhen() { } private byte memoizedIsInitialized = -1; - @java.lang.Override + @Override public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; @@ -199,7 +199,7 @@ public final boolean isInitialized() { return true; } - @java.lang.Override + @Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (!getWhatBytes().isEmpty()) { @@ -211,7 +211,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) unknownFields.writeTo(output); } - @java.lang.Override + @Override public int getSerializedSize() { int size = memoizedSize; if (size != -1) return size; @@ -229,15 +229,15 @@ public int getSerializedSize() { return size; } - @java.lang.Override - public boolean equals(final java.lang.Object obj) { + @Override + public boolean equals(final Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.apicurio.tests.common.serdes.proto.MsgTypes.Msg)) { + if (!(obj instanceof MsgTypes.Msg)) { return super.equals(obj); } - io.apicurio.tests.common.serdes.proto.MsgTypes.Msg other = (io.apicurio.tests.common.serdes.proto.MsgTypes.Msg) obj; + MsgTypes.Msg other = (MsgTypes.Msg) obj; if (!getWhat() .equals(other.getWhat())) return false; @@ -247,7 +247,7 @@ public boolean equals(final java.lang.Object obj) { return true; } - @java.lang.Override + @Override public int hashCode() { if (memoizedHashCode != 0) { return memoizedHashCode; @@ -264,69 +264,69 @@ public int hashCode() { return hash; } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseFrom( + public static MsgTypes.Msg parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseFrom( + public static MsgTypes.Msg parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseFrom( + public static MsgTypes.Msg parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseFrom( + public static MsgTypes.Msg parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseFrom(byte[] data) + public static MsgTypes.Msg parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseFrom( + public static MsgTypes.Msg parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseFrom(java.io.InputStream input) + public static MsgTypes.Msg parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseFrom( + public static MsgTypes.Msg parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseDelimitedFrom(java.io.InputStream input) + public static MsgTypes.Msg parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseDelimitedFrom( + public static MsgTypes.Msg parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseFrom( + public static MsgTypes.Msg parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseFrom( + public static MsgTypes.Msg parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -334,23 +334,23 @@ public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parseFrom( .parseWithIOException(PARSER, input, extensionRegistry); } - @java.lang.Override + @Override public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.apicurio.tests.common.serdes.proto.MsgTypes.Msg prototype) { + public static Builder newBuilder(MsgTypes.Msg prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } - @java.lang.Override + @Override public Builder toBuilder() { return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); } - @java.lang.Override + @Override protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + BuilderParent parent) { Builder builder = new Builder(parent); return builder; } @@ -360,18 +360,18 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements // @@protoc_insertion_point(builder_implements:io.apicurio.tests.serdes.proto.Msg) - io.apicurio.tests.common.serdes.proto.MsgTypes.MsgOrBuilder { + MsgTypes.MsgOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.apicurio.tests.common.serdes.proto.MsgTypes.internal_static_io_apicurio_tests_serdes_proto_Msg_descriptor; + return MsgTypes.internal_static_io_apicurio_tests_serdes_proto_Msg_descriptor; } - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + @Override + protected FieldAccessorTable internalGetFieldAccessorTable() { - return io.apicurio.tests.common.serdes.proto.MsgTypes.internal_static_io_apicurio_tests_serdes_proto_Msg_fieldAccessorTable + return MsgTypes.internal_static_io_apicurio_tests_serdes_proto_Msg_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.apicurio.tests.common.serdes.proto.MsgTypes.Msg.class, io.apicurio.tests.common.serdes.proto.MsgTypes.Msg.Builder.class); + MsgTypes.Msg.class, MsgTypes.Msg.Builder.class); } // Construct using io.apicurio.tests.serdes.proto.MsgTypes.Msg.newBuilder() @@ -380,7 +380,7 @@ private Builder() { } private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + BuilderParent parent) { super(parent); maybeForceBuilderInitialization(); } @@ -389,7 +389,7 @@ private void maybeForceBuilderInitialization() { .alwaysUseFieldBuilders) { } } - @java.lang.Override + @Override public Builder clear() { super.clear(); what_ = ""; @@ -399,79 +399,79 @@ public Builder clear() { return this; } - @java.lang.Override + @Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.apicurio.tests.common.serdes.proto.MsgTypes.internal_static_io_apicurio_tests_serdes_proto_Msg_descriptor; + return MsgTypes.internal_static_io_apicurio_tests_serdes_proto_Msg_descriptor; } - @java.lang.Override - public io.apicurio.tests.common.serdes.proto.MsgTypes.Msg getDefaultInstanceForType() { - return io.apicurio.tests.common.serdes.proto.MsgTypes.Msg.getDefaultInstance(); + @Override + public MsgTypes.Msg getDefaultInstanceForType() { + return MsgTypes.Msg.getDefaultInstance(); } - @java.lang.Override - public io.apicurio.tests.common.serdes.proto.MsgTypes.Msg build() { - io.apicurio.tests.common.serdes.proto.MsgTypes.Msg result = buildPartial(); + @Override + public MsgTypes.Msg build() { + MsgTypes.Msg result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } - @java.lang.Override - public io.apicurio.tests.common.serdes.proto.MsgTypes.Msg buildPartial() { - io.apicurio.tests.common.serdes.proto.MsgTypes.Msg result = new io.apicurio.tests.common.serdes.proto.MsgTypes.Msg(this); + @Override + public MsgTypes.Msg buildPartial() { + MsgTypes.Msg result = new MsgTypes.Msg(this); result.what_ = what_; result.when_ = when_; onBuilt(); return result; } - @java.lang.Override + @Override public Builder clone() { return super.clone(); } - @java.lang.Override + @Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { + Object value) { return super.setField(field, value); } - @java.lang.Override + @Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { return super.clearField(field); } - @java.lang.Override + @Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { return super.clearOneof(oneof); } - @java.lang.Override + @Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { + int index, Object value) { return super.setRepeatedField(field, index, value); } - @java.lang.Override + @Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { + Object value) { return super.addRepeatedField(field, value); } - @java.lang.Override + @Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.apicurio.tests.common.serdes.proto.MsgTypes.Msg) { - return mergeFrom((io.apicurio.tests.common.serdes.proto.MsgTypes.Msg)other); + if (other instanceof MsgTypes.Msg) { + return mergeFrom((MsgTypes.Msg)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.apicurio.tests.common.serdes.proto.MsgTypes.Msg other) { - if (other == io.apicurio.tests.common.serdes.proto.MsgTypes.Msg.getDefaultInstance()) return this; + public Builder mergeFrom(MsgTypes.Msg other) { + if (other == MsgTypes.Msg.getDefaultInstance()) return this; if (!other.getWhat().isEmpty()) { what_ = other.what_; onChanged(); @@ -484,21 +484,21 @@ public Builder mergeFrom(io.apicurio.tests.common.serdes.proto.MsgTypes.Msg othe return this; } - @java.lang.Override + @Override public final boolean isInitialized() { return true; } - @java.lang.Override + @Override public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - io.apicurio.tests.common.serdes.proto.MsgTypes.Msg parsedMessage = null; + MsgTypes.Msg parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (io.apicurio.tests.common.serdes.proto.MsgTypes.Msg) e.getUnfinishedMessage(); + parsedMessage = (MsgTypes.Msg) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -508,21 +508,21 @@ public Builder mergeFrom( return this; } - private java.lang.Object what_ = ""; + private Object what_ = ""; /** * string what = 1; * @return The what. */ - public java.lang.String getWhat() { - java.lang.Object ref = what_; - if (!(ref instanceof java.lang.String)) { + public String getWhat() { + Object ref = what_; + if (!(ref instanceof String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); what_ = s; return s; } else { - return (java.lang.String) ref; + return (String) ref; } } /** @@ -531,11 +531,11 @@ public java.lang.String getWhat() { */ public com.google.protobuf.ByteString getWhatBytes() { - java.lang.Object ref = what_; + Object ref = what_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); what_ = b; return b; } else { @@ -548,7 +548,7 @@ public java.lang.String getWhat() { * @return This builder for chaining. */ public Builder setWhat( - java.lang.String value) { + String value) { if (value == null) { throw new NullPointerException(); } @@ -613,13 +613,13 @@ public Builder clearWhen() { onChanged(); return this; } - @java.lang.Override + @Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); } - @java.lang.Override + @Override public final Builder mergeUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.mergeUnknownFields(unknownFields); @@ -630,18 +630,18 @@ public final Builder mergeUnknownFields( } // @@protoc_insertion_point(class_scope:io.apicurio.tests.serdes.proto.Msg) - private static final io.apicurio.tests.common.serdes.proto.MsgTypes.Msg DEFAULT_INSTANCE; + private static final MsgTypes.Msg DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.apicurio.tests.common.serdes.proto.MsgTypes.Msg(); + DEFAULT_INSTANCE = new MsgTypes.Msg(); } - public static io.apicurio.tests.common.serdes.proto.MsgTypes.Msg getDefaultInstance() { + public static MsgTypes.Msg getDefaultInstance() { return DEFAULT_INSTANCE; } private static final com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override + @Override public Msg parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) @@ -654,13 +654,13 @@ public static com.google.protobuf.Parser parser() { return PARSER; } - @java.lang.Override + @Override public com.google.protobuf.Parser getParserForType() { return PARSER; } - @java.lang.Override - public io.apicurio.tests.common.serdes.proto.MsgTypes.Msg getDefaultInstanceForType() { + @Override + public MsgTypes.Msg getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -679,7 +679,7 @@ public io.apicurio.tests.common.serdes.proto.MsgTypes.Msg getDefaultInstanceForT private static com.google.protobuf.Descriptors.FileDescriptor descriptor; static { - java.lang.String[] descriptorData = { + String[] descriptorData = { "\n\tlog.proto\022\036io.apicurio.tests.serdes.pr" + "oto\"!\n\003Msg\022\014\n\004what\030\001 \001(\t\022\014\n\004when\030\002 \001(\006B*" + "\n\036io.apicurio.tests.serdes.protoB\010MsgTyp" + @@ -694,7 +694,7 @@ public io.apicurio.tests.common.serdes.proto.MsgTypes.Msg getDefaultInstanceForT internal_static_io_apicurio_tests_serdes_proto_Msg_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_io_apicurio_tests_serdes_proto_Msg_descriptor, - new java.lang.String[] { "What", "When", }); + new String[] { "What", "When", }); } // @@protoc_insertion_point(outer_class_scope) diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/proto/TestCmmn.java b/integration-tests/src/test/java/io/apicurio/tests/common/serdes/proto/TestCmmn.java similarity index 83% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/proto/TestCmmn.java rename to integration-tests/src/test/java/io/apicurio/tests/common/serdes/proto/TestCmmn.java index 2e6ec3e91c..03056794a7 100644 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/serdes/proto/TestCmmn.java +++ b/integration-tests/src/test/java/io/apicurio/tests/common/serdes/proto/TestCmmn.java @@ -43,14 +43,14 @@ private UUID(com.google.protobuf.GeneratedMessageV3.Builder builder) { private UUID() { } - @java.lang.Override + @Override @SuppressWarnings({"unused"}) - protected java.lang.Object newInstance( + protected Object newInstance( UnusedPrivateParameter unused) { return new UUID(); } - @java.lang.Override + @Override public final com.google.protobuf.UnknownFieldSet getUnknownFields() { return this.unknownFields; @@ -61,7 +61,7 @@ private UUID( throws com.google.protobuf.InvalidProtocolBufferException { this(); if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); + throw new NullPointerException(); } com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet.newBuilder(); @@ -107,12 +107,12 @@ private UUID( return TestCmmn.internal_static_io_apicurio_registry_common_proto_UUID_descriptor; } - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + @Override + protected FieldAccessorTable internalGetFieldAccessorTable() { return TestCmmn.internal_static_io_apicurio_registry_common_proto_UUID_fieldAccessorTable .ensureFieldAccessorsInitialized( - TestCmmn.UUID.class, TestCmmn.UUID.Builder.class); + UUID.class, Builder.class); } public static final int MSB_FIELD_NUMBER = 1; @@ -134,7 +134,7 @@ public long getLsb() { } private byte memoizedIsInitialized = -1; - @java.lang.Override + @Override public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; @@ -144,7 +144,7 @@ public final boolean isInitialized() { return true; } - @java.lang.Override + @Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (msb_ != 0L) { @@ -156,7 +156,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) unknownFields.writeTo(output); } - @java.lang.Override + @Override public int getSerializedSize() { int size = memoizedSize; if (size != -1) return size; @@ -175,15 +175,15 @@ public int getSerializedSize() { return size; } - @java.lang.Override - public boolean equals(final java.lang.Object obj) { + @Override + public boolean equals(final Object obj) { if (obj == this) { return true; } - if (!(obj instanceof TestCmmn.UUID)) { + if (!(obj instanceof UUID)) { return super.equals(obj); } - TestCmmn.UUID other = (TestCmmn.UUID) obj; + UUID other = (UUID) obj; if (getMsb() != other.getMsb()) return false; @@ -194,7 +194,7 @@ public boolean equals(final java.lang.Object obj) { } @SuppressWarnings("unchecked") - @java.lang.Override + @Override public int hashCode() { if (memoizedHashCode != 0) { return memoizedHashCode; @@ -212,69 +212,69 @@ public int hashCode() { return hash; } - public static TestCmmn.UUID parseFrom( + public static UUID parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static TestCmmn.UUID parseFrom( + public static UUID parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static TestCmmn.UUID parseFrom( + public static UUID parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static TestCmmn.UUID parseFrom( + public static UUID parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static TestCmmn.UUID parseFrom(byte[] data) + public static UUID parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static TestCmmn.UUID parseFrom( + public static UUID parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static TestCmmn.UUID parseFrom(java.io.InputStream input) + public static UUID parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static TestCmmn.UUID parseFrom( + public static UUID parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static TestCmmn.UUID parseDelimitedFrom(java.io.InputStream input) + public static UUID parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static TestCmmn.UUID parseDelimitedFrom( + public static UUID parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static TestCmmn.UUID parseFrom( + public static UUID parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static TestCmmn.UUID parseFrom( + public static UUID parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -282,23 +282,23 @@ public static TestCmmn.UUID parseFrom( .parseWithIOException(PARSER, input, extensionRegistry); } - @java.lang.Override + @Override public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(TestCmmn.UUID prototype) { + public static Builder newBuilder(UUID prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } - @java.lang.Override + @Override public Builder toBuilder() { return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); } - @java.lang.Override + @Override protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + BuilderParent parent) { Builder builder = new Builder(parent); return builder; } @@ -308,18 +308,18 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements // @@protoc_insertion_point(builder_implements:io.apicurio.registry.common.proto.UUID) - TestCmmn.UUIDOrBuilder { + UUIDOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { return TestCmmn.internal_static_io_apicurio_registry_common_proto_UUID_descriptor; } - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + @Override + protected FieldAccessorTable internalGetFieldAccessorTable() { return TestCmmn.internal_static_io_apicurio_registry_common_proto_UUID_fieldAccessorTable .ensureFieldAccessorsInitialized( - TestCmmn.UUID.class, TestCmmn.UUID.Builder.class); + UUID.class, Builder.class); } // Construct using io.apicurio.registry.support.Cmmn.UUID.newBuilder() @@ -328,7 +328,7 @@ private Builder() { } private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + BuilderParent parent) { super(parent); maybeForceBuilderInitialization(); } @@ -337,7 +337,7 @@ private void maybeForceBuilderInitialization() { .alwaysUseFieldBuilders) { } } - @java.lang.Override + @Override public Builder clear() { super.clear(); msb_ = 0L; @@ -347,79 +347,79 @@ public Builder clear() { return this; } - @java.lang.Override + @Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { return TestCmmn.internal_static_io_apicurio_registry_common_proto_UUID_descriptor; } - @java.lang.Override - public TestCmmn.UUID getDefaultInstanceForType() { - return TestCmmn.UUID.getDefaultInstance(); + @Override + public UUID getDefaultInstanceForType() { + return UUID.getDefaultInstance(); } - @java.lang.Override - public TestCmmn.UUID build() { - TestCmmn.UUID result = buildPartial(); + @Override + public UUID build() { + UUID result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } - @java.lang.Override - public TestCmmn.UUID buildPartial() { - TestCmmn.UUID result = new TestCmmn.UUID(this); + @Override + public UUID buildPartial() { + UUID result = new UUID(this); result.msb_ = msb_; result.lsb_ = lsb_; onBuilt(); return result; } - @java.lang.Override + @Override public Builder clone() { return super.clone(); } - @java.lang.Override + @Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { + Object value) { return super.setField(field, value); } - @java.lang.Override + @Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { return super.clearField(field); } - @java.lang.Override + @Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { return super.clearOneof(oneof); } - @java.lang.Override + @Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { + int index, Object value) { return super.setRepeatedField(field, index, value); } - @java.lang.Override + @Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { + Object value) { return super.addRepeatedField(field, value); } - @java.lang.Override + @Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof TestCmmn.UUID) { - return mergeFrom((TestCmmn.UUID)other); + if (other instanceof UUID) { + return mergeFrom((UUID)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(TestCmmn.UUID other) { - if (other == TestCmmn.UUID.getDefaultInstance()) return this; + public Builder mergeFrom(UUID other) { + if (other == UUID.getDefaultInstance()) return this; if (other.getMsb() != 0L) { setMsb(other.getMsb()); } @@ -431,21 +431,21 @@ public Builder mergeFrom(TestCmmn.UUID other) { return this; } - @java.lang.Override + @Override public final boolean isInitialized() { return true; } - @java.lang.Override + @Override public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - TestCmmn.UUID parsedMessage = null; + UUID parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (TestCmmn.UUID) e.getUnfinishedMessage(); + parsedMessage = (UUID) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -506,13 +506,13 @@ public Builder clearLsb() { onChanged(); return this; } - @java.lang.Override + @Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); } - @java.lang.Override + @Override public final Builder mergeUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.mergeUnknownFields(unknownFields); @@ -523,18 +523,18 @@ public final Builder mergeUnknownFields( } // @@protoc_insertion_point(class_scope:io.apicurio.registry.common.proto.UUID) - private static final TestCmmn.UUID DEFAULT_INSTANCE; + private static final UUID DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new TestCmmn.UUID(); + DEFAULT_INSTANCE = new UUID(); } - public static TestCmmn.UUID getDefaultInstance() { + public static UUID getDefaultInstance() { return DEFAULT_INSTANCE; } private static final com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override + @Override public UUID parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) @@ -547,13 +547,13 @@ public static com.google.protobuf.Parser parser() { return PARSER; } - @java.lang.Override + @Override public com.google.protobuf.Parser getParserForType() { return PARSER; } - @java.lang.Override - public TestCmmn.UUID getDefaultInstanceForType() { + @Override + public UUID getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -572,7 +572,7 @@ public TestCmmn.UUID getDefaultInstanceForType() { private static com.google.protobuf.Descriptors.FileDescriptor descriptor; static { - java.lang.String[] descriptorData = { + String[] descriptorData = { "\n\014common.proto\022!io.apicurio.registry.com" + "mon.proto\" \n\004UUID\022\013\n\003msb\030\001 \001(\006\022\013\n\003lsb\030\002 " + "\001(\006B)\n!io.apicurio.registry.common.proto" + @@ -587,7 +587,7 @@ public TestCmmn.UUID getDefaultInstanceForType() { internal_static_io_apicurio_registry_common_proto_UUID_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_io_apicurio_registry_common_proto_UUID_descriptor, - new java.lang.String[] { "Msb", "Lsb", }); + new String[] { "Msb", "Lsb", }); } // @@protoc_insertion_point(outer_class_scope) diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/converters/RegistryConverterIT.java b/integration-tests/src/test/java/io/apicurio/tests/converters/RegistryConverterIT.java similarity index 90% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/converters/RegistryConverterIT.java rename to integration-tests/src/test/java/io/apicurio/tests/converters/RegistryConverterIT.java index 3b0a15ea8f..5f4070d0a7 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/converters/RegistryConverterIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/converters/RegistryConverterIT.java @@ -16,28 +16,11 @@ package io.apicurio.tests.converters; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - -import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericData.Record; -import org.apache.kafka.connect.data.SchemaBuilder; -import org.apache.kafka.connect.data.Struct; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; - +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.AvroGenericRecordSchemaFactory; +import io.apicurio.tests.utils.Constants; import io.apicurio.registry.rest.client.RegistryClient; import io.apicurio.registry.serde.AbstractKafkaSerDe; import io.apicurio.registry.serde.SerdeConfig; @@ -54,16 +37,37 @@ import io.apicurio.registry.utils.converter.json.FormatStrategy; import io.apicurio.registry.utils.converter.json.PrettyFormatStrategy; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.serdes.apicurio.AvroGenericRecordSchemaFactory; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import org.apache.avro.Schema; +import org.apache.avro.generic.GenericData.Record; +import org.apache.kafka.connect.data.SchemaBuilder; +import org.apache.kafka.connect.data.Struct; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; /** - * @author Ales Justin + * @author Carles Arnal */ @Tag(Constants.SERDES) @Tag(Constants.ACCEPTANCE) -public class RegistryConverterIT extends ApicurioV2BaseIT { +@QuarkusIntegrationTest +public class RegistryConverterIT extends ApicurioRegistryBaseIT { + + @Override + public void cleanArtifacts() throws Exception { + //Don't clean up + } @Test public void testConfiguration() throws Exception { @@ -75,22 +79,22 @@ public void testConfiguration() throws Exception { createArtifact(groupId, topic + "-" + recordName, ArtifactType.AVRO, new ByteArrayInputStream(schema.toString().getBytes(StandardCharsets.UTF_8))); - GenericData.Record record = new GenericData.Record(schema); + Record record = new Record(schema); record.put("bar", "somebar"); Map config = new HashMap<>(); - config.put(SerdeConfig.REGISTRY_URL, TestUtils.getRegistryV2ApiUrl()); + config.put(SerdeConfig.REGISTRY_URL, getRegistryV2ApiUrl()); config.put(SerdeBasedConverter.REGISTRY_CONVERTER_SERIALIZER_PARAM, AvroKafkaSerializer.class.getName()); config.put(SerdeBasedConverter.REGISTRY_CONVERTER_DESERIALIZER_PARAM, AvroKafkaDeserializer.class.getName()); config.put(SerdeConfig.ARTIFACT_RESOLVER_STRATEGY, TopicRecordIdStrategy.class.getName()); config.put(AvroKafkaSerdeConfig.AVRO_DATUM_PROVIDER, DefaultAvroDatumProvider.class.getName()); - SerdeBasedConverter converter = new SerdeBasedConverter<>(); + SerdeBasedConverter converter = new SerdeBasedConverter<>(); byte[] bytes; try { converter.configure(config, true); bytes = converter.fromConnectData(topic, null, record); - record = (GenericData.Record) converter.toConnectData(topic, bytes).value(); + record = (Record) converter.toConnectData(topic, bytes).value(); Assertions.assertEquals("somebar", record.get("bar").toString()); } finally { converter.close(); @@ -103,7 +107,7 @@ public void testAvro() throws Exception { try (AvroConverter converter = new AvroConverter<>()) { Map config = new HashMap<>(); - config.put(SerdeConfig.REGISTRY_URL, TestUtils.getRegistryV2ApiUrl()); + config.put(SerdeConfig.REGISTRY_URL, getRegistryV2ApiUrl()); config.put(SerdeConfig.AUTO_REGISTER_ARTIFACT, "true"); converter.configure(config, false); diff --git a/integration-tests/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlLogCompactionIT.java b/integration-tests/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlLogCompactionIT.java new file mode 100644 index 0000000000..c055bd665c --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlLogCompactionIT.java @@ -0,0 +1,191 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.tests.dbupgrade; + +import io.apicurio.registry.rest.client.RegistryClientFactory; +import io.apicurio.registry.test.utils.KafkaTestContainerManager; +import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.utils.tests.SimpleDisplayName; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.Constants; +import io.apicurio.tests.utils.CustomTestsUtils; +import io.apicurio.tests.utils.RegistryWaitUtils; +import io.apicurio.tests.utils.TestSeparator; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.kafka.clients.CommonClientConfigs; +import org.apache.kafka.clients.admin.AdminClient; +import org.apache.kafka.clients.admin.NewTopic; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import static io.apicurio.tests.dbupgrade.UpgradeTestsDataInitializer.PREPARE_LOG_COMPACTION; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author Carles Arnal + */ +@DisplayNameGeneration(SimpleDisplayName.class) +@TestInstance(Lifecycle.PER_CLASS) +@Tag(Constants.DB_UPGRADE) +@Tag(Constants.KAFKA_SQL) +@QuarkusTestResource(value = KafkaTestContainerManager.class, restrictToAnnotatedClass = true) +@QuarkusTestResource(value = KafkaSqlLogCompactionIT.KafkaSqlLogCompactionTestInitializer.class, restrictToAnnotatedClass = true) +@QuarkusIntegrationTest +public class KafkaSqlLogCompactionIT extends ApicurioRegistryBaseIT implements TestSeparator, Constants { + + static final Logger logger = LoggerFactory.getLogger(KafkaSqlLogCompactionIT.class); + + @Override + public void cleanArtifacts() throws Exception { + //Don't clean artifacts for this test + } + + @Test + public void testLogCompaction() throws Exception { + //The check must be retried so the kafka storage has been bootstrapped + retry(() -> assertEquals(3, registryClient.listArtifactsInGroup(PREPARE_LOG_COMPACTION).getCount())); + + var searchResults = registryClient.listArtifactsInGroup(PREPARE_LOG_COMPACTION); + assertEquals(3, searchResults.getCount()); + + String test2content = ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v2.proto"); + String originalHash = DigestUtils.sha256Hex(test2content); + var artifact = CustomTestsUtils.createArtifact(registryClient, PREPARE_LOG_COMPACTION, ArtifactType.PROTOBUF, test2content); + + assertEquals(originalHash, artifact.contentHash); + + String byglobalidHash = DigestUtils.sha256Hex(registryClient.getContentByGlobalId(artifact.meta.getGlobalId())); + String bycontentidHash = DigestUtils.sha256Hex(registryClient.getContentById(artifact.meta.getContentId())); + + assertEquals(originalHash, byglobalidHash); + assertEquals(originalHash, bycontentidHash); + + //assert total num of artifacts + assertEquals(4, registryClient.listArtifactsInGroup(PREPARE_LOG_COMPACTION).getCount()); + } + + public static class KafkaSqlLogCompactionTestInitializer implements QuarkusTestResourceLifecycleManager { + GenericContainer genericContainer; + AdminClient adminClient; + + @Override + public int order() { + return 10000; + } + + @Override + public Map start() { + if (!Boolean.parseBoolean(System.getProperty("cluster.tests"))) { + + String bootstrapServers = System.getProperty("bootstrap.servers"); + + genericContainer = new GenericContainer("quay.io/apicurio/apicurio-registry-kafkasql:2.1.2.Final") + .withEnv(Map.of("KAFKA_BOOTSTRAP_SERVERS", bootstrapServers, "QUARKUS_HTTP_PORT", "8081")) + .withNetworkMode("host"); + + //create the topic with agressive log compaction + createTopic("kafkasql-journal", 1, bootstrapServers); + + genericContainer.start(); + genericContainer.waitingFor(Wait.forLogMessage(".*(KSQL Kafka Consumer Thread) KafkaSQL storage bootstrapped.*", 1)); + + var registryClient = RegistryClientFactory.create("http://localhost:8081"); + + try { + RegistryWaitUtils.retry(registryClient, registryClient1 -> CustomTestsUtils.createArtifact(registryClient, ArtifactType.AVRO, ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "avro/multi-field_v1.json"))); + + var artifactdata = CustomTestsUtils.createArtifact(registryClient, ArtifactType.JSON, ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "jsonSchema/person_v1.json")); + CustomTestsUtils.createArtifact(registryClient, ArtifactType.PROTOBUF, ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v1.proto")); + + assertEquals(3, registryClient.listArtifactsInGroup(PREPARE_LOG_COMPACTION).getCount()); + + //spend some time doing something + //this is just to give kafka some time to be 100% the topic is log compacted + logger.info("Giving kafka some time to do log compaction"); + for (int i = 0; i < 15; i++) { + registryClient.getArtifactMetaData(artifactdata.meta.getGroupId(), artifactdata.meta.getId()); + try { + Thread.sleep(900); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + logger.info("Finished giving kafka some time"); + } catch (Exception e) { + logger.warn("Error filling origin with artifacts information:", e); + } + } + + return Collections.emptyMap(); + } + + @Override + public void stop() { + if (genericContainer != null && genericContainer.isRunning()) { + genericContainer.stop(); + } + } + + public AdminClient adminClient(String bootstrapServers) { + if (adminClient == null) { + adminClient = AdminClient.create(connectionProperties(bootstrapServers)); + } + return adminClient; + } + + public void createTopic(String topic, int partitions, String bootstrapServers) { + var journal = new NewTopic(topic, partitions, (short) 1); + + /*journal.configs(Map.of( + "min.cleanable.dirty.ratio","0.000001", + "cleanup.policy","compact", + "segment.ms", "100", + "delete.retention.ms", "100" + ));*/ + + journal.configs(Map.of( + "cleanup.policy", "compact" + )); + + adminClient(bootstrapServers).createTopics(List.of(journal)); + } + + public Properties connectionProperties(String bootstrapServers) { + Properties properties = new Properties(); + properties.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + properties.put(CommonClientConfigs.CONNECTIONS_MAX_IDLE_MS_CONFIG, 10000); + properties.put(CommonClientConfigs.REQUEST_TIMEOUT_MS_CONFIG, 5000); + return properties; + } + } +} diff --git a/integration-tests/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlStorageUpgradeIT.java b/integration-tests/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlStorageUpgradeIT.java new file mode 100644 index 0000000000..d054360947 --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlStorageUpgradeIT.java @@ -0,0 +1,167 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.tests.dbupgrade; + +import io.apicurio.registry.rest.client.RegistryClientFactory; +import io.apicurio.registry.rest.v2.beans.ArtifactReference; +import io.apicurio.registry.test.utils.KafkaTestContainerManager; +import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.utils.IoUtil; +import io.apicurio.registry.utils.tests.SimpleDisplayName; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.Constants; +import io.apicurio.tests.utils.CustomTestsUtils; +import io.apicurio.tests.utils.TestSeparator; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static io.apicurio.tests.dbupgrade.UpgradeTestsDataInitializer.ARTIFACT_CONTENT; +import static io.apicurio.tests.dbupgrade.UpgradeTestsDataInitializer.PREPARE_PROTO_GROUP; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author Carles Arnal + */ +@DisplayNameGeneration(SimpleDisplayName.class) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Tag(Constants.DB_UPGRADE) +@Tag(Constants.KAFKA_SQL) +@QuarkusTestResource(value = KafkaTestContainerManager.class, restrictToAnnotatedClass = true) +@QuarkusTestResource(value = KafkaSqlStorageUpgradeIT.KafkaSqlStorageUpgradeInitializer.class, restrictToAnnotatedClass = true) +@QuarkusIntegrationTest +public class KafkaSqlStorageUpgradeIT extends ApicurioRegistryBaseIT implements TestSeparator, Constants { + + static final Logger logger = LoggerFactory.getLogger(KafkaSqlLogCompactionIT.class); + + protected static CustomTestsUtils.ArtifactData artifactWithReferences; + protected static List artifactReferences; + protected static CustomTestsUtils.ArtifactData protoData; + + @Override + public void cleanArtifacts() throws Exception { + //Don't clean artifacts for this test + } + + @Test + public void testStorageUpgradeProtobufUpgraderKafkaSql() throws Exception { + //The check must be retried so the kafka storage has been bootstrapped + retry(() -> assertEquals(3, registryClient.listArtifactsInGroup(PREPARE_PROTO_GROUP).getCount()), 1000L); + + var searchResults = registryClient.listArtifactsInGroup(PREPARE_PROTO_GROUP); + + var protobufs = searchResults.getArtifacts().stream() + .filter(ar -> ar.getType().equals(ArtifactType.PROTOBUF)) + .collect(Collectors.toList()); + + System.out.println("Protobuf artifacts are " + protobufs.size()); + assertEquals(1, protobufs.size()); + var protoMetadata = registryClient.getArtifactMetaData(protobufs.get(0).getGroupId(), protobufs.get(0).getId()); + var content = registryClient.getContentByGlobalId(protoMetadata.getGlobalId()); + + //search with canonicalize + var versionMetadata = registryClient.getArtifactVersionMetaDataByContent(protobufs.get(0).getGroupId(), protobufs.get(0).getId(), true, null, content); + assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); + + String test1content = ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v1.proto"); + + //search with canonicalize + versionMetadata = registryClient.getArtifactVersionMetaDataByContent(protobufs.get(0).getGroupId(), protobufs.get(0).getId(), true, null, IoUtil.toStream(test1content)); + assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); + + //search without canonicalize + versionMetadata = registryClient.getArtifactVersionMetaDataByContent(protobufs.get(0).getGroupId(), protobufs.get(0).getId(), false, null, IoUtil.toStream(test1content)); + assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); + + //create one more protobuf artifact and verify + String test2content = ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v2.proto"); + protoData = CustomTestsUtils.createArtifact(registryClient, PREPARE_PROTO_GROUP, ArtifactType.PROTOBUF, test2content); + versionMetadata = registryClient.getArtifactVersionMetaDataByContent(PREPARE_PROTO_GROUP, protoData.meta.getId(), true, null, IoUtil.toStream(test2content)); + assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); + + //assert total num of artifacts + assertEquals(4, registryClient.listArtifactsInGroup(PREPARE_PROTO_GROUP).getCount()); + } + + @Test + public void testStorageUpgradeReferencesContentHash() throws Exception { + //The check must be retried so the kafka storage has been bootstrapped + retry(() -> Assertions.assertTrue(registryClient.listArtifactsInGroup(artifactWithReferences.meta.getGroupId()).getCount() > 0), 1000L); + //Once the storage is filled with the proper information, if we try to create the same artifact with the same references, no new version will be created and the same ids are used. + CustomTestsUtils.ArtifactData upgradedArtifact = CustomTestsUtils.createArtifactWithReferences(artifactWithReferences.meta.getGroupId(), artifactWithReferences.meta.getId(), registryClient, ArtifactType.AVRO, ARTIFACT_CONTENT, artifactReferences); + assertEquals(artifactWithReferences.meta.getGlobalId(), upgradedArtifact.meta.getGlobalId()); + assertEquals(artifactWithReferences.meta.getContentId(), upgradedArtifact.meta.getContentId()); + } + + public static class KafkaSqlStorageUpgradeInitializer implements QuarkusTestResourceLifecycleManager { + private GenericContainer genericContainer; + + @Override + public Map start() { + if (!Boolean.parseBoolean(System.getProperty("cluster.tests"))) { + + String bootstrapServers = System.getProperty("bootstrap.servers"); + startOldRegistryVersion("quay.io/apicurio/apicurio-registry-kafkasql:2.1.2.Final", bootstrapServers); + + try { + var registryClient = RegistryClientFactory.create("http://localhost:8081/"); + + UpgradeTestsDataInitializer.prepareProtobufHashUpgradeTest(registryClient); + UpgradeTestsDataInitializer.prepareReferencesUpgradeTest(registryClient); + } catch (Exception e) { + logger.warn("Error filling old registry with information: ", e); + } + } + return Collections.emptyMap(); + } + + @Override + public int order() { + return 10000; + } + + @Override + public void stop() { + if (genericContainer != null && genericContainer.isRunning()) { + genericContainer.stop(); + } + } + + private void startOldRegistryVersion(String registryImage, String bootstrapServers) { + genericContainer = new GenericContainer<>(registryImage) + .withEnv(Map.of("KAFKA_BOOTSTRAP_SERVERS", bootstrapServers, "QUARKUS_HTTP_PORT", "8081")) + .withNetworkMode("host"); + + genericContainer.start(); + genericContainer.waitingFor(Wait.forLogMessage(".*(KSQL Kafka Consumer Thread) KafkaSQL storage bootstrapped.*", 1)); + } + } +} \ No newline at end of file diff --git a/integration-tests/src/test/java/io/apicurio/tests/dbupgrade/SqlStorageUpgradeIT.java b/integration-tests/src/test/java/io/apicurio/tests/dbupgrade/SqlStorageUpgradeIT.java new file mode 100644 index 0000000000..5a4ea8636e --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/dbupgrade/SqlStorageUpgradeIT.java @@ -0,0 +1,273 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.tests.dbupgrade; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.apicurio.registry.rest.client.RegistryClient; +import io.apicurio.registry.rest.v2.beans.ArtifactReference; +import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.utils.IoUtil; +import io.apicurio.registry.utils.tests.MultitenancyNoAuthTestProfile; +import io.apicurio.registry.utils.tests.PostgreSqlEmbeddedTestResource; +import io.apicurio.registry.utils.tests.SimpleDisplayName; +import io.apicurio.registry.utils.tests.TestUtils; +import io.apicurio.tenantmanager.api.datamodel.SortBy; +import io.apicurio.tenantmanager.api.datamodel.SortOrder; +import io.apicurio.tenantmanager.api.datamodel.TenantStatusValue; +import io.apicurio.tenantmanager.client.TenantManagerClient; +import io.apicurio.tenantmanager.client.TenantManagerClientImpl; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.multitenancy.MultitenancySupport; +import io.apicurio.tests.multitenancy.TenantUser; +import io.apicurio.tests.multitenancy.TenantUserClient; +import io.apicurio.tests.utils.Constants; +import io.apicurio.tests.utils.CustomTestsUtils; +import io.apicurio.tests.utils.TestSeparator; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import io.quarkus.test.junit.TestProfile; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + +import static io.apicurio.tests.dbupgrade.UpgradeTestsDataInitializer.PREPARE_PROTO_GROUP; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author Carles Arnal + */ +@DisplayNameGeneration(SimpleDisplayName.class) +@TestInstance(Lifecycle.PER_CLASS) +@Tag(Constants.DB_UPGRADE) +@Tag(Constants.SQL) +@TestProfile(MultitenancyNoAuthTestProfile.class) +@QuarkusIntegrationTest +@QuarkusTestResource(value = PostgreSqlEmbeddedTestResource.class, restrictToAnnotatedClass = true) +@QuarkusTestResource(value = SqlStorageUpgradeIT.SqlStorageUpgradeTestInitializer.class, restrictToAnnotatedClass = true) +public class SqlStorageUpgradeIT extends ApicurioRegistryBaseIT implements TestSeparator, Constants { + + private static final Logger logger = LoggerFactory.getLogger(SqlStorageUpgradeIT.class); + + protected static List data; + + private static final String ARTIFACT_CONTENT = "{\"name\":\"redhat\"}"; + private static final String REFERENCE_CONTENT = "{\"name\":\"ibm\"}"; + + private static final ObjectMapper mapper = new ObjectMapper(); + + protected static CustomTestsUtils.ArtifactData artifactWithReferences; + protected static List artifactReferences; + protected static CustomTestsUtils.ArtifactData protoData; + + public static RegistryClient upgradeTenantClient; + + @Override + public void cleanArtifacts() throws Exception { + //Don't clean up + } + + @Test + public void testStorageUpgrade() throws Exception { + //First verify the data created in the old registry version. + UpgradeTestsDataInitializer.verifyData(data); + //Add more data to the new registry instance. + UpgradeTestsDataInitializer.createMoreArtifacts(data); + //Verify the new data. + UpgradeTestsDataInitializer.verifyData(data); + } + + @Test + public void testStorageUpgradeReferencesContentHash() throws Exception { + testStorageUpgradeReferencesContentHashUpgrader("referencesContentHash"); + } + + public void testStorageUpgradeReferencesContentHashUpgrader(String testName) throws Exception { + //Once the storage is filled with the proper information, if we try to create the same artifact with the same references, no new version will be created and the same ids are used. + CustomTestsUtils.ArtifactData upgradedArtifact = CustomTestsUtils.createArtifactWithReferences(artifactWithReferences.meta.getGroupId(), artifactWithReferences.meta.getId(), upgradeTenantClient, ArtifactType.AVRO, ARTIFACT_CONTENT, artifactReferences); + assertEquals(artifactWithReferences.meta.getGlobalId(), upgradedArtifact.meta.getGlobalId()); + assertEquals(artifactWithReferences.meta.getContentId(), upgradedArtifact.meta.getContentId()); + } + + @Test + public void testStorageUpgradeProtobufUpgraderKafkaSql() throws Exception { + testStorageUpgradeProtobufUpgrader("protobufCanonicalHashKafkaSql"); + } + + public void testStorageUpgradeProtobufUpgrader(String testName) throws Exception { + //The check must be retried so the kafka storage has been bootstrapped + retry(() -> assertEquals(3, upgradeTenantClient.listArtifactsInGroup(PREPARE_PROTO_GROUP).getCount())); + + var searchResults = upgradeTenantClient.listArtifactsInGroup(PREPARE_PROTO_GROUP); + + var protobufs = searchResults.getArtifacts().stream() + .filter(ar -> ar.getType().equals(ArtifactType.PROTOBUF)) + .collect(Collectors.toList()); + + System.out.println("Protobuf artifacts are " + protobufs.size()); + assertEquals(1, protobufs.size()); + var protoMetadata = upgradeTenantClient.getArtifactMetaData(protobufs.get(0).getGroupId(), protobufs.get(0).getId()); + var content = upgradeTenantClient.getContentByGlobalId(protoMetadata.getGlobalId()); + + //search with canonicalize + var versionMetadata = upgradeTenantClient.getArtifactVersionMetaDataByContent(protobufs.get(0).getGroupId(), protobufs.get(0).getId(), true, null, content); + assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); + + String test1content = ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v1.proto"); + + //search with canonicalize + versionMetadata = upgradeTenantClient.getArtifactVersionMetaDataByContent(protobufs.get(0).getGroupId(), protobufs.get(0).getId(), true, null, IoUtil.toStream(test1content)); + assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); + + //search without canonicalize + versionMetadata = upgradeTenantClient.getArtifactVersionMetaDataByContent(protobufs.get(0).getGroupId(), protobufs.get(0).getId(), false, null, IoUtil.toStream(test1content)); + assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); + + //create one more protobuf artifact and verify + String test2content = ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v2.proto"); + protoData = CustomTestsUtils.createArtifact(upgradeTenantClient, PREPARE_PROTO_GROUP, ArtifactType.PROTOBUF, test2content); + versionMetadata = upgradeTenantClient.getArtifactVersionMetaDataByContent(PREPARE_PROTO_GROUP, protoData.meta.getId(), true, null, IoUtil.toStream(test2content)); + assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); + + //assert total num of artifacts + assertEquals(4, upgradeTenantClient.listArtifactsInGroup(PREPARE_PROTO_GROUP).getCount()); + } + + public static class SqlStorageUpgradeTestInitializer implements QuarkusTestResourceLifecycleManager { + GenericContainer registryContainer; + GenericContainer tenantManagerContainer; + TenantManagerClient tenantManager; + + @Override + public int order() { + return 10000; + } + + @Override + public Map start() { + if (!Boolean.parseBoolean(System.getProperty("cluster.tests"))) { + + String jdbcUrl = System.getProperty("quarkus.datasource.jdbc.url"); + String userName = System.getProperty("quarkus.datasource.username"); + String password = System.getProperty("quarkus.datasource.password"); + + String tenantManagerUrl = startTenantManagerApplication("quay.io/apicurio/apicurio-tenant-manager-api:latest", jdbcUrl, userName, password); + String registryBaseUrl = startOldRegistryVersion("quay.io/apicurio/apicurio-registry-sql:2.1.0.Final", jdbcUrl, userName, password, tenantManagerUrl); + + try { + + //Warm up until the tenant manager is ready. + TestUtils.retry(() -> { + getTenantManagerClient(tenantManagerUrl).listTenants(TenantStatusValue.READY, 0, 1, SortOrder.asc, SortBy.tenantId); + }); + + UpgradeTestsDataInitializer.prepareTestStorageUpgrade(SqlStorageUpgradeIT.class.getSimpleName(), tenantManagerUrl, "http://localhost:8081"); + + //Wait until all the data is available for the upgrade test. + TestUtils.retry(() -> Assertions.assertEquals(10, getTenantManagerClient(tenantManagerUrl).listTenants(TenantStatusValue.READY, 0, 51, SortOrder.asc, SortBy.tenantId).getCount())); + + MultitenancySupport mt = new MultitenancySupport(tenantManagerUrl, registryBaseUrl); + TenantUser tenantUser = new TenantUser(UUID.randomUUID().toString(), UUID.randomUUID().toString(), "storageUpgrade", UUID.randomUUID().toString()); + final TenantUserClient tenantUpgradeClient = mt.createTenant(tenantUser); + + //Prepare the data for the content and canonical hash upgraders using an isolated tenant so we don't have data conflicts. + UpgradeTestsDataInitializer.prepareProtobufHashUpgradeTest(tenantUpgradeClient.client); + UpgradeTestsDataInitializer.prepareReferencesUpgradeTest(tenantUpgradeClient.client); + + upgradeTenantClient = tenantUpgradeClient.client; + + //Once the data is set, stop the old registry before running the tests. + if (registryContainer != null && registryContainer.isRunning()) { + registryContainer.stop(); + } + + } catch (Exception e) { + logger.warn("Error filling old registry with information: ", e); + } + } + + return Collections.emptyMap(); + } + + private String startTenantManagerApplication(String tenantManagerImageName, String jdbcUrl, String username, String password) { + tenantManagerContainer = new GenericContainer<>(tenantManagerImageName) + .withEnv(Map.of("DATASOURCE_URL", jdbcUrl, + "REGISTRY_ROUTE_URL", "", + "DATASOURCE_USERNAME", username, + "DATASOURCE_PASSWORD", password, + "QUARKUS_HTTP_PORT", "8585")) + .withNetworkMode("host"); + + tenantManagerContainer.start(); + tenantManagerContainer.waitingFor(Wait.forLogMessage(".*Installed features:*", 1)); + + return "http://localhost:8585"; + } + + @Override + public void stop() { + //Once the data is set, stop the old registry before running the tests. + if (registryContainer != null && registryContainer.isRunning()) { + registryContainer.stop(); + } + + if (tenantManagerContainer != null && tenantManagerContainer.isRunning()) { + tenantManagerContainer.stop(); + } + } + + private String startOldRegistryVersion(String imageName, String jdbcUrl, String username, String password, String tenantManagerUrl) { + registryContainer = new GenericContainer<>(imageName) + .withEnv(Map.of( + "REGISTRY_ENABLE_MULTITENANCY", "true", + "TENANT_MANAGER_AUTH_ENABLED", "false", + "TENANT_MANAGER_URL", tenantManagerUrl, + "REGISTRY_DATASOURCE_URL", jdbcUrl, + "REGISTRY_DATASOURCE_USERNAME", username, + "REGISTRY_DATASOURCE_PASSWORD", password, + "QUARKUS_HTTP_PORT", "8081")) + .dependsOn(tenantManagerContainer) + .withNetworkMode("host"); + + registryContainer.start(); + //TODO change log message + registryContainer.waitingFor(Wait.forLogMessage(".*Installed features:*", 1)); + + return "http://localhost:8081"; + } + + public synchronized TenantManagerClient getTenantManagerClient(String tenantManagerUrl) { + if (tenantManager == null) { + tenantManager = new TenantManagerClientImpl(tenantManagerUrl, Collections.emptyMap(), null); + } + return tenantManager; + } + } +} diff --git a/integration-tests/src/test/java/io/apicurio/tests/dbupgrade/UpgradeTestsDataInitializer.java b/integration-tests/src/test/java/io/apicurio/tests/dbupgrade/UpgradeTestsDataInitializer.java new file mode 100644 index 0000000000..8dc1c03003 --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/dbupgrade/UpgradeTestsDataInitializer.java @@ -0,0 +1,243 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.tests.dbupgrade; + +import io.apicurio.registry.rest.client.RegistryClient; +import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; +import io.apicurio.registry.rest.v2.beans.ArtifactReference; +import io.apicurio.registry.rest.v2.beans.Rule; +import io.apicurio.registry.rest.v2.beans.VersionMetaData; +import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.types.RuleType; +import io.apicurio.registry.utils.IoUtil; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.multitenancy.MultitenancySupport; +import io.apicurio.tests.multitenancy.TenantUserClient; +import io.apicurio.tests.utils.CustomTestsUtils; +import io.apicurio.tests.utils.RegistryWaitUtils; +import org.apache.commons.codec.digest.DigestUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static io.apicurio.tests.ApicurioRegistryBaseIT.resourceToString; +import static io.apicurio.tests.utils.CustomTestsUtils.createArtifact; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class UpgradeTestsDataInitializer { + + protected static final String REFERENCE_CONTENT = "{\"name\":\"ibm\"}"; + protected static final String ARTIFACT_CONTENT = "{\"name\":\"redhat\"}"; + + public static final String PREPARE_LOG_COMPACTION = "prepareLogCompactionGroup"; + public static final String PREPARE_PROTO_GROUP = "prepareProtobufHashUpgradeTest"; + public static final String PREPARE_REFERENCES_GROUP = "prepareReferencesUpgradeTest"; + + private static final Logger logger = LoggerFactory.getLogger(UpgradeTestsDataInitializer.class); + + public static void prepareProtobufHashUpgradeTest(RegistryClient registryClient) throws Exception { + logger.info("Preparing ProtobufHashUpgradeTest test data..."); + + RegistryWaitUtils.retry(registryClient, registryClient1 -> CustomTestsUtils.createArtifact(registryClient, PREPARE_PROTO_GROUP, ArtifactType.AVRO, resourceToString("artifactTypes/" + "avro/multi-field_v1.json"))); + CustomTestsUtils.createArtifact(registryClient, PREPARE_PROTO_GROUP, ArtifactType.JSON, resourceToString("artifactTypes/" + "jsonSchema/person_v1.json")); + + String test1content = resourceToString("artifactTypes/" + "protobuf/tutorial_v1.proto"); + var protoData = CustomTestsUtils.createArtifact(registryClient, PREPARE_PROTO_GROUP, ArtifactType.PROTOBUF, test1content); + + //verify search with canonicalize returns the expected artifact metadata + var versionMetadata = registryClient.getArtifactVersionMetaDataByContent(PREPARE_PROTO_GROUP, protoData.meta.getId(), true, null, IoUtil.toStream(test1content)); + assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); + + assertEquals(3, registryClient.listArtifactsInGroup(PREPARE_PROTO_GROUP).getCount()); + + //Once prepared, set the global variable, so we can compare during the test execution + KafkaSqlStorageUpgradeIT.protoData = protoData; + SqlStorageUpgradeIT.protoData = protoData; + + logger.info("Finished preparing ProtobufHashUpgradeTest test data."); + } + + public static void prepareReferencesUpgradeTest(RegistryClient registryClient) throws Exception { + logger.info("Preparing ReferencesUpgradeTest test data..."); + + final CustomTestsUtils.ArtifactData artifact = CustomTestsUtils.createArtifact(registryClient, PREPARE_REFERENCES_GROUP, ArtifactType.JSON, REFERENCE_CONTENT); + + //Create a second artifact referencing the first one, the hash will be the same using version 2.4.1.Final. + var artifactReference = new ArtifactReference(); + + artifactReference.setName("testReference"); + artifactReference.setArtifactId(artifact.meta.getId()); + artifactReference.setGroupId(artifact.meta.getGroupId()); + artifactReference.setVersion(artifact.meta.getVersion()); + + var artifactReferences = List.of(artifactReference); + + String artifactId = UUID.randomUUID().toString(); + + final CustomTestsUtils.ArtifactData artifactWithReferences = CustomTestsUtils.createArtifactWithReferences(PREPARE_REFERENCES_GROUP, artifactId, registryClient, ArtifactType.AVRO, ARTIFACT_CONTENT, artifactReferences); + + String calculatedHash = DigestUtils.sha256Hex(ARTIFACT_CONTENT); + + //Assertions + //The artifact hash is calculated without using references + assertEquals(calculatedHash, artifactWithReferences.contentHash); + + //Once prepared, set the global variables, so we can compare during the test execution. + KafkaSqlStorageUpgradeIT.artifactReferences = artifactReferences; + KafkaSqlStorageUpgradeIT.artifactWithReferences = artifactWithReferences; + SqlStorageUpgradeIT.artifactReferences = artifactReferences; + SqlStorageUpgradeIT.artifactWithReferences = artifactWithReferences; + + logger.info("Finished preparing ReferencesUpgradeTest test data."); + } + + public static void prepareTestStorageUpgrade(String testName, String tenantManagerUrl, String registryBaseUrl) throws Exception { + logger.info("Preparing TestStorageUpgrade test data..."); + + MultitenancySupport mt = new MultitenancySupport(tenantManagerUrl, registryBaseUrl); + + List data = loadData(mt, testName); + + verifyData(data); + + SqlStorageUpgradeIT.data = data; + + logger.info("Finished preparing TestStorageUpgrade test data."); + } + + public static void prepareLogCompactionTests(RegistryClient registryClient) throws Exception { + try { + + logger.info("Preparing LogCompactionTests test data..."); + + RegistryWaitUtils.retry(registryClient, registryClient1 -> CustomTestsUtils.createArtifact(registryClient, PREPARE_LOG_COMPACTION, ArtifactType.AVRO, ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "avro/multi-field_v1.json"))); + + var artifactdata = CustomTestsUtils.createArtifact(registryClient, PREPARE_LOG_COMPACTION, ArtifactType.JSON, ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "jsonSchema/person_v1.json")); + CustomTestsUtils.createArtifact(registryClient, PREPARE_LOG_COMPACTION, ArtifactType.PROTOBUF, ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v1.proto")); + assertEquals(3, registryClient.listArtifactsInGroup(PREPARE_LOG_COMPACTION).getCount()); + + //spend some time doing something + //this is just to give kafka some time to be 100% the topic is log compacted + logger.info("Giving kafka some time to do log compaction"); + for (int i = 0; i < 15; i++) { + registryClient.getArtifactMetaData(artifactdata.meta.getGroupId(), artifactdata.meta.getId()); + try { + Thread.sleep(900); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + logger.info("Finished giving kafka some time"); + } catch (Exception e) { + logger.warn("Error filling origin with artifacts information:", e); + } + + logger.info("Finished preparing LogCompactionTests test data."); + } + + private static List loadData(MultitenancySupport mt, String testName) throws Exception { + + List tenants = new ArrayList<>(); + + for (int i = 0; i < 10; i++) { + + TenantData tenant = new TenantData(); + TenantUserClient user = mt.createTenant(); + tenant.tenant = user; + tenants.add(tenant); + + logger.info("Tenant {} created...", tenant.tenant.user.tenantId); + + RegistryClient client = user.client; + + Rule comp = new Rule(); + comp.setType(RuleType.COMPATIBILITY); + comp.setConfig("BACKWARD"); + client.createGlobalRule(comp); + Rule val = new Rule(); + val.setType(RuleType.VALIDITY); + val.setConfig("SYNTAX_ONLY"); + client.createGlobalRule(val); + + tenant.artifacts.add(CustomTestsUtils.createArtifact(client, ArtifactType.AVRO, resourceToString("artifactTypes/" + "avro/multi-field_v1.json"))); + tenant.artifacts.add(CustomTestsUtils.createArtifact(client, ArtifactType.JSON, resourceToString("artifactTypes/" + "jsonSchema/person_v1.json"))); + tenant.artifacts.add(CustomTestsUtils.createArtifact(client, ArtifactType.ASYNCAPI, resourceToString("artifactTypes/" + "asyncapi/2.0-streetlights_v1.json"))); + + logger.info("Tenant {} filled with test data...", tenant.tenant.user.tenantId); + } + return tenants; + } + + public static void verifyData(List tenants) { + + for (TenantData tenant : tenants) { + + logger.info("Verifying tenant {} data...", tenant.tenant.user.tenantId); + + var client = tenant.tenant.client; + + var grules = client.listGlobalRules(); + assertEquals(2, grules.size()); + + for (CustomTestsUtils.ArtifactData data : tenant.artifacts) { + ArtifactMetaData meta = data.meta; + + String content = IoUtil.toString(client.getArtifactVersion(meta.getGroupId(), meta.getId(), meta.getVersion())); + String contentHash = DigestUtils.sha256Hex(IoUtil.toBytes(content)); + + assertEquals(data.contentHash, contentHash); + + String contentgid = IoUtil.toString(client.getContentByGlobalId(meta.getGlobalId())); + String contentgidHash = DigestUtils.sha256Hex(IoUtil.toBytes(contentgid)); + + assertEquals(data.contentHash, contentgidHash); + + String contentcid = IoUtil.toString(client.getContentById(meta.getContentId())); + String contentcidHash = DigestUtils.sha256Hex(IoUtil.toBytes(contentcid)); + + assertEquals(data.contentHash, contentcidHash); + + VersionMetaData vmeta = client.getArtifactVersionMetaData(meta.getGroupId(), meta.getId(), meta.getVersion()); + assertEquals(meta.getContentId(), vmeta.getContentId()); + + logger.info("Tenant {} data verified...", tenant.tenant.user.tenantId); + } + } + } + + public static void createMoreArtifacts(List tenants) throws Exception { + for (TenantData tenant : tenants) { + var client = tenant.tenant.client; + + tenant.artifacts.add(createArtifact(client, ArtifactType.AVRO, ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "avro/multi-field_v1.json"))); + tenant.artifacts.add(createArtifact(client, ArtifactType.KCONNECT, ApicurioRegistryBaseIT.resourceToString("artifactTypes/" + "kafkaConnect/simple_v1.json"))); + } + } + + public static class TenantData { + TenantUserClient tenant; + List artifacts; + + public TenantData() { + artifacts = new ArrayList<>(); + } + } +} diff --git a/integration-tests/src/test/java/io/apicurio/tests/migration/DataMigrationIT.java b/integration-tests/src/test/java/io/apicurio/tests/migration/DataMigrationIT.java new file mode 100644 index 0000000000..320eeb8c83 --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/migration/DataMigrationIT.java @@ -0,0 +1,98 @@ +package io.apicurio.tests.migration; + +import io.apicurio.registry.rest.client.RegistryClient; +import io.apicurio.registry.rest.client.RegistryClientFactory; +import io.apicurio.registry.rest.v2.beans.ArtifactReference; +import io.apicurio.registry.types.RuleType; +import io.apicurio.registry.utils.tests.TestUtils; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.AbstractTestDataInitializer; +import io.apicurio.tests.utils.Constants; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static io.apicurio.tests.migration.MigrationTestsDataInitializer.matchesReferences; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author Carles Arnal + */ +@QuarkusIntegrationTest +@QuarkusTestResource(value = DataMigrationIT.MigrateTestInitializer.class, restrictToAnnotatedClass = true) +@Tag(Constants.MIGRATION) +public class DataMigrationIT extends ApicurioRegistryBaseIT { + + private static final Logger log = LoggerFactory.getLogger(DataMigrationIT.class); + + public static InputStream migrateDataToImport; + public static HashMap> migrateReferencesMap = new HashMap<>(); + public static List migrateGlobalIds = new ArrayList<>(); + public static Map doNotPreserveIdsImportArtifacts = new HashMap<>(); + + /** + * The data required for this test is initialized by MigrationTestsDataInitializer.initializeMigrateTest(RegistryClient) + * + * @throws Exception + */ + @Test + public void migrate() throws Exception { + RegistryClient dest = RegistryClientFactory.create(ApicurioRegistryBaseIT.getRegistryV2ApiUrl()); + dest.importData(migrateDataToImport); + + retry(() -> { + for (long gid : migrateGlobalIds) { + dest.getContentByGlobalId(gid); + if (migrateReferencesMap.containsKey(gid)) { + List srcReferences = migrateReferencesMap.get(gid); + List destReferences = dest.getArtifactReferencesByGlobalId(gid); + assertTrue(matchesReferences(srcReferences, destReferences)); + } + } + assertEquals("SYNTAX_ONLY", dest.getArtifactRuleConfig("migrateTest", "avro-0", RuleType.VALIDITY).getConfig()); + assertEquals("BACKWARD", dest.getGlobalRuleConfig(RuleType.COMPATIBILITY).getConfig()); + }); + } + + @AfterEach + public void tearDownRegistries() throws IOException { + } + + public static class MigrateTestInitializer extends AbstractTestDataInitializer { + + @Override + public Map start() { + + String registryBaseUrl = startRegistryApplication("quay.io/apicurio/apicurio-registry-mem:latest-release"); + RegistryClient source = RegistryClientFactory.create(registryBaseUrl); + + try { + + //Warm up until the source registry is ready. + TestUtils.retry(() -> { + source.listArtifactsInGroup(null); + }); + + MigrationTestsDataInitializer.initializeMigrateTest(source); + + } catch (Exception ex) { + log.error("Error filling origin registry with data:", ex); + } + + return Collections.emptyMap(); + } + } +} \ No newline at end of file diff --git a/integration-tests/src/test/java/io/apicurio/tests/migration/DoNotPreserveIdsImportIT.java b/integration-tests/src/test/java/io/apicurio/tests/migration/DoNotPreserveIdsImportIT.java new file mode 100644 index 0000000000..3bc278c119 --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/migration/DoNotPreserveIdsImportIT.java @@ -0,0 +1,124 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.tests.migration; + +import io.apicurio.registry.rest.client.RegistryClient; +import io.apicurio.registry.rest.client.RegistryClientFactory; +import io.apicurio.registry.utils.IoUtil; +import io.apicurio.registry.utils.tests.TestUtils; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.serdes.apicurio.AvroGenericRecordSchemaFactory; +import io.apicurio.tests.serdes.apicurio.JsonSchemaMsgFactory; +import io.apicurio.tests.utils.AbstractTestDataInitializer; +import io.apicurio.tests.utils.Constants; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.InputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * @author Carles Arnal + */ +@QuarkusIntegrationTest +@QuarkusTestResource(value = DoNotPreserveIdsImportIT.DoNotPreserveIdsInitializer.class, restrictToAnnotatedClass = true) +@Tag(Constants.MIGRATION) +public class DoNotPreserveIdsImportIT extends ApicurioRegistryBaseIT { + + private static final Logger log = LoggerFactory.getLogger(DataMigrationIT.class); + public static InputStream doNotPreserveIdsImportDataToImport; + public static JsonSchemaMsgFactory jsonSchema; + public static Map doNotPreserveIdsImportArtifacts = new HashMap<>(); + + @Override + public void cleanArtifacts() throws Exception { + //Don't clean up + } + + @Test + public void testDoNotPreserveIdsImport() throws Exception { + RegistryClient dest = RegistryClientFactory.create(ApicurioRegistryBaseIT.getRegistryV2ApiUrl()); + + // Fill the destination registry with data (Avro content is inserted first to ensure that the content IDs are different) + for (int idx = 0; idx < 15; idx++) { + AvroGenericRecordSchemaFactory avroSchema = new AvroGenericRecordSchemaFactory(List.of("a" + idx)); + String artifactId = "avro-" + idx + "-" + UUID.randomUUID().toString(); // Artifact ids need to be different we do not support identical artifact ids + String content = IoUtil.toString(avroSchema.generateSchemaStream()); + var amd = dest.createArtifact("testDoNotPreserveIdsImport", artifactId, IoUtil.toStream(content)); + retry(() -> dest.getContentByGlobalId(amd.getGlobalId())); + doNotPreserveIdsImportArtifacts.put("testDoNotPreserveIdsImport:" + artifactId, content); + } + + for (int idx = 0; idx < 50; idx++) { + String artifactId = idx + "-" + UUID.randomUUID().toString(); // Artifact ids need to be different we do not support identical artifact ids + String content = IoUtil.toString(jsonSchema.getSchemaStream()); + var amd = dest.createArtifact("testDoNotPreserveIdsImport", artifactId, IoUtil.toStream(content)); + retry(() -> dest.getContentByGlobalId(amd.getGlobalId())); + doNotPreserveIdsImportArtifacts.put("testDoNotPreserveIdsImport:" + artifactId, content); + } + + // Import the data + dest.importData(doNotPreserveIdsImportDataToImport, false, false); + + // Check that the import was successful + retry(() -> { + for (var entry : doNotPreserveIdsImportArtifacts.entrySet()) { + String groupId = entry.getKey().split(":")[0]; + String artifactId = entry.getKey().split(":")[1]; + String content = entry.getValue(); + var registryContent = dest.getLatestArtifact(groupId, artifactId); + assertNotNull(registryContent); + assertEquals(content, IoUtil.toString(registryContent)); + } + }); + } + + public static class DoNotPreserveIdsInitializer extends AbstractTestDataInitializer { + + @Override + public Map start() { + + String registryBaseUrl = startRegistryApplication("quay.io/apicurio/apicurio-registry-mem:latest-release"); + RegistryClient source = RegistryClientFactory.create(registryBaseUrl); + + try { + //Warm up until the source registry is ready. + TestUtils.retry(() -> { + source.listArtifactsInGroup(null); + }); + + MigrationTestsDataInitializer.initializeDoNotPreserveIdsImport(source); + + } catch (Exception ex) { + log.error("Error filling origin registry with data:", ex); + } + + return Collections.emptyMap(); + } + } +} diff --git a/integration-tests/src/test/java/io/apicurio/tests/migration/GenerateCanonicalHashImportIT.java b/integration-tests/src/test/java/io/apicurio/tests/migration/GenerateCanonicalHashImportIT.java new file mode 100644 index 0000000000..b1b698ae12 --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/migration/GenerateCanonicalHashImportIT.java @@ -0,0 +1,150 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.tests.migration; + +import io.apicurio.registry.rest.client.RegistryClient; +import io.apicurio.registry.rest.client.RegistryClientFactory; +import io.apicurio.registry.types.ArtifactState; +import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.utils.IoUtil; +import io.apicurio.registry.utils.impexp.ArtifactVersionEntity; +import io.apicurio.registry.utils.impexp.ContentEntity; +import io.apicurio.registry.utils.impexp.EntityWriter; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.serdes.apicurio.JsonSchemaMsgFactory; +import io.apicurio.tests.utils.Constants; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import org.apache.commons.codec.digest.DigestUtils; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.zip.ZipOutputStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@QuarkusIntegrationTest +@Tag(Constants.MIGRATION) +public class GenerateCanonicalHashImportIT extends ApicurioRegistryBaseIT { + + @Test + public void testGeneratingCanonicalHashOnImport() throws Exception { + RegistryClient dest = RegistryClientFactory.create(ApicurioRegistryBaseIT.getRegistryV2ApiUrl()); + + Map artifacts = new HashMap<>(); + + JsonSchemaMsgFactory jsonSchema = new JsonSchemaMsgFactory(); + for (int i = 0; i < 20; i++) { + String artifactId = i + "-" + UUID.randomUUID(); + String content = IoUtil.toString(jsonSchema.getSchemaStream()); + artifacts.put(artifactId, content); + } + dest.importData(generateExportedZip(artifacts), false, false); + + retry(() -> { + for (var entry : artifacts.entrySet()) { + String groupId = "default"; + String artifactId = entry.getKey(); + String content = entry.getValue(); + + /* + TODO: Check if the canonical hash is generated correctly. + The only way is to generate canonical hash and then search artifact by it. But that needs apicurio-registry-app module as dependency. + */ + + var registryContent = dest.getLatestArtifact(groupId, artifactId); + assertNotNull(registryContent); + assertEquals(content, IoUtil.toString(registryContent)); + } + }); + + } + + public InputStream generateExportedZip(Map artifacts) { + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + ZipOutputStream zip = new ZipOutputStream(outputStream, StandardCharsets.UTF_8); + EntityWriter writer = new EntityWriter(zip); + + Map contentIndex = new HashMap<>(); + + AtomicInteger globalIdSeq = new AtomicInteger(1); + AtomicInteger contentIdSeq = new AtomicInteger(1); + + for (var entry : artifacts.entrySet()) { + String artifactId = entry.getKey(); + String content = entry.getValue(); + byte[] contentBytes = IoUtil.toBytes(content); + String contentHash = DigestUtils.sha256Hex(contentBytes); + + String artifactType = ArtifactType.JSON; + + Long contentId = contentIndex.computeIfAbsent(contentHash, k -> { + ContentEntity contentEntity = new ContentEntity(); + contentEntity.contentId = contentIdSeq.getAndIncrement(); + contentEntity.contentHash = contentHash; + contentEntity.canonicalHash = null; + contentEntity.contentBytes = contentBytes; + contentEntity.artifactType = artifactType; + + try { + writer.writeEntity(contentEntity); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return contentEntity.contentId; + }); + + ArtifactVersionEntity versionEntity = new ArtifactVersionEntity(); + versionEntity.artifactId = artifactId; + versionEntity.artifactType = artifactType; + versionEntity.contentId = contentId; + versionEntity.createdBy = "integration-tests"; + versionEntity.createdOn = System.currentTimeMillis(); + versionEntity.description = null; + versionEntity.globalId = globalIdSeq.getAndIncrement(); + versionEntity.groupId = null; + versionEntity.isLatest = true; + versionEntity.labels = null; + versionEntity.name = null; + versionEntity.properties = null; + versionEntity.state = ArtifactState.ENABLED; + versionEntity.version = "1"; + versionEntity.versionId = 1; + + writer.writeEntity(versionEntity); + } + + zip.flush(); + zip.close(); + + return new ByteArrayInputStream(outputStream.toByteArray()); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/integration-tests/src/test/java/io/apicurio/tests/migration/MigrationTestsDataInitializer.java b/integration-tests/src/test/java/io/apicurio/tests/migration/MigrationTestsDataInitializer.java new file mode 100644 index 0000000000..16a93f8012 --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/migration/MigrationTestsDataInitializer.java @@ -0,0 +1,213 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.tests.migration; + +import io.apicurio.registry.rest.client.RegistryClient; +import io.apicurio.registry.rest.v2.beans.ArtifactReference; +import io.apicurio.registry.rest.v2.beans.Rule; +import io.apicurio.registry.types.ArtifactState; +import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.types.RuleType; +import io.apicurio.registry.utils.IoUtil; +import io.apicurio.registry.utils.impexp.ArtifactVersionEntity; +import io.apicurio.registry.utils.impexp.ContentEntity; +import io.apicurio.registry.utils.impexp.EntityWriter; +import io.apicurio.registry.utils.tests.TestUtils; +import io.apicurio.tests.serdes.apicurio.AvroGenericRecordSchemaFactory; +import io.apicurio.tests.serdes.apicurio.JsonSchemaMsgFactory; +import org.apache.commons.codec.digest.DigestUtils; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.zip.ZipOutputStream; + +import static io.apicurio.tests.migration.DataMigrationIT.doNotPreserveIdsImportArtifacts; +import static io.apicurio.tests.migration.DataMigrationIT.migrateGlobalIds; +import static io.apicurio.tests.migration.DataMigrationIT.migrateReferencesMap; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class MigrationTestsDataInitializer { + + public static void initializeMigrateTest(RegistryClient source) throws Exception { + migrateGlobalIds = new ArrayList<>(); + migrateReferencesMap = new HashMap<>(); + + JsonSchemaMsgFactory jsonSchema = new JsonSchemaMsgFactory(); + for (int idx = 0; idx < 50; idx++) { + String artifactId = idx + "-" + UUID.randomUUID().toString(); + var amd = source.createArtifact("default", artifactId, jsonSchema.getSchemaStream()); + TestUtils.retry(() -> source.getContentByGlobalId(amd.getGlobalId())); + migrateGlobalIds.add(amd.getGlobalId()); + } + + for (int idx = 0; idx < 15; idx++) { + AvroGenericRecordSchemaFactory avroSchema = new AvroGenericRecordSchemaFactory(List.of("a" + idx)); + String artifactId = "avro-" + idx; + List references = idx > 0 ? getSingletonRefList("migrateTest", "avro-" + (idx - 1), "1", "myRef" + idx) : Collections.emptyList(); + var amd = source.createArtifact("migrateTest", artifactId, avroSchema.generateSchemaStream(), references); + TestUtils.retry(() -> source.getContentByGlobalId(amd.getGlobalId())); + assertTrue(matchesReferences(references, source.getArtifactReferencesByGlobalId(amd.getGlobalId()))); + migrateReferencesMap.put(amd.getGlobalId(), references); + migrateGlobalIds.add(amd.getGlobalId()); + + avroSchema = new AvroGenericRecordSchemaFactory(List.of("u" + idx)); + List updatedReferences = idx > 0 ? getSingletonRefList("migrateTest", "avro-" + (idx - 1), "2", "myRef" + idx) : Collections.emptyList(); + var vmd = source.updateArtifact("migrateTest", artifactId, null, null, null, avroSchema.generateSchemaStream(), updatedReferences); + TestUtils.retry(() -> source.getContentByGlobalId(vmd.getGlobalId())); + assertTrue(matchesReferences(updatedReferences, source.getArtifactReferencesByGlobalId(vmd.getGlobalId()))); + migrateReferencesMap.put(vmd.getGlobalId(), updatedReferences); + migrateGlobalIds.add(vmd.getGlobalId()); + } + + Rule rule = new Rule(); + rule.setType(RuleType.VALIDITY); + rule.setConfig("SYNTAX_ONLY"); + source.createArtifactRule("migrateTest", "avro-0", rule); + + rule = new Rule(); + rule.setType(RuleType.COMPATIBILITY); + rule.setConfig("BACKWARD"); + source.createGlobalRule(rule); + + DataMigrationIT.migrateDataToImport = source.exportData(); + } + + public static void initializeDoNotPreserveIdsImport(RegistryClient source) throws Exception { + // Fill the source registry with data + JsonSchemaMsgFactory jsonSchema = new JsonSchemaMsgFactory(); + for (int idx = 0; idx < 50; idx++) { + String artifactId = idx + "-" + UUID.randomUUID().toString(); + String content = IoUtil.toString(jsonSchema.getSchemaStream()); + var amd = source.createArtifact("testDoNotPreserveIdsImport", artifactId, IoUtil.toStream(content)); + TestUtils.retry(() -> source.getContentByGlobalId(amd.getGlobalId())); + doNotPreserveIdsImportArtifacts.put("testDoNotPreserveIdsImport:" + artifactId, content); + } + + for (int idx = 0; idx < 15; idx++) { + AvroGenericRecordSchemaFactory avroSchema = new AvroGenericRecordSchemaFactory(List.of("a" + idx)); + String artifactId = "avro-" + idx + "-" + UUID.randomUUID().toString(); + String content = IoUtil.toString(avroSchema.generateSchemaStream()); + var amd = source.createArtifact("testDoNotPreserveIdsImport", artifactId, IoUtil.toStream(content)); + TestUtils.retry(() -> source.getContentByGlobalId(amd.getGlobalId())); + doNotPreserveIdsImportArtifacts.put("testDoNotPreserveIdsImport:" + artifactId, content); + + avroSchema = new AvroGenericRecordSchemaFactory(List.of("u" + idx)); + String content2 = IoUtil.toString(avroSchema.generateSchemaStream()); + var vmd = source.updateArtifact("testDoNotPreserveIdsImport", artifactId, IoUtil.toStream(content2)); + TestUtils.retry(() -> source.getContentByGlobalId(vmd.getGlobalId())); + doNotPreserveIdsImportArtifacts.put("testDoNotPreserveIdsImport:" + artifactId, content2); + } + + DoNotPreserveIdsImportIT.doNotPreserveIdsImportDataToImport = source.exportData(); + DoNotPreserveIdsImportIT.jsonSchema = jsonSchema; + } + + protected static List getSingletonRefList(String groupId, String artifactId, String version, String name) { + ArtifactReference artifactReference = new ArtifactReference(); + artifactReference.setGroupId(groupId); + artifactReference.setArtifactId(artifactId); + artifactReference.setVersion(version); + artifactReference.setName(name); + return Collections.singletonList(artifactReference); + } + + public static boolean matchesReferences(List srcReferences, List destReferences) { + return destReferences.size() == srcReferences.size() && destReferences.stream().allMatch( + srcRef -> srcReferences.stream().anyMatch(destRef -> + Objects.equals(srcRef.getGroupId(), destRef.getGroupId()) && + Objects.equals(srcRef.getArtifactId(), destRef.getArtifactId()) && + Objects.equals(srcRef.getVersion(), destRef.getVersion()) && + Objects.equals(srcRef.getName(), destRef.getName())) + ); + } + + public InputStream generateExportedZip(Map artifacts) { + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + ZipOutputStream zip = new ZipOutputStream(outputStream, StandardCharsets.UTF_8); + EntityWriter writer = new EntityWriter(zip); + + Map contentIndex = new HashMap<>(); + + AtomicInteger migrateGlobalIdseq = new AtomicInteger(1); + AtomicInteger contentIdSeq = new AtomicInteger(1); + + for (var entry : artifacts.entrySet()) { + String artifactId = entry.getKey(); + String content = entry.getValue(); + byte[] contentBytes = IoUtil.toBytes(content); + String contentHash = DigestUtils.sha256Hex(contentBytes); + + String artifactType = ArtifactType.JSON; + + Long contentId = contentIndex.computeIfAbsent(contentHash, k -> { + ContentEntity contentEntity = new ContentEntity(); + contentEntity.contentId = contentIdSeq.getAndIncrement(); + contentEntity.contentHash = contentHash; + contentEntity.canonicalHash = null; + contentEntity.contentBytes = contentBytes; + contentEntity.artifactType = artifactType; + + try { + writer.writeEntity(contentEntity); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return contentEntity.contentId; + }); + + ArtifactVersionEntity versionEntity = new ArtifactVersionEntity(); + versionEntity.artifactId = artifactId; + versionEntity.artifactType = artifactType; + versionEntity.contentId = contentId; + versionEntity.createdBy = "integration-tests"; + versionEntity.createdOn = System.currentTimeMillis(); + versionEntity.description = null; + versionEntity.globalId = migrateGlobalIdseq.getAndIncrement(); + versionEntity.groupId = null; + versionEntity.isLatest = true; + versionEntity.labels = null; + versionEntity.name = null; + versionEntity.properties = null; + versionEntity.state = ArtifactState.ENABLED; + versionEntity.version = "1"; + versionEntity.versionId = 1; + + writer.writeEntity(versionEntity); + } + + zip.flush(); + zip.close(); + + return new ByteArrayInputStream(outputStream.toByteArray()); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/MultitenantLimitsIT.java b/integration-tests/src/test/java/io/apicurio/tests/multitenancy/MultitenancyLimitsIT.java similarity index 82% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/MultitenantLimitsIT.java rename to integration-tests/src/test/java/io/apicurio/tests/multitenancy/MultitenancyLimitsIT.java index 12e7d9a82f..e016a2c4be 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/MultitenantLimitsIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/multitenancy/MultitenancyLimitsIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,25 +16,24 @@ package io.apicurio.tests.multitenancy; -import io.apicurio.tenantmanager.api.datamodel.NewApicurioTenantRequest; -import io.apicurio.tenantmanager.api.datamodel.ResourceType; -import io.apicurio.tenantmanager.api.datamodel.TenantResource; -import io.apicurio.tenantmanager.client.TenantManagerClient; -import io.apicurio.tenantmanager.client.TenantManagerClientImpl; import io.apicurio.registry.rest.client.RegistryClient; import io.apicurio.registry.rest.client.RegistryClientFactory; import io.apicurio.registry.rest.client.exception.LimitExceededException; import io.apicurio.registry.rest.v2.beans.EditableMetaData; import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.utils.tests.MultitenancyNoAuthTestProfile; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.rest.client.auth.OidcAuth; -import io.apicurio.rest.client.auth.exception.AuthErrorHandler; -import io.apicurio.rest.client.spi.ApicurioHttpClient; -import io.apicurio.rest.client.spi.ApicurioHttpClientFactory; -import io.apicurio.tests.common.ApicurioRegistryBaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.RegistryFacade; -import io.apicurio.tests.common.auth.CustomJWTAuth; +import io.apicurio.tenantmanager.api.datamodel.NewApicurioTenantRequest; +import io.apicurio.tenantmanager.api.datamodel.ResourceType; +import io.apicurio.tenantmanager.api.datamodel.TenantResource; +import io.apicurio.tenantmanager.client.TenantManagerClient; +import io.apicurio.tenantmanager.client.TenantManagerClientImpl; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.Constants; +import io.apicurio.tests.utils.TenantManagerTestResource; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import io.quarkus.test.junit.TestProfile; import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Tag; @@ -49,16 +48,15 @@ import java.util.Map; import java.util.UUID; -/** - * @author Fabian Martinez - */ @Tag(Constants.MULTITENANCY) -public class MultitenantLimitsIT extends ApicurioRegistryBaseIT { +@QuarkusIntegrationTest +@TestProfile(MultitenancyNoAuthTestProfile.class) +@QuarkusTestResource(value = TenantManagerTestResource.class, restrictToAnnotatedClass = true) +public class MultitenancyLimitsIT extends ApicurioRegistryBaseIT { private static final ByteArrayInputStream CONTENT = new ByteArrayInputStream("{\"type\":\"record\",\"name\":\"myrecord1\",\"fields\":[{\"name\":\"foo\",\"type\":\"string\"}]}".getBytes(StandardCharsets.UTF_8)); private static final long CONTENT_SIZE = CONTENT.available(); private static final ByteArrayInputStream CONTENT_LARGER = new ByteArrayInputStream("{\"type\":\"record\",\"name\":\"myrecord111111111111\",\"fields\":[{\"name\":\"foo\",\"type\":\"string\"}]}".getBytes(StandardCharsets.UTF_8)); - private static final long CONTENT_LARGER_SIZE = CONTENT_LARGER.available(); private static ByteArrayInputStream useContent() { CONTENT.reset(); @@ -70,15 +68,9 @@ private static ByteArrayInputStream useContentLarger() { return CONTENT_LARGER; } - private RegistryFacade registryFacade = RegistryFacade.getInstance(); - - ApicurioHttpClient httpClient; - - protected ApicurioHttpClient getHttpClient(String baseEndpoint) { - if (httpClient == null) { - httpClient = ApicurioHttpClientFactory.create(baseEndpoint, new AuthErrorHandler()); - } - return httpClient; + @Override + public void cleanArtifacts() throws Exception { + //Don't clean up } @Test @@ -93,8 +85,6 @@ public void testLimits() { } private void testTenantLimits(RegistryClient client) { - - String artifactId = TestUtils.generateArtifactId(); client.createArtifact(null, artifactId, ArtifactType.JSON, useContent()); client.createArtifactVersion(null, artifactId, null, useContent()); @@ -194,16 +184,12 @@ private RegistryClient createTenant() { //TODO add limits for more resources - var keycloak = registryFacade.getMTOnlyKeycloakMock(); - - TenantManagerClient tenantManager = new TenantManagerClientImpl(registryFacade.getTenantManagerUrl(), Collections.emptyMap(), - new OidcAuth(getHttpClient(keycloak.tokenEndpoint), keycloak.clientId, keycloak.clientSecret)); + TenantManagerClient tenantManager = new TenantManagerClientImpl(ApicurioRegistryBaseIT.getTenantManagerUrl(), Collections.emptyMap(), null); tenantManager.createTenant(tenantReq); - String tenantAppUrl = TestUtils.getRegistryBaseUrl() + "/t/" + tenantReq.getTenantId(); + String tenantAppUrl = getRegistryBaseUrl() + "/t/" + tenantReq.getTenantId(); - return RegistryClientFactory.create(tenantAppUrl + "/apis/registry/v2", Collections.emptyMap(), new CustomJWTAuth(username, tenantReq.getOrganizationId())); + return RegistryClientFactory.create(tenantAppUrl + "/apis/registry/v2", Collections.emptyMap()); } - } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/MultitenancySupport.java b/integration-tests/src/test/java/io/apicurio/tests/multitenancy/MultitenancySupport.java similarity index 68% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/MultitenancySupport.java rename to integration-tests/src/test/java/io/apicurio/tests/multitenancy/MultitenancySupport.java index ba80b7adc8..0732e00b2f 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/MultitenancySupport.java +++ b/integration-tests/src/test/java/io/apicurio/tests/multitenancy/MultitenancySupport.java @@ -16,35 +16,36 @@ package io.apicurio.tests.multitenancy; -import java.util.Collections; -import java.util.UUID; - +import io.apicurio.registry.rest.client.RegistryClient; +import io.apicurio.registry.rest.client.RegistryClientFactory; +import io.apicurio.registry.utils.tests.TestUtils; import io.apicurio.rest.client.auth.exception.AuthErrorHandler; import io.apicurio.rest.client.spi.ApicurioHttpClient; import io.apicurio.rest.client.spi.ApicurioHttpClientFactory; -import org.junit.jupiter.api.Assertions; - import io.apicurio.tenantmanager.api.datamodel.NewApicurioTenantRequest; import io.apicurio.tenantmanager.client.TenantManagerClient; import io.apicurio.tenantmanager.client.TenantManagerClientImpl; -import io.apicurio.registry.rest.client.RegistryClient; -import io.apicurio.registry.rest.client.RegistryClientFactory; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.rest.client.auth.OidcAuth; -import io.apicurio.tests.common.RegistryFacade; -import io.apicurio.tests.common.auth.CustomJWTAuth; +import org.junit.jupiter.api.Assertions; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import static io.apicurio.rest.client.config.ApicurioClientConfig.APICURIO_REQUEST_HEADERS_PREFIX; /** - * @author Fabian Martinez + * @author Carles Arnal */ public class MultitenancySupport { - private RegistryFacade registryFacade = RegistryFacade.getInstance(); - private TenantManagerClient tenantManager; + private final String tenantManagerUrl; + private final String registryBaseUrl; - public MultitenancySupport() { - //singleton + public MultitenancySupport(String tenantManagerUrl, String registryBaseUrl) { + this.tenantManagerUrl = tenantManagerUrl; + this.registryBaseUrl = registryBaseUrl; } ApicurioHttpClient httpClient; @@ -64,13 +65,12 @@ public TenantUserClient createTenant() throws Exception { public TenantUserClient createTenant(TenantUser user) throws Exception { String tenantAppUrl = registerTenant(user); var client = createUserClient(user, tenantAppUrl); - registryFacade.getMTOnlyKeycloakMock().addStubForTenant(user.principalId, user.principalPassword, user.organizationId); - return new TenantUserClient(user, tenantAppUrl, client, registryFacade.getMTOnlyKeycloakMock().tokenEndpoint); + return new TenantUserClient(user, tenantAppUrl, client, null); } private String registerTenant(TenantUser user) throws Exception { - String tenantAppUrl = TestUtils.getRegistryBaseUrl() + "/t/" + user.tenantId; + String tenantAppUrl = registryBaseUrl + "/t/" + user.tenantId; NewApicurioTenantRequest tenantReq = new NewApicurioTenantRequest(); tenantReq.setOrganizationId(user.organizationId); @@ -85,20 +85,15 @@ private String registerTenant(TenantUser user) throws Exception { return tenantAppUrl; } - public RegistryClient createUserClientCustomJWT(TenantUser user, String tenantAppUrl) { - return RegistryClientFactory.create(tenantAppUrl, Collections.emptyMap(), new CustomJWTAuth(user.principalId, user.organizationId)); - } - public RegistryClient createUserClient(TenantUser user, String tenantAppUrl) { - var keycloak = registryFacade.getMTOnlyKeycloakMock(); - return RegistryClientFactory.create(tenantAppUrl, Collections.emptyMap(), new OidcAuth(getHttpClient(keycloak.tokenEndpoint), user.principalId, user.principalPassword)); + Map headers = new HashMap<>(); + headers.put(APICURIO_REQUEST_HEADERS_PREFIX + "X-Tenant-Id", user.organizationId); + return RegistryClientFactory.create(tenantAppUrl, headers); } public synchronized TenantManagerClient getTenantManagerClient() { if (tenantManager == null) { - var keycloak = registryFacade.getMTOnlyKeycloakMock(); - tenantManager = new TenantManagerClientImpl(registryFacade.getTenantManagerUrl(), Collections.emptyMap(), - new OidcAuth(getHttpClient(keycloak.tokenEndpoint), keycloak.clientId, keycloak.clientSecret)); + tenantManager = new TenantManagerClientImpl(tenantManagerUrl, Collections.emptyMap(), null); } return tenantManager; } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/TenantReaperIT.java b/integration-tests/src/test/java/io/apicurio/tests/multitenancy/TenantReaperIT.java similarity index 77% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/TenantReaperIT.java rename to integration-tests/src/test/java/io/apicurio/tests/multitenancy/TenantReaperIT.java index db6eea58c0..743b2c34f0 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/TenantReaperIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/multitenancy/TenantReaperIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,18 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package io.apicurio.tests.multitenancy; -import io.apicurio.tenantmanager.api.datamodel.TenantStatusValue; -import io.apicurio.tenantmanager.api.datamodel.UpdateApicurioTenantRequest; -import io.apicurio.tenantmanager.client.TenantManagerClient; import io.apicurio.registry.rest.client.RegistryClient; import io.apicurio.registry.rest.client.exception.RestClientException; import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.utils.tests.MultitenancyNoAuthTestProfile; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.common.ApicurioRegistryBaseIT; -import io.apicurio.tests.common.Constants; +import io.apicurio.tenantmanager.api.datamodel.TenantStatusValue; +import io.apicurio.tenantmanager.api.datamodel.UpdateApicurioTenantRequest; +import io.apicurio.tenantmanager.client.TenantManagerClient; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.Constants; +import io.apicurio.tests.utils.TenantManagerTestResource; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import io.quarkus.test.junit.TestProfile; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -34,30 +40,33 @@ import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.List; + import static org.junit.jupiter.api.Assertions.assertNotNull; -/** - * @author Fabian Martinez - * @author Jakub Senko m@jsenko.net - */ @Tag(Constants.MULTITENANCY) +@QuarkusIntegrationTest +@TestProfile(MultitenancyNoAuthTestProfile.class) +@QuarkusTestResource(value = TenantManagerTestResource.class, restrictToAnnotatedClass = true) public class TenantReaperIT extends ApicurioRegistryBaseIT { private static final Logger LOGGER = LoggerFactory.getLogger(TenantReaperIT.class); private static String groupId = "testGroup"; + @Override + public void cleanArtifacts() throws Exception { + //Don't clean up + } + @Test public void testTenantReaper() throws Exception { try { - MultitenancySupport mt = new MultitenancySupport(); - - List tenants = new ArrayList<>(55); - + MultitenancySupport mt = new MultitenancySupport(ApicurioRegistryBaseIT.getTenantManagerUrl(), ApicurioRegistryBaseIT.getRegistryBaseUrl()); + List tenants = new ArrayList<>(5); TenantManagerClient tenantManager = mt.getTenantManagerClient(); - // Create 55 tenants to force use of pagination (currently 50), and some data - for (int i = 0; i < 55; i++) { + // Create 15 tenants to force use of pagination (currently 50), and < { - for (int i = 0; i < 53; i++) { + for (int i = 0; i < 3; i++) { if (tenantManager.getTenant(tenants.get(i).user.tenantId).getStatus() != TenantStatusValue.DELETED) { return false; } @@ -81,7 +90,7 @@ public void testTenantReaper() throws Exception { }); // Ensure that the APIs are disabled - for (int i = 0; i < 53; i++) { + for (int i = 0; i < 3; i++) { RegistryClient client = tenants.get(i).client; try { client.listArtifactsInGroup(groupId); @@ -93,14 +102,14 @@ public void testTenantReaper() throws Exception { } // To test that the data was removed, we will change the tenant status back to ready - for (int i = 0; i < 53; i++) { + for (int i = 0; i < 3; i++) { updateTenantStatus(tenantManager, tenants.get(i).user.tenantId, TenantStatusValue.READY); } // Wait for the reaper again, because it also purges the tenant loader cache TestUtils.waitFor("tenant reaper 2", 3000, 6 * 3000, () -> { try { - for (int i = 0; i < 53; i++) { + for (int i = 0; i < 3; i++) { RegistryClient client = tenants.get(i).client; client.listArtifactsInGroup(groupId); } @@ -111,12 +120,12 @@ public void testTenantReaper() throws Exception { }); // First 53 tenants should be "empty" and the last 2 should keep their content - for (int i = 0; i < 53; i++) { + for (int i = 0; i < 3; i++) { RegistryClient client = tenants.get(i).client; Assertions.assertEquals(0, client.listArtifactsInGroup(groupId).getCount()); } - Assertions.assertEquals(2, tenants.get(53).client.listArtifactsInGroup(groupId).getCount()); - Assertions.assertEquals(2, tenants.get(54).client.listArtifactsInGroup(groupId).getCount()); + Assertions.assertEquals(2, tenants.get(3).client.listArtifactsInGroup(groupId).getCount()); + Assertions.assertEquals(2, tenants.get(4).client.listArtifactsInGroup(groupId).getCount()); } catch (RestClientException restClientException) { LOGGER.warn("Unexpected rest client exception", restClientException); LOGGER.warn("Error code {} message {}", restClientException.getError().getErrorCode(), restClientException.getError().getMessage()); @@ -138,5 +147,4 @@ private void updateTenantStatus(TenantManagerClient tenantManager, String tenant tenantManager.updateTenant(tenantId, request); TestUtils.retry(() -> Assertions.assertEquals(status, tenantManager.getTenant(tenantId).getStatus())); } - } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/TenantUser.java b/integration-tests/src/test/java/io/apicurio/tests/multitenancy/TenantUser.java similarity index 97% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/TenantUser.java rename to integration-tests/src/test/java/io/apicurio/tests/multitenancy/TenantUser.java index 16ac02bc51..bc25a8bed9 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/TenantUser.java +++ b/integration-tests/src/test/java/io/apicurio/tests/multitenancy/TenantUser.java @@ -17,7 +17,7 @@ package io.apicurio.tests.multitenancy; /** - * @author Fabian Martinez + * @author Carles Arnal */ public class TenantUser { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/TenantUserClient.java b/integration-tests/src/test/java/io/apicurio/tests/multitenancy/TenantUserClient.java similarity index 97% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/TenantUserClient.java rename to integration-tests/src/test/java/io/apicurio/tests/multitenancy/TenantUserClient.java index 8b81777039..53b54cc1ab 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/TenantUserClient.java +++ b/integration-tests/src/test/java/io/apicurio/tests/multitenancy/TenantUserClient.java @@ -19,7 +19,7 @@ import io.apicurio.registry.rest.client.RegistryClient; /** - * @author Fabian Martinez + * @author Carles Arnal */ public class TenantUserClient { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/serdes/RateLimitedRegistrySerdeIT.java b/integration-tests/src/test/java/io/apicurio/tests/multitenancy/serdes/RateLimitedRegistrySerdeIT.java similarity index 61% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/serdes/RateLimitedRegistrySerdeIT.java rename to integration-tests/src/test/java/io/apicurio/tests/multitenancy/serdes/RateLimitedRegistrySerdeIT.java index 3e23e0fc77..1ad346ae3c 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/serdes/RateLimitedRegistrySerdeIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/multitenancy/serdes/RateLimitedRegistrySerdeIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,23 +16,6 @@ package io.apicurio.tests.multitenancy.serdes; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.io.InputStream; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -import io.apicurio.tests.utils.RetryLimitingProxy; -import io.vertx.core.http.HttpServer; -import org.apache.avro.generic.GenericRecord; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable; - import io.apicurio.registry.rest.client.RegistryClient; import io.apicurio.registry.rest.client.exception.RateLimitedClientException; import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; @@ -44,23 +27,42 @@ import io.apicurio.registry.serde.strategy.TopicIdStrategy; import io.apicurio.registry.types.ArtifactType; import io.apicurio.registry.utils.IoUtil; +import io.apicurio.registry.utils.tests.MultitenancyNoAuthTestProfile; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.common.ApicurioRegistryBaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.KafkaFacade; +import io.apicurio.tests.ApicurioRegistryBaseIT; import io.apicurio.tests.multitenancy.MultitenancySupport; -import io.apicurio.tests.serdes.apicurio.AvroGenericRecordSchemaFactory; import io.apicurio.tests.serdes.apicurio.SimpleSerdesTesterBuilder; +import io.apicurio.tests.utils.AvroGenericRecordSchemaFactory; +import io.apicurio.tests.utils.Constants; +import io.apicurio.tests.utils.KafkaFacade; import io.apicurio.tests.utils.RateLimitingProxy; +import io.apicurio.tests.utils.RetryLimitingProxy; +import io.apicurio.tests.utils.TenantManagerTestResource; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import io.quarkus.test.junit.TestProfile; +import io.vertx.core.http.HttpServer; +import org.apache.avro.generic.GenericRecord; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.io.InputStream; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; -/** - * @author Fabian Martinez - */ @Tag(Constants.MULTITENANCY) -@DisabledIfEnvironmentVariable(named = Constants.CURRENT_ENV, matches = Constants.CURRENT_ENV_MAS_REGEX) +@QuarkusIntegrationTest +@TestProfile(MultitenancyNoAuthTestProfile.class) +@QuarkusTestResource(value = TenantManagerTestResource.class, restrictToAnnotatedClass = true) public class RateLimitedRegistrySerdeIT extends ApicurioRegistryBaseIT { - private KafkaFacade kafkaCluster = KafkaFacade.getInstance(); + private final KafkaFacade kafkaCluster = KafkaFacade.getInstance(); @BeforeAll void setupEnvironment() { @@ -68,22 +70,27 @@ void setupEnvironment() { } @AfterAll - public void teardown() throws Exception { + void teardownEnvironment() throws Exception { kafkaCluster.stopIfPossible(); } + @Override + public void cleanArtifacts() throws Exception { + //Don't clean up + } + protected void createArtifact(RegistryClient client, String groupId, String artifactId, String artifactType, InputStream artifact) throws Exception { ArtifactMetaData meta = client.createArtifact(groupId, artifactId, null, artifactType, IfExists.FAIL, false, artifact); - TestUtils.retry(() -> client.getContentByGlobalId(meta.getGlobalId())); + retry(() -> client.getContentByGlobalId(meta.getGlobalId())); assertNotNull(client.getLatestArtifact(meta.getGroupId(), meta.getId())); } @Test void testRateLimitingProxy() throws Exception { - RateLimitingProxy proxy = new RateLimitingProxy(2, TestUtils.getRegistryHost(), TestUtils.getRegistryPort()); + RateLimitingProxy proxy = new RateLimitingProxy(2, getRegistryHost(), getRegistryPort()); - MultitenancySupport mt = new MultitenancySupport(); + MultitenancySupport mt = new MultitenancySupport(ApicurioRegistryBaseIT.getTenantManagerUrl(), ApicurioRegistryBaseIT.getRegistryBaseUrl()); var tenant = mt.createTenant(); RegistryClient clientTenant = tenant.client; @@ -94,7 +101,7 @@ void testRateLimitingProxy() throws Exception { try { final CompletableFuture server = proxy.start(); - TestUtils.waitFor("proxy is ready", Constants.POLL_INTERVAL, Constants.TIMEOUT_GLOBAL, server::isDone); + waitFor("proxy is ready", Constants.POLL_INTERVAL, Constants.TIMEOUT_GLOBAL, server::isDone); RegistryClient rateLimitedClient = mt.createUserClient(tenant.user, tenantRateLimitedUrl); @@ -106,7 +113,7 @@ void testRateLimitingProxy() throws Exception { //client connecting to rate limiting proxy , from now requests should fail Assertions.assertThrows(RateLimitedClientException.class, () -> rateLimitedClient.listArtifactsInGroup(null)); Assertions.assertThrows(RateLimitedClientException.class, () -> rateLimitedClient.listArtifactsInGroup(null)); - Assertions.assertThrows(RateLimitedClientException.class, () -> rateLimitedClient.listGlobalRules()); + Assertions.assertThrows(RateLimitedClientException.class, rateLimitedClient::listGlobalRules); } finally { proxy.stop(); @@ -115,9 +122,9 @@ void testRateLimitingProxy() throws Exception { @Test void testRetryLimitingProxy() throws Exception { - RetryLimitingProxy proxy = new RetryLimitingProxy(2, TestUtils.getRegistryHost(), TestUtils.getRegistryPort()); + RetryLimitingProxy proxy = new RetryLimitingProxy(2, getRegistryHost(), getRegistryPort()); - MultitenancySupport mt = new MultitenancySupport(); + MultitenancySupport mt = new MultitenancySupport(ApicurioRegistryBaseIT.getTenantManagerUrl(), ApicurioRegistryBaseIT.getRegistryBaseUrl()); var tenant = mt.createTenant(); RegistryClient clientTenant = tenant.client; @@ -150,9 +157,9 @@ void testRetryLimitingProxy() throws Exception { @Test void testFindLatestRateLimited() throws Exception { - RateLimitingProxy proxy = new RateLimitingProxy(3, TestUtils.getRegistryHost(), TestUtils.getRegistryPort()); + RateLimitingProxy proxy = new RateLimitingProxy(3, getRegistryHost(), getRegistryPort()); - MultitenancySupport mt = new MultitenancySupport(); + MultitenancySupport mt = new MultitenancySupport(ApicurioRegistryBaseIT.getTenantManagerUrl(), ApicurioRegistryBaseIT.getRegistryBaseUrl()); var tenant = mt.createTenant(); RegistryClient clientTenant = tenant.client; String tenantRateLimitedUrl = proxy.getServerUrl() + "/t/" + tenant.user.tenantId; @@ -170,43 +177,36 @@ void testFindLatestRateLimited() throws Exception { createArtifact(clientTenant, topicName, artifactId, ArtifactType.AVRO, avroSchema.generateSchemaStream()); new SimpleSerdesTesterBuilder() - .withTopic(topicName) - - //url of the proxy - .withCommonProperty(SerdeConfig.REGISTRY_URL, tenantRateLimitedUrl) + .withTopic(topicName) - //add auth properties - .withCommonProperty(SerdeConfig.AUTH_TOKEN_ENDPOINT, tenant.tokenEndpoint) - //making use of tenant owner is admin feature - .withCommonProperty(SerdeConfig.AUTH_CLIENT_ID, tenant.user.principalId) - .withCommonProperty(SerdeConfig.AUTH_CLIENT_SECRET, tenant.user.principalPassword) + //url of the proxy + .withCommonProperty(SerdeConfig.REGISTRY_URL, tenantRateLimitedUrl) - .withSerializer(AvroKafkaSerializer.class) - .withDeserializer(AvroKafkaDeserializer.class) - .withStrategy(SimpleTopicIdStrategy.class) - .withDataGenerator(avroSchema::generateRecord) - .withDataValidator(avroSchema::validateRecord) - .withProducerProperty(SerdeConfig.EXPLICIT_ARTIFACT_GROUP_ID, topicName) + .withSerializer(AvroKafkaSerializer.class) + .withDeserializer(AvroKafkaDeserializer.class) + .withStrategy(SimpleTopicIdStrategy.class) + .withDataGenerator(avroSchema::generateRecord) + .withDataValidator(avroSchema::validateRecord) + .withProducerProperty(SerdeConfig.EXPLICIT_ARTIFACT_GROUP_ID, topicName) - // make serdes tester send multiple message batches, that will test that the cache is used when loaded - .withMessages(4, 5) + // make serdes tester send multiple message batches, that will test that the cache is used when loaded + .withMessages(4, 5) - .build() - .test(); + .build() + .test(); } finally { proxy.stop(); } - } @Test void testAutoRegisterRateLimited() throws Exception { - RateLimitingProxy proxy = new RateLimitingProxy(3, TestUtils.getRegistryHost(), TestUtils.getRegistryPort()); + RateLimitingProxy proxy = new RateLimitingProxy(3, getRegistryHost(), getRegistryPort()); - MultitenancySupport mt = new MultitenancySupport(); + MultitenancySupport mt = new MultitenancySupport(ApicurioRegistryBaseIT.getTenantManagerUrl(), ApicurioRegistryBaseIT.getRegistryBaseUrl()); var tenant = mt.createTenant(); RegistryClient clientTenant = tenant.client; String tenantRateLimitedUrl = proxy.getServerUrl() + "/t/" + tenant.user.tenantId; @@ -223,36 +223,30 @@ void testAutoRegisterRateLimited() throws Exception { AvroGenericRecordSchemaFactory avroSchema = new AvroGenericRecordSchemaFactory("myrecordapicurio1", List.of("key1")); new SimpleSerdesTesterBuilder() - .withTopic(topicName) - - //url of the proxy - .withCommonProperty(SerdeConfig.REGISTRY_URL, tenantRateLimitedUrl) - - //add auth properties - .withCommonProperty(SerdeConfig.AUTH_TOKEN_ENDPOINT, tenant.tokenEndpoint) - //making use of tenant owner is admin feature - .withCommonProperty(SerdeConfig.AUTH_CLIENT_ID, tenant.user.principalId) - .withCommonProperty(SerdeConfig.AUTH_CLIENT_SECRET, tenant.user.principalPassword) - - .withSerializer(AvroKafkaSerializer.class) - .withDeserializer(AvroKafkaDeserializer.class) - .withStrategy(TopicIdStrategy.class) - .withDataGenerator(avroSchema::generateRecord) - .withDataValidator(avroSchema::validateRecord) - .withProducerProperty(SerdeConfig.AUTO_REGISTER_ARTIFACT, "true") - .withAfterProduceValidator(() -> { - return TestUtils.retry(() -> { - ArtifactMetaData meta = clientTenant.getArtifactMetaData(null, artifactId); - clientTenant.getContentByGlobalId(meta.getGlobalId()); - return true; - }); - }) + .withTopic(topicName) + + //url of the proxy + .withCommonProperty(SerdeConfig.REGISTRY_URL, tenantRateLimitedUrl) - // make serdes tester send multiple message batches, that will test that the cache is used when loaded - .withMessages(4, 5) + .withSerializer(AvroKafkaSerializer.class) + .withDeserializer(AvroKafkaDeserializer.class) + .withStrategy(TopicIdStrategy.class) + .withDataGenerator(avroSchema::generateRecord) + .withDataValidator(avroSchema::validateRecord) + .withProducerProperty(SerdeConfig.AUTO_REGISTER_ARTIFACT, "true") + .withAfterProduceValidator(() -> { + return TestUtils.retry(() -> { + ArtifactMetaData meta = clientTenant.getArtifactMetaData(null, artifactId); + clientTenant.getContentByGlobalId(meta.getGlobalId()); + return true; + }); + }) - .build() - .test(); + // make serdes tester send multiple message batches, that will test that the cache is used when loaded + .withMessages(4, 5) + + .build() + .test(); ArtifactMetaData meta = clientTenant.getArtifactMetaData(null, artifactId); @@ -263,15 +257,14 @@ void testAutoRegisterRateLimited() throws Exception { } finally { proxy.stop(); } - } @Test void testRetryRateLimited() throws Exception { - RetryLimitingProxy proxy = new RetryLimitingProxy(3, TestUtils.getRegistryHost(), TestUtils.getRegistryPort()); + RetryLimitingProxy proxy = new RetryLimitingProxy(3, getRegistryHost(), getRegistryPort()); - MultitenancySupport mt = new MultitenancySupport(); + MultitenancySupport mt = new MultitenancySupport(ApicurioRegistryBaseIT.getTenantManagerUrl(), ApicurioRegistryBaseIT.getRegistryBaseUrl()); var tenant = mt.createTenant(); RegistryClient clientTenant = tenant.client; String tenantRateLimitedUrl = proxy.getServerUrl() + "/t/" + tenant.user.tenantId; @@ -288,36 +281,28 @@ void testRetryRateLimited() throws Exception { AvroGenericRecordSchemaFactory avroSchema = new AvroGenericRecordSchemaFactory("myrecordapicurio1", List.of("key1")); new SimpleSerdesTesterBuilder() - .withTopic(topicName) - - //url of the proxy - .withCommonProperty(SerdeConfig.REGISTRY_URL, tenantRateLimitedUrl) - - //add auth properties - .withCommonProperty(SerdeConfig.AUTH_TOKEN_ENDPOINT, tenant.tokenEndpoint) - //making use of tenant owner is admin feature - .withCommonProperty(SerdeConfig.AUTH_CLIENT_ID, tenant.user.principalId) - .withCommonProperty(SerdeConfig.AUTH_CLIENT_SECRET, tenant.user.principalPassword) - - .withSerializer(AvroKafkaSerializer.class) - .withDeserializer(AvroKafkaDeserializer.class) - .withStrategy(TopicIdStrategy.class) - .withDataGenerator(avroSchema::generateRecord) - .withDataValidator(avroSchema::validateRecord) - .withProducerProperty(SerdeConfig.AUTO_REGISTER_ARTIFACT, "true") - .withAfterProduceValidator(() -> { - return TestUtils.retry(() -> { + .withTopic(topicName) + + //url of the proxy + .withCommonProperty(SerdeConfig.REGISTRY_URL, tenantRateLimitedUrl) + + .withSerializer(AvroKafkaSerializer.class) + .withDeserializer(AvroKafkaDeserializer.class) + .withStrategy(TopicIdStrategy.class) + .withDataGenerator(avroSchema::generateRecord) + .withDataValidator(avroSchema::validateRecord) + .withProducerProperty(SerdeConfig.AUTO_REGISTER_ARTIFACT, "true") + .withAfterProduceValidator(() -> TestUtils.retry(() -> { ArtifactMetaData meta = clientTenant.getArtifactMetaData(null, artifactId); clientTenant.getContentByGlobalId(meta.getGlobalId()); return true; - }); - }) + })) - // make serdes tester send multiple message batches, that will test that the cache is used when loaded - .withMessages(4, 5) + // make serdes tester send multiple message batches, that will test that the cache is used when loaded + .withMessages(4, 5) - .build() - .test(); + .build() + .test(); ArtifactMetaData meta = clientTenant.getArtifactMetaData(null, artifactId); diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/Header.java b/integration-tests/src/test/java/io/apicurio/tests/protobuf/Header.java similarity index 80% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/Header.java rename to integration-tests/src/test/java/io/apicurio/tests/protobuf/Header.java index eb246b7ed1..05ab3ceeba 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/Header.java +++ b/integration-tests/src/test/java/io/apicurio/tests/protobuf/Header.java @@ -9,7 +9,7 @@ public final class Header extends com.google.protobuf.GeneratedMessageV3 implements // @@protoc_insertion_point(message_implements:io.apicurio.tests.protobuf.Header) - HeaderOrBuilder { + HeaderOrBuilder { private static final long serialVersionUID = 0L; // Use Header.newBuilder() to construct. private Header(com.google.protobuf.GeneratedMessageV3.Builder builder) { @@ -24,14 +24,14 @@ private Header() { rawMessage_ = ""; } - @java.lang.Override + @Override @SuppressWarnings({"unused"}) - protected java.lang.Object newInstance( + protected Object newInstance( UnusedPrivateParameter unused) { return new Header(); } - @java.lang.Override + @Override public final com.google.protobuf.UnknownFieldSet getUnknownFields() { return this.unknownFields; @@ -42,7 +42,7 @@ private Header( throws com.google.protobuf.InvalidProtocolBufferException { this(); if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); + throw new NullPointerException(); } int mutable_bitField0_ = 0; com.google.protobuf.UnknownFieldSet.Builder unknownFields = @@ -69,25 +69,25 @@ private Header( break; } case 18: { - java.lang.String s = input.readStringRequireUtf8(); + String s = input.readStringRequireUtf8(); source_ = s; break; } case 26: { - java.lang.String s = input.readStringRequireUtf8(); + String s = input.readStringRequireUtf8(); destination_ = s; break; } case 34: { - java.lang.String s = input.readStringRequireUtf8(); + String s = input.readStringRequireUtf8(); uuid_ = s; break; } case 42: { - java.lang.String s = input.readStringRequireUtf8(); + String s = input.readStringRequireUtf8(); if (!((mutable_bitField0_ & 0x00000001) != 0)) { sourceUuids_ = new com.google.protobuf.LazyStringArrayList(); mutable_bitField0_ |= 0x00000001; @@ -96,13 +96,13 @@ private Header( break; } case 50: { - java.lang.String s = input.readStringRequireUtf8(); + String s = input.readStringRequireUtf8(); messageTypeId_ = s; break; } case 58: { - java.lang.String s = input.readStringRequireUtf8(); + String s = input.readStringRequireUtf8(); rawMessage_ = s; break; @@ -131,15 +131,15 @@ private Header( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_Header_descriptor; + return Testmessage.internal_static_io_apicurio_tests_protobuf_Header_descriptor; } - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + @Override + protected FieldAccessorTable internalGetFieldAccessorTable() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_Header_fieldAccessorTable + return Testmessage.internal_static_io_apicurio_tests_protobuf_Header_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.apicurio.tests.protobuf.Header.class, io.apicurio.tests.protobuf.Header.Builder.class); + Header.class, Builder.class); } public static final int TIME_FIELD_NUMBER = 1; @@ -148,7 +148,7 @@ private Header( * .google.protobuf.Timestamp time = 1; * @return Whether the time field is set. */ - @java.lang.Override + @Override public boolean hasTime() { return time_ != null; } @@ -156,33 +156,33 @@ public boolean hasTime() { * .google.protobuf.Timestamp time = 1; * @return The time. */ - @java.lang.Override + @Override public com.google.protobuf.Timestamp getTime() { return time_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : time_; } /** * .google.protobuf.Timestamp time = 1; */ - @java.lang.Override + @Override public com.google.protobuf.TimestampOrBuilder getTimeOrBuilder() { return getTime(); } public static final int SOURCE_FIELD_NUMBER = 2; - private volatile java.lang.Object source_; + private volatile Object source_; /** * string source = 2; * @return The source. */ - @java.lang.Override - public java.lang.String getSource() { - java.lang.Object ref = source_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; + @Override + public String getSource() { + Object ref = source_; + if (ref instanceof String) { + return (String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); source_ = s; return s; } @@ -191,14 +191,14 @@ public java.lang.String getSource() { * string source = 2; * @return The bytes for source. */ - @java.lang.Override + @Override public com.google.protobuf.ByteString getSourceBytes() { - java.lang.Object ref = source_; - if (ref instanceof java.lang.String) { + Object ref = source_; + if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); source_ = b; return b; } else { @@ -207,20 +207,20 @@ public java.lang.String getSource() { } public static final int DESTINATION_FIELD_NUMBER = 3; - private volatile java.lang.Object destination_; + private volatile Object destination_; /** * string destination = 3; * @return The destination. */ - @java.lang.Override - public java.lang.String getDestination() { - java.lang.Object ref = destination_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; + @Override + public String getDestination() { + Object ref = destination_; + if (ref instanceof String) { + return (String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); destination_ = s; return s; } @@ -229,14 +229,14 @@ public java.lang.String getDestination() { * string destination = 3; * @return The bytes for destination. */ - @java.lang.Override + @Override public com.google.protobuf.ByteString getDestinationBytes() { - java.lang.Object ref = destination_; - if (ref instanceof java.lang.String) { + Object ref = destination_; + if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); destination_ = b; return b; } else { @@ -245,20 +245,20 @@ public java.lang.String getDestination() { } public static final int UUID_FIELD_NUMBER = 4; - private volatile java.lang.Object uuid_; + private volatile Object uuid_; /** * string uuid = 4; * @return The uuid. */ - @java.lang.Override - public java.lang.String getUuid() { - java.lang.Object ref = uuid_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; + @Override + public String getUuid() { + Object ref = uuid_; + if (ref instanceof String) { + return (String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); uuid_ = s; return s; } @@ -267,14 +267,14 @@ public java.lang.String getUuid() { * string uuid = 4; * @return The bytes for uuid. */ - @java.lang.Override + @Override public com.google.protobuf.ByteString getUuidBytes() { - java.lang.Object ref = uuid_; - if (ref instanceof java.lang.String) { + Object ref = uuid_; + if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); uuid_ = b; return b; } else { @@ -304,7 +304,7 @@ public int getSourceUuidsCount() { * @param index The index of the element to return. * @return The sourceUuids at the given index. */ - public java.lang.String getSourceUuids(int index) { + public String getSourceUuids(int index) { return sourceUuids_.get(index); } /** @@ -318,20 +318,20 @@ public java.lang.String getSourceUuids(int index) { } public static final int MESSAGE_TYPE_ID_FIELD_NUMBER = 6; - private volatile java.lang.Object messageTypeId_; + private volatile Object messageTypeId_; /** * string message_type_id = 6; * @return The messageTypeId. */ - @java.lang.Override - public java.lang.String getMessageTypeId() { - java.lang.Object ref = messageTypeId_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; + @Override + public String getMessageTypeId() { + Object ref = messageTypeId_; + if (ref instanceof String) { + return (String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); messageTypeId_ = s; return s; } @@ -340,14 +340,14 @@ public java.lang.String getMessageTypeId() { * string message_type_id = 6; * @return The bytes for messageTypeId. */ - @java.lang.Override + @Override public com.google.protobuf.ByteString getMessageTypeIdBytes() { - java.lang.Object ref = messageTypeId_; - if (ref instanceof java.lang.String) { + Object ref = messageTypeId_; + if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); messageTypeId_ = b; return b; } else { @@ -356,20 +356,20 @@ public java.lang.String getMessageTypeId() { } public static final int RAW_MESSAGE_FIELD_NUMBER = 7; - private volatile java.lang.Object rawMessage_; + private volatile Object rawMessage_; /** * string raw_message = 7; * @return The rawMessage. */ - @java.lang.Override - public java.lang.String getRawMessage() { - java.lang.Object ref = rawMessage_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; + @Override + public String getRawMessage() { + Object ref = rawMessage_; + if (ref instanceof String) { + return (String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); rawMessage_ = s; return s; } @@ -378,14 +378,14 @@ public java.lang.String getRawMessage() { * string raw_message = 7; * @return The bytes for rawMessage. */ - @java.lang.Override + @Override public com.google.protobuf.ByteString getRawMessageBytes() { - java.lang.Object ref = rawMessage_; - if (ref instanceof java.lang.String) { + Object ref = rawMessage_; + if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); rawMessage_ = b; return b; } else { @@ -394,7 +394,7 @@ public java.lang.String getRawMessage() { } private byte memoizedIsInitialized = -1; - @java.lang.Override + @Override public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; @@ -404,7 +404,7 @@ public final boolean isInitialized() { return true; } - @java.lang.Override + @Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (time_ != null) { @@ -431,7 +431,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) unknownFields.writeTo(output); } - @java.lang.Override + @Override public int getSerializedSize() { int size = memoizedSize; if (size != -1) return size; @@ -469,15 +469,15 @@ public int getSerializedSize() { return size; } - @java.lang.Override - public boolean equals(final java.lang.Object obj) { + @Override + public boolean equals(final Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.apicurio.tests.protobuf.Header)) { + if (!(obj instanceof Header)) { return super.equals(obj); } - io.apicurio.tests.protobuf.Header other = (io.apicurio.tests.protobuf.Header) obj; + Header other = (Header) obj; if (hasTime() != other.hasTime()) return false; if (hasTime()) { @@ -500,7 +500,7 @@ public boolean equals(final java.lang.Object obj) { return true; } - @java.lang.Override + @Override public int hashCode() { if (memoizedHashCode != 0) { return memoizedHashCode; @@ -530,69 +530,69 @@ public int hashCode() { return hash; } - public static io.apicurio.tests.protobuf.Header parseFrom( + public static Header parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.apicurio.tests.protobuf.Header parseFrom( + public static Header parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.apicurio.tests.protobuf.Header parseFrom( + public static Header parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.apicurio.tests.protobuf.Header parseFrom( + public static Header parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.apicurio.tests.protobuf.Header parseFrom(byte[] data) + public static Header parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.apicurio.tests.protobuf.Header parseFrom( + public static Header parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.apicurio.tests.protobuf.Header parseFrom(java.io.InputStream input) + public static Header parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static io.apicurio.tests.protobuf.Header parseFrom( + public static Header parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.apicurio.tests.protobuf.Header parseDelimitedFrom(java.io.InputStream input) + public static Header parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static io.apicurio.tests.protobuf.Header parseDelimitedFrom( + public static Header parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.apicurio.tests.protobuf.Header parseFrom( + public static Header parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static io.apicurio.tests.protobuf.Header parseFrom( + public static Header parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -600,23 +600,23 @@ public static io.apicurio.tests.protobuf.Header parseFrom( .parseWithIOException(PARSER, input, extensionRegistry); } - @java.lang.Override + @Override public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.apicurio.tests.protobuf.Header prototype) { + public static Builder newBuilder(Header prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } - @java.lang.Override + @Override public Builder toBuilder() { return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); } - @java.lang.Override + @Override protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + BuilderParent parent) { Builder builder = new Builder(parent); return builder; } @@ -626,18 +626,18 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements // @@protoc_insertion_point(builder_implements:io.apicurio.tests.protobuf.Header) - io.apicurio.tests.protobuf.HeaderOrBuilder { + HeaderOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_Header_descriptor; + return Testmessage.internal_static_io_apicurio_tests_protobuf_Header_descriptor; } - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + @Override + protected FieldAccessorTable internalGetFieldAccessorTable() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_Header_fieldAccessorTable + return Testmessage.internal_static_io_apicurio_tests_protobuf_Header_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.apicurio.tests.protobuf.Header.class, io.apicurio.tests.protobuf.Header.Builder.class); + Header.class, Builder.class); } // Construct using io.apicurio.tests.protobuf.Header.newBuilder() @@ -646,7 +646,7 @@ private Builder() { } private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + BuilderParent parent) { super(parent); maybeForceBuilderInitialization(); } @@ -655,7 +655,7 @@ private void maybeForceBuilderInitialization() { .alwaysUseFieldBuilders) { } } - @java.lang.Override + @Override public Builder clear() { super.clear(); if (timeBuilder_ == null) { @@ -679,29 +679,29 @@ public Builder clear() { return this; } - @java.lang.Override + @Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_Header_descriptor; + return Testmessage.internal_static_io_apicurio_tests_protobuf_Header_descriptor; } - @java.lang.Override - public io.apicurio.tests.protobuf.Header getDefaultInstanceForType() { - return io.apicurio.tests.protobuf.Header.getDefaultInstance(); + @Override + public Header getDefaultInstanceForType() { + return Header.getDefaultInstance(); } - @java.lang.Override - public io.apicurio.tests.protobuf.Header build() { - io.apicurio.tests.protobuf.Header result = buildPartial(); + @Override + public Header build() { + Header result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } - @java.lang.Override - public io.apicurio.tests.protobuf.Header buildPartial() { - io.apicurio.tests.protobuf.Header result = new io.apicurio.tests.protobuf.Header(this); + @Override + public Header buildPartial() { + Header result = new Header(this); int from_bitField0_ = bitField0_; if (timeBuilder_ == null) { result.time_ = time_; @@ -722,50 +722,50 @@ public io.apicurio.tests.protobuf.Header buildPartial() { return result; } - @java.lang.Override + @Override public Builder clone() { return super.clone(); } - @java.lang.Override + @Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { + Object value) { return super.setField(field, value); } - @java.lang.Override + @Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { return super.clearField(field); } - @java.lang.Override + @Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { return super.clearOneof(oneof); } - @java.lang.Override + @Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { + int index, Object value) { return super.setRepeatedField(field, index, value); } - @java.lang.Override + @Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { + Object value) { return super.addRepeatedField(field, value); } - @java.lang.Override + @Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.apicurio.tests.protobuf.Header) { - return mergeFrom((io.apicurio.tests.protobuf.Header)other); + if (other instanceof Header) { + return mergeFrom((Header)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.apicurio.tests.protobuf.Header other) { - if (other == io.apicurio.tests.protobuf.Header.getDefaultInstance()) return this; + public Builder mergeFrom(Header other) { + if (other == Header.getDefaultInstance()) return this; if (other.hasTime()) { mergeTime(other.getTime()); } @@ -804,21 +804,21 @@ public Builder mergeFrom(io.apicurio.tests.protobuf.Header other) { return this; } - @java.lang.Override + @Override public final boolean isInitialized() { return true; } - @java.lang.Override + @Override public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - io.apicurio.tests.protobuf.Header parsedMessage = null; + Header parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (io.apicurio.tests.protobuf.Header) e.getUnfinishedMessage(); + parsedMessage = (Header) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -948,21 +948,21 @@ public com.google.protobuf.TimestampOrBuilder getTimeOrBuilder() { return timeBuilder_; } - private java.lang.Object source_ = ""; + private Object source_ = ""; /** * string source = 2; * @return The source. */ - public java.lang.String getSource() { - java.lang.Object ref = source_; - if (!(ref instanceof java.lang.String)) { + public String getSource() { + Object ref = source_; + if (!(ref instanceof String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); source_ = s; return s; } else { - return (java.lang.String) ref; + return (String) ref; } } /** @@ -971,11 +971,11 @@ public java.lang.String getSource() { */ public com.google.protobuf.ByteString getSourceBytes() { - java.lang.Object ref = source_; + Object ref = source_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); source_ = b; return b; } else { @@ -988,7 +988,7 @@ public java.lang.String getSource() { * @return This builder for chaining. */ public Builder setSource( - java.lang.String value) { + String value) { if (value == null) { throw new NullPointerException(); } @@ -1024,21 +1024,21 @@ public Builder setSourceBytes( return this; } - private java.lang.Object destination_ = ""; + private Object destination_ = ""; /** * string destination = 3; * @return The destination. */ - public java.lang.String getDestination() { - java.lang.Object ref = destination_; - if (!(ref instanceof java.lang.String)) { + public String getDestination() { + Object ref = destination_; + if (!(ref instanceof String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); destination_ = s; return s; } else { - return (java.lang.String) ref; + return (String) ref; } } /** @@ -1047,11 +1047,11 @@ public java.lang.String getDestination() { */ public com.google.protobuf.ByteString getDestinationBytes() { - java.lang.Object ref = destination_; + Object ref = destination_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); destination_ = b; return b; } else { @@ -1064,7 +1064,7 @@ public java.lang.String getDestination() { * @return This builder for chaining. */ public Builder setDestination( - java.lang.String value) { + String value) { if (value == null) { throw new NullPointerException(); } @@ -1100,21 +1100,21 @@ public Builder setDestinationBytes( return this; } - private java.lang.Object uuid_ = ""; + private Object uuid_ = ""; /** * string uuid = 4; * @return The uuid. */ - public java.lang.String getUuid() { - java.lang.Object ref = uuid_; - if (!(ref instanceof java.lang.String)) { + public String getUuid() { + Object ref = uuid_; + if (!(ref instanceof String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); uuid_ = s; return s; } else { - return (java.lang.String) ref; + return (String) ref; } } /** @@ -1123,11 +1123,11 @@ public java.lang.String getUuid() { */ public com.google.protobuf.ByteString getUuidBytes() { - java.lang.Object ref = uuid_; + Object ref = uuid_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); uuid_ = b; return b; } else { @@ -1140,7 +1140,7 @@ public java.lang.String getUuid() { * @return This builder for chaining. */ public Builder setUuid( - java.lang.String value) { + String value) { if (value == null) { throw new NullPointerException(); } @@ -1203,7 +1203,7 @@ public int getSourceUuidsCount() { * @param index The index of the element to return. * @return The sourceUuids at the given index. */ - public java.lang.String getSourceUuids(int index) { + public String getSourceUuids(int index) { return sourceUuids_.get(index); } /** @@ -1222,7 +1222,7 @@ public java.lang.String getSourceUuids(int index) { * @return This builder for chaining. */ public Builder setSourceUuids( - int index, java.lang.String value) { + int index, String value) { if (value == null) { throw new NullPointerException(); } @@ -1237,7 +1237,7 @@ public Builder setSourceUuids( * @return This builder for chaining. */ public Builder addSourceUuids( - java.lang.String value) { + String value) { if (value == null) { throw new NullPointerException(); } @@ -1252,7 +1252,7 @@ public Builder addSourceUuids( * @return This builder for chaining. */ public Builder addAllSourceUuids( - java.lang.Iterable values) { + Iterable values) { ensureSourceUuidsIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( values, sourceUuids_); @@ -1286,21 +1286,21 @@ public Builder addSourceUuidsBytes( return this; } - private java.lang.Object messageTypeId_ = ""; + private Object messageTypeId_ = ""; /** * string message_type_id = 6; * @return The messageTypeId. */ - public java.lang.String getMessageTypeId() { - java.lang.Object ref = messageTypeId_; - if (!(ref instanceof java.lang.String)) { + public String getMessageTypeId() { + Object ref = messageTypeId_; + if (!(ref instanceof String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); messageTypeId_ = s; return s; } else { - return (java.lang.String) ref; + return (String) ref; } } /** @@ -1309,11 +1309,11 @@ public java.lang.String getMessageTypeId() { */ public com.google.protobuf.ByteString getMessageTypeIdBytes() { - java.lang.Object ref = messageTypeId_; + Object ref = messageTypeId_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); messageTypeId_ = b; return b; } else { @@ -1326,7 +1326,7 @@ public java.lang.String getMessageTypeId() { * @return This builder for chaining. */ public Builder setMessageTypeId( - java.lang.String value) { + String value) { if (value == null) { throw new NullPointerException(); } @@ -1362,21 +1362,21 @@ public Builder setMessageTypeIdBytes( return this; } - private java.lang.Object rawMessage_ = ""; + private Object rawMessage_ = ""; /** * string raw_message = 7; * @return The rawMessage. */ - public java.lang.String getRawMessage() { - java.lang.Object ref = rawMessage_; - if (!(ref instanceof java.lang.String)) { + public String getRawMessage() { + Object ref = rawMessage_; + if (!(ref instanceof String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); rawMessage_ = s; return s; } else { - return (java.lang.String) ref; + return (String) ref; } } /** @@ -1385,11 +1385,11 @@ public java.lang.String getRawMessage() { */ public com.google.protobuf.ByteString getRawMessageBytes() { - java.lang.Object ref = rawMessage_; + Object ref = rawMessage_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); rawMessage_ = b; return b; } else { @@ -1402,7 +1402,7 @@ public java.lang.String getRawMessage() { * @return This builder for chaining. */ public Builder setRawMessage( - java.lang.String value) { + String value) { if (value == null) { throw new NullPointerException(); } @@ -1437,13 +1437,13 @@ public Builder setRawMessageBytes( onChanged(); return this; } - @java.lang.Override + @Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); } - @java.lang.Override + @Override public final Builder mergeUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.mergeUnknownFields(unknownFields); @@ -1454,18 +1454,18 @@ public final Builder mergeUnknownFields( } // @@protoc_insertion_point(class_scope:io.apicurio.tests.protobuf.Header) - private static final io.apicurio.tests.protobuf.Header DEFAULT_INSTANCE; + private static final Header DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.apicurio.tests.protobuf.Header(); + DEFAULT_INSTANCE = new Header(); } - public static io.apicurio.tests.protobuf.Header getDefaultInstance() { + public static Header getDefaultInstance() { return DEFAULT_INSTANCE; } private static final com.google.protobuf.Parser
PARSER = new com.google.protobuf.AbstractParser
() { - @java.lang.Override + @Override public Header parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) @@ -1478,13 +1478,13 @@ public static com.google.protobuf.Parser
parser() { return PARSER; } - @java.lang.Override + @Override public com.google.protobuf.Parser
getParserForType() { return PARSER; } - @java.lang.Override - public io.apicurio.tests.protobuf.Header getDefaultInstanceForType() { + @Override + public Header getDefaultInstanceForType() { return DEFAULT_INSTANCE; } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/HeaderOrBuilder.java b/integration-tests/src/test/java/io/apicurio/tests/protobuf/HeaderOrBuilder.java similarity index 91% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/HeaderOrBuilder.java rename to integration-tests/src/test/java/io/apicurio/tests/protobuf/HeaderOrBuilder.java index 01fe1c2aa1..b1944ceac2 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/HeaderOrBuilder.java +++ b/integration-tests/src/test/java/io/apicurio/tests/protobuf/HeaderOrBuilder.java @@ -26,7 +26,7 @@ public interface HeaderOrBuilder extends * string source = 2; * @return The source. */ - java.lang.String getSource(); + String getSource(); /** * string source = 2; * @return The bytes for source. @@ -38,7 +38,7 @@ public interface HeaderOrBuilder extends * string destination = 3; * @return The destination. */ - java.lang.String getDestination(); + String getDestination(); /** * string destination = 3; * @return The bytes for destination. @@ -50,7 +50,7 @@ public interface HeaderOrBuilder extends * string uuid = 4; * @return The uuid. */ - java.lang.String getUuid(); + String getUuid(); /** * string uuid = 4; * @return The bytes for uuid. @@ -62,7 +62,7 @@ public interface HeaderOrBuilder extends * repeated string source_uuids = 5; * @return A list containing the sourceUuids. */ - java.util.List + java.util.List getSourceUuidsList(); /** * repeated string source_uuids = 5; @@ -74,7 +74,7 @@ public interface HeaderOrBuilder extends * @param index The index of the element to return. * @return The sourceUuids at the given index. */ - java.lang.String getSourceUuids(int index); + String getSourceUuids(int index); /** * repeated string source_uuids = 5; * @param index The index of the value to return. @@ -87,7 +87,7 @@ public interface HeaderOrBuilder extends * string message_type_id = 6; * @return The messageTypeId. */ - java.lang.String getMessageTypeId(); + String getMessageTypeId(); /** * string message_type_id = 6; * @return The bytes for messageTypeId. @@ -99,7 +99,7 @@ public interface HeaderOrBuilder extends * string raw_message = 7; * @return The rawMessage. */ - java.lang.String getRawMessage(); + String getRawMessage(); /** * string raw_message = 7; * @return The bytes for rawMessage. diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/Point.java b/integration-tests/src/test/java/io/apicurio/tests/protobuf/Point.java similarity index 77% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/Point.java rename to integration-tests/src/test/java/io/apicurio/tests/protobuf/Point.java index 05a6df3d00..00f9b0e26c 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/Point.java +++ b/integration-tests/src/test/java/io/apicurio/tests/protobuf/Point.java @@ -9,7 +9,7 @@ public final class Point extends com.google.protobuf.GeneratedMessageV3 implements // @@protoc_insertion_point(message_implements:io.apicurio.tests.protobuf.Point) - PointOrBuilder { + PointOrBuilder { private static final long serialVersionUID = 0L; // Use Point.newBuilder() to construct. private Point(com.google.protobuf.GeneratedMessageV3.Builder builder) { @@ -18,14 +18,14 @@ private Point(com.google.protobuf.GeneratedMessageV3.Builder builder) { private Point() { } - @java.lang.Override + @Override @SuppressWarnings({"unused"}) - protected java.lang.Object newInstance( + protected Object newInstance( UnusedPrivateParameter unused) { return new Point(); } - @java.lang.Override + @Override public final com.google.protobuf.UnknownFieldSet getUnknownFields() { return this.unknownFields; @@ -36,7 +36,7 @@ private Point( throws com.google.protobuf.InvalidProtocolBufferException { this(); if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); + throw new NullPointerException(); } com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet.newBuilder(); @@ -84,22 +84,22 @@ private Point( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_Point_descriptor; + return Testmessage.internal_static_io_apicurio_tests_protobuf_Point_descriptor; } - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + @Override + protected FieldAccessorTable internalGetFieldAccessorTable() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_Point_fieldAccessorTable + return Testmessage.internal_static_io_apicurio_tests_protobuf_Point_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.apicurio.tests.protobuf.Point.class, io.apicurio.tests.protobuf.Point.Builder.class); + Point.class, Builder.class); } private int longitudeOneofCase_ = 0; - private java.lang.Object longitudeOneof_; + private Object longitudeOneof_; public enum LongitudeOneofCase implements com.google.protobuf.Internal.EnumLite, - com.google.protobuf.AbstractMessage.InternalOneOfEnum { + InternalOneOfEnum { LONGITUDE(1), LONGITUDEONEOF_NOT_SET(0); private final int value; @@ -111,7 +111,7 @@ private LongitudeOneofCase(int value) { * @return The enum associated with the given number. * @deprecated Use {@link #forNumber(int)} instead. */ - @java.lang.Deprecated + @Deprecated public static LongitudeOneofCase valueOf(int value) { return forNumber(value); } @@ -135,10 +135,10 @@ public int getNumber() { } private int latitudeOneofCase_ = 0; - private java.lang.Object latitudeOneof_; + private Object latitudeOneof_; public enum LatitudeOneofCase implements com.google.protobuf.Internal.EnumLite, - com.google.protobuf.AbstractMessage.InternalOneOfEnum { + InternalOneOfEnum { LATITUDE(2), LATITUDEONEOF_NOT_SET(0); private final int value; @@ -150,7 +150,7 @@ private LatitudeOneofCase(int value) { * @return The enum associated with the given number. * @deprecated Use {@link #forNumber(int)} instead. */ - @java.lang.Deprecated + @Deprecated public static LatitudeOneofCase valueOf(int value) { return forNumber(value); } @@ -174,10 +174,10 @@ public int getNumber() { } private int altitudeOneofCase_ = 0; - private java.lang.Object altitudeOneof_; + private Object altitudeOneof_; public enum AltitudeOneofCase implements com.google.protobuf.Internal.EnumLite, - com.google.protobuf.AbstractMessage.InternalOneOfEnum { + InternalOneOfEnum { ALTITUDE(3), ALTITUDEONEOF_NOT_SET(0); private final int value; @@ -189,7 +189,7 @@ private AltitudeOneofCase(int value) { * @return The enum associated with the given number. * @deprecated Use {@link #forNumber(int)} instead. */ - @java.lang.Deprecated + @Deprecated public static AltitudeOneofCase valueOf(int value) { return forNumber(value); } @@ -217,7 +217,7 @@ public int getNumber() { * double longitude = 1; * @return Whether the longitude field is set. */ - @java.lang.Override + @Override public boolean hasLongitude() { return longitudeOneofCase_ == 1; } @@ -225,10 +225,10 @@ public boolean hasLongitude() { * double longitude = 1; * @return The longitude. */ - @java.lang.Override + @Override public double getLongitude() { if (longitudeOneofCase_ == 1) { - return (java.lang.Double) longitudeOneof_; + return (Double) longitudeOneof_; } return 0D; } @@ -238,7 +238,7 @@ public double getLongitude() { * double latitude = 2; * @return Whether the latitude field is set. */ - @java.lang.Override + @Override public boolean hasLatitude() { return latitudeOneofCase_ == 2; } @@ -246,10 +246,10 @@ public boolean hasLatitude() { * double latitude = 2; * @return The latitude. */ - @java.lang.Override + @Override public double getLatitude() { if (latitudeOneofCase_ == 2) { - return (java.lang.Double) latitudeOneof_; + return (Double) latitudeOneof_; } return 0D; } @@ -259,7 +259,7 @@ public double getLatitude() { * double altitude = 3; * @return Whether the altitude field is set. */ - @java.lang.Override + @Override public boolean hasAltitude() { return altitudeOneofCase_ == 3; } @@ -267,16 +267,16 @@ public boolean hasAltitude() { * double altitude = 3; * @return The altitude. */ - @java.lang.Override + @Override public double getAltitude() { if (altitudeOneofCase_ == 3) { - return (java.lang.Double) altitudeOneof_; + return (Double) altitudeOneof_; } return 0D; } private byte memoizedIsInitialized = -1; - @java.lang.Override + @Override public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; @@ -286,25 +286,25 @@ public final boolean isInitialized() { return true; } - @java.lang.Override + @Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (longitudeOneofCase_ == 1) { output.writeDouble( - 1, (double)((java.lang.Double) longitudeOneof_)); + 1, (double)((Double) longitudeOneof_)); } if (latitudeOneofCase_ == 2) { output.writeDouble( - 2, (double)((java.lang.Double) latitudeOneof_)); + 2, (double)((Double) latitudeOneof_)); } if (altitudeOneofCase_ == 3) { output.writeDouble( - 3, (double)((java.lang.Double) altitudeOneof_)); + 3, (double)((Double) altitudeOneof_)); } unknownFields.writeTo(output); } - @java.lang.Override + @Override public int getSerializedSize() { int size = memoizedSize; if (size != -1) return size; @@ -313,38 +313,38 @@ public int getSerializedSize() { if (longitudeOneofCase_ == 1) { size += com.google.protobuf.CodedOutputStream .computeDoubleSize( - 1, (double)((java.lang.Double) longitudeOneof_)); + 1, (double)((Double) longitudeOneof_)); } if (latitudeOneofCase_ == 2) { size += com.google.protobuf.CodedOutputStream .computeDoubleSize( - 2, (double)((java.lang.Double) latitudeOneof_)); + 2, (double)((Double) latitudeOneof_)); } if (altitudeOneofCase_ == 3) { size += com.google.protobuf.CodedOutputStream .computeDoubleSize( - 3, (double)((java.lang.Double) altitudeOneof_)); + 3, (double)((Double) altitudeOneof_)); } size += unknownFields.getSerializedSize(); memoizedSize = size; return size; } - @java.lang.Override - public boolean equals(final java.lang.Object obj) { + @Override + public boolean equals(final Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.apicurio.tests.protobuf.Point)) { + if (!(obj instanceof Point)) { return super.equals(obj); } - io.apicurio.tests.protobuf.Point other = (io.apicurio.tests.protobuf.Point) obj; + Point other = (Point) obj; if (!getLongitudeOneofCase().equals(other.getLongitudeOneofCase())) return false; switch (longitudeOneofCase_) { case 1: - if (java.lang.Double.doubleToLongBits(getLongitude()) - != java.lang.Double.doubleToLongBits( + if (Double.doubleToLongBits(getLongitude()) + != Double.doubleToLongBits( other.getLongitude())) return false; break; case 0: @@ -353,8 +353,8 @@ public boolean equals(final java.lang.Object obj) { if (!getLatitudeOneofCase().equals(other.getLatitudeOneofCase())) return false; switch (latitudeOneofCase_) { case 2: - if (java.lang.Double.doubleToLongBits(getLatitude()) - != java.lang.Double.doubleToLongBits( + if (Double.doubleToLongBits(getLatitude()) + != Double.doubleToLongBits( other.getLatitude())) return false; break; case 0: @@ -363,8 +363,8 @@ public boolean equals(final java.lang.Object obj) { if (!getAltitudeOneofCase().equals(other.getAltitudeOneofCase())) return false; switch (altitudeOneofCase_) { case 3: - if (java.lang.Double.doubleToLongBits(getAltitude()) - != java.lang.Double.doubleToLongBits( + if (Double.doubleToLongBits(getAltitude()) + != Double.doubleToLongBits( other.getAltitude())) return false; break; case 0: @@ -374,7 +374,7 @@ public boolean equals(final java.lang.Object obj) { return true; } - @java.lang.Override + @Override public int hashCode() { if (memoizedHashCode != 0) { return memoizedHashCode; @@ -385,7 +385,7 @@ public int hashCode() { case 1: hash = (37 * hash) + LONGITUDE_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashLong( - java.lang.Double.doubleToLongBits(getLongitude())); + Double.doubleToLongBits(getLongitude())); break; case 0: default: @@ -394,7 +394,7 @@ public int hashCode() { case 2: hash = (37 * hash) + LATITUDE_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashLong( - java.lang.Double.doubleToLongBits(getLatitude())); + Double.doubleToLongBits(getLatitude())); break; case 0: default: @@ -403,7 +403,7 @@ public int hashCode() { case 3: hash = (37 * hash) + ALTITUDE_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashLong( - java.lang.Double.doubleToLongBits(getAltitude())); + Double.doubleToLongBits(getAltitude())); break; case 0: default: @@ -413,69 +413,69 @@ public int hashCode() { return hash; } - public static io.apicurio.tests.protobuf.Point parseFrom( + public static Point parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.apicurio.tests.protobuf.Point parseFrom( + public static Point parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.apicurio.tests.protobuf.Point parseFrom( + public static Point parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.apicurio.tests.protobuf.Point parseFrom( + public static Point parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.apicurio.tests.protobuf.Point parseFrom(byte[] data) + public static Point parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.apicurio.tests.protobuf.Point parseFrom( + public static Point parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.apicurio.tests.protobuf.Point parseFrom(java.io.InputStream input) + public static Point parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static io.apicurio.tests.protobuf.Point parseFrom( + public static Point parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.apicurio.tests.protobuf.Point parseDelimitedFrom(java.io.InputStream input) + public static Point parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static io.apicurio.tests.protobuf.Point parseDelimitedFrom( + public static Point parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.apicurio.tests.protobuf.Point parseFrom( + public static Point parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static io.apicurio.tests.protobuf.Point parseFrom( + public static Point parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -483,23 +483,23 @@ public static io.apicurio.tests.protobuf.Point parseFrom( .parseWithIOException(PARSER, input, extensionRegistry); } - @java.lang.Override + @Override public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.apicurio.tests.protobuf.Point prototype) { + public static Builder newBuilder(Point prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } - @java.lang.Override + @Override public Builder toBuilder() { return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); } - @java.lang.Override + @Override protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + BuilderParent parent) { Builder builder = new Builder(parent); return builder; } @@ -509,18 +509,18 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements // @@protoc_insertion_point(builder_implements:io.apicurio.tests.protobuf.Point) - io.apicurio.tests.protobuf.PointOrBuilder { + PointOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_Point_descriptor; + return Testmessage.internal_static_io_apicurio_tests_protobuf_Point_descriptor; } - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + @Override + protected FieldAccessorTable internalGetFieldAccessorTable() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_Point_fieldAccessorTable + return Testmessage.internal_static_io_apicurio_tests_protobuf_Point_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.apicurio.tests.protobuf.Point.class, io.apicurio.tests.protobuf.Point.Builder.class); + Point.class, Builder.class); } // Construct using io.apicurio.tests.protobuf.Point.newBuilder() @@ -529,7 +529,7 @@ private Builder() { } private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + BuilderParent parent) { super(parent); maybeForceBuilderInitialization(); } @@ -538,7 +538,7 @@ private void maybeForceBuilderInitialization() { .alwaysUseFieldBuilders) { } } - @java.lang.Override + @Override public Builder clear() { super.clear(); longitudeOneofCase_ = 0; @@ -550,29 +550,29 @@ public Builder clear() { return this; } - @java.lang.Override + @Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_Point_descriptor; + return Testmessage.internal_static_io_apicurio_tests_protobuf_Point_descriptor; } - @java.lang.Override - public io.apicurio.tests.protobuf.Point getDefaultInstanceForType() { - return io.apicurio.tests.protobuf.Point.getDefaultInstance(); + @Override + public Point getDefaultInstanceForType() { + return Point.getDefaultInstance(); } - @java.lang.Override - public io.apicurio.tests.protobuf.Point build() { - io.apicurio.tests.protobuf.Point result = buildPartial(); + @Override + public Point build() { + Point result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } - @java.lang.Override - public io.apicurio.tests.protobuf.Point buildPartial() { - io.apicurio.tests.protobuf.Point result = new io.apicurio.tests.protobuf.Point(this); + @Override + public Point buildPartial() { + Point result = new Point(this); if (longitudeOneofCase_ == 1) { result.longitudeOneof_ = longitudeOneof_; } @@ -589,50 +589,50 @@ public io.apicurio.tests.protobuf.Point buildPartial() { return result; } - @java.lang.Override + @Override public Builder clone() { return super.clone(); } - @java.lang.Override + @Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { + Object value) { return super.setField(field, value); } - @java.lang.Override + @Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { return super.clearField(field); } - @java.lang.Override + @Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { return super.clearOneof(oneof); } - @java.lang.Override + @Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { + int index, Object value) { return super.setRepeatedField(field, index, value); } - @java.lang.Override + @Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { + Object value) { return super.addRepeatedField(field, value); } - @java.lang.Override + @Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.apicurio.tests.protobuf.Point) { - return mergeFrom((io.apicurio.tests.protobuf.Point)other); + if (other instanceof Point) { + return mergeFrom((Point)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.apicurio.tests.protobuf.Point other) { - if (other == io.apicurio.tests.protobuf.Point.getDefaultInstance()) return this; + public Builder mergeFrom(Point other) { + if (other == Point.getDefaultInstance()) return this; switch (other.getLongitudeOneofCase()) { case LONGITUDE: { setLongitude(other.getLongitude()); @@ -665,21 +665,21 @@ public Builder mergeFrom(io.apicurio.tests.protobuf.Point other) { return this; } - @java.lang.Override + @Override public final boolean isInitialized() { return true; } - @java.lang.Override + @Override public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - io.apicurio.tests.protobuf.Point parsedMessage = null; + Point parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (io.apicurio.tests.protobuf.Point) e.getUnfinishedMessage(); + parsedMessage = (Point) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -689,7 +689,7 @@ public Builder mergeFrom( return this; } private int longitudeOneofCase_ = 0; - private java.lang.Object longitudeOneof_; + private Object longitudeOneof_; public LongitudeOneofCase getLongitudeOneofCase() { return LongitudeOneofCase.forNumber( @@ -704,7 +704,7 @@ public Builder clearLongitudeOneof() { } private int latitudeOneofCase_ = 0; - private java.lang.Object latitudeOneof_; + private Object latitudeOneof_; public LatitudeOneofCase getLatitudeOneofCase() { return LatitudeOneofCase.forNumber( @@ -719,7 +719,7 @@ public Builder clearLatitudeOneof() { } private int altitudeOneofCase_ = 0; - private java.lang.Object altitudeOneof_; + private Object altitudeOneof_; public AltitudeOneofCase getAltitudeOneofCase() { return AltitudeOneofCase.forNumber( @@ -747,7 +747,7 @@ public boolean hasLongitude() { */ public double getLongitude() { if (longitudeOneofCase_ == 1) { - return (java.lang.Double) longitudeOneof_; + return (Double) longitudeOneof_; } return 0D; } @@ -788,7 +788,7 @@ public boolean hasLatitude() { */ public double getLatitude() { if (latitudeOneofCase_ == 2) { - return (java.lang.Double) latitudeOneof_; + return (Double) latitudeOneof_; } return 0D; } @@ -829,7 +829,7 @@ public boolean hasAltitude() { */ public double getAltitude() { if (altitudeOneofCase_ == 3) { - return (java.lang.Double) altitudeOneof_; + return (Double) altitudeOneof_; } return 0D; } @@ -856,13 +856,13 @@ public Builder clearAltitude() { } return this; } - @java.lang.Override + @Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); } - @java.lang.Override + @Override public final Builder mergeUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.mergeUnknownFields(unknownFields); @@ -873,18 +873,18 @@ public final Builder mergeUnknownFields( } // @@protoc_insertion_point(class_scope:io.apicurio.tests.protobuf.Point) - private static final io.apicurio.tests.protobuf.Point DEFAULT_INSTANCE; + private static final Point DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.apicurio.tests.protobuf.Point(); + DEFAULT_INSTANCE = new Point(); } - public static io.apicurio.tests.protobuf.Point getDefaultInstance() { + public static Point getDefaultInstance() { return DEFAULT_INSTANCE; } private static final com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override + @Override public Point parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) @@ -897,13 +897,13 @@ public static com.google.protobuf.Parser parser() { return PARSER; } - @java.lang.Override + @Override public com.google.protobuf.Parser getParserForType() { return PARSER; } - @java.lang.Override - public io.apicurio.tests.protobuf.Point getDefaultInstanceForType() { + @Override + public Point getDefaultInstanceForType() { return DEFAULT_INSTANCE; } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/PointOrBuilder.java b/integration-tests/src/test/java/io/apicurio/tests/protobuf/PointOrBuilder.java similarity index 80% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/PointOrBuilder.java rename to integration-tests/src/test/java/io/apicurio/tests/protobuf/PointOrBuilder.java index 92ff0e6a75..9e766f511e 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/PointOrBuilder.java +++ b/integration-tests/src/test/java/io/apicurio/tests/protobuf/PointOrBuilder.java @@ -40,9 +40,9 @@ public interface PointOrBuilder extends */ double getAltitude(); - public io.apicurio.tests.protobuf.Point.LongitudeOneofCase getLongitudeOneofCase(); + public Point.LongitudeOneofCase getLongitudeOneofCase(); - public io.apicurio.tests.protobuf.Point.LatitudeOneofCase getLatitudeOneofCase(); + public Point.LatitudeOneofCase getLatitudeOneofCase(); - public io.apicurio.tests.protobuf.Point.AltitudeOneofCase getAltitudeOneofCase(); + public Point.AltitudeOneofCase getAltitudeOneofCase(); } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessage.java b/integration-tests/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessage.java similarity index 81% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessage.java rename to integration-tests/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessage.java index 915a4d8f4d..c42a24e044 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessage.java +++ b/integration-tests/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessage.java @@ -9,7 +9,7 @@ public final class ProtobufTestMessage extends com.google.protobuf.GeneratedMessageV3 implements // @@protoc_insertion_point(message_implements:io.apicurio.tests.protobuf.ProtobufTestMessage) - ProtobufTestMessageOrBuilder { + ProtobufTestMessageOrBuilder { private static final long serialVersionUID = 0L; // Use ProtobufTestMessage.newBuilder() to construct. private ProtobufTestMessage(com.google.protobuf.GeneratedMessageV3.Builder builder) { @@ -19,14 +19,14 @@ private ProtobufTestMessage() { s1_ = ""; } - @java.lang.Override + @Override @SuppressWarnings({"unused"}) - protected java.lang.Object newInstance( + protected Object newInstance( UnusedPrivateParameter unused) { return new ProtobufTestMessage(); } - @java.lang.Override + @Override public final com.google.protobuf.UnknownFieldSet getUnknownFields() { return this.unknownFields; @@ -37,7 +37,7 @@ private ProtobufTestMessage( throws com.google.protobuf.InvalidProtocolBufferException { this(); if (extensionRegistry == null) { - throw new java.lang.NullPointerException(); + throw new NullPointerException(); } com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet.newBuilder(); @@ -50,11 +50,11 @@ private ProtobufTestMessage( done = true; break; case 10: { - io.apicurio.tests.protobuf.Header.Builder subBuilder = null; + Header.Builder subBuilder = null; if (header_ != null) { subBuilder = header_.toBuilder(); } - header_ = input.readMessage(io.apicurio.tests.protobuf.Header.parser(), extensionRegistry); + header_ = input.readMessage(Header.parser(), extensionRegistry); if (subBuilder != null) { subBuilder.mergeFrom(header_); header_ = subBuilder.buildPartial(); @@ -68,7 +68,7 @@ private ProtobufTestMessage( break; } case 34: { - java.lang.String s = input.readStringRequireUtf8(); + String s = input.readStringRequireUtf8(); s1_ = s; break; @@ -130,24 +130,24 @@ private ProtobufTestMessage( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_ProtobufTestMessage_descriptor; + return Testmessage.internal_static_io_apicurio_tests_protobuf_ProtobufTestMessage_descriptor; } - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + @Override + protected FieldAccessorTable internalGetFieldAccessorTable() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_ProtobufTestMessage_fieldAccessorTable + return Testmessage.internal_static_io_apicurio_tests_protobuf_ProtobufTestMessage_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.apicurio.tests.protobuf.ProtobufTestMessage.class, io.apicurio.tests.protobuf.ProtobufTestMessage.Builder.class); + ProtobufTestMessage.class, Builder.class); } public static final int HEADER_FIELD_NUMBER = 1; - private io.apicurio.tests.protobuf.Header header_; + private Header header_; /** * .io.apicurio.tests.protobuf.Header header = 1; * @return Whether the header field is set. */ - @java.lang.Override + @Override public boolean hasHeader() { return header_ != null; } @@ -155,14 +155,14 @@ public boolean hasHeader() { * .io.apicurio.tests.protobuf.Header header = 1; * @return The header. */ - @java.lang.Override - public io.apicurio.tests.protobuf.Header getHeader() { - return header_ == null ? io.apicurio.tests.protobuf.Header.getDefaultInstance() : header_; + @Override + public Header getHeader() { + return header_ == null ? Header.getDefaultInstance() : header_; } /** * .io.apicurio.tests.protobuf.Header header = 1; */ - @java.lang.Override + @Override public io.apicurio.tests.protobuf.HeaderOrBuilder getHeaderOrBuilder() { return getHeader(); } @@ -173,26 +173,26 @@ public io.apicurio.tests.protobuf.HeaderOrBuilder getHeaderOrBuilder() { * double d1 = 2; * @return The d1. */ - @java.lang.Override + @Override public double getD1() { return d1_; } public static final int S1_FIELD_NUMBER = 4; - private volatile java.lang.Object s1_; + private volatile Object s1_; /** * string s1 = 4; * @return The s1. */ - @java.lang.Override - public java.lang.String getS1() { - java.lang.Object ref = s1_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; + @Override + public String getS1() { + Object ref = s1_; + if (ref instanceof String) { + return (String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); s1_ = s; return s; } @@ -201,14 +201,14 @@ public java.lang.String getS1() { * string s1 = 4; * @return The bytes for s1. */ - @java.lang.Override + @Override public com.google.protobuf.ByteString getS1Bytes() { - java.lang.Object ref = s1_; - if (ref instanceof java.lang.String) { + Object ref = s1_; + if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); s1_ = b; return b; } else { @@ -222,7 +222,7 @@ public java.lang.String getS1() { * int32 i1 = 7; * @return The i1. */ - @java.lang.Override + @Override public int getI1() { return i1_; } @@ -233,7 +233,7 @@ public int getI1() { * int64 bi1 = 12; * @return The bi1. */ - @java.lang.Override + @Override public long getBi1() { return bi1_; } @@ -244,7 +244,7 @@ public long getBi1() { * .google.protobuf.Timestamp state_time = 22; * @return Whether the stateTime field is set. */ - @java.lang.Override + @Override public boolean hasStateTime() { return stateTime_ != null; } @@ -252,14 +252,14 @@ public boolean hasStateTime() { * .google.protobuf.Timestamp state_time = 22; * @return The stateTime. */ - @java.lang.Override + @Override public com.google.protobuf.Timestamp getStateTime() { return stateTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : stateTime_; } /** * .google.protobuf.Timestamp state_time = 22; */ - @java.lang.Override + @Override public com.google.protobuf.TimestampOrBuilder getStateTimeOrBuilder() { return getStateTime(); } @@ -270,7 +270,7 @@ public com.google.protobuf.TimestampOrBuilder getStateTimeOrBuilder() { * .io.apicurio.tests.protobuf.Point point = 30; * @return Whether the point field is set. */ - @java.lang.Override + @Override public boolean hasPoint() { return point_ != null; } @@ -278,20 +278,20 @@ public boolean hasPoint() { * .io.apicurio.tests.protobuf.Point point = 30; * @return The point. */ - @java.lang.Override + @Override public io.apicurio.tests.protobuf.Point getPoint() { return point_ == null ? io.apicurio.tests.protobuf.Point.getDefaultInstance() : point_; } /** * .io.apicurio.tests.protobuf.Point point = 30; */ - @java.lang.Override + @Override public io.apicurio.tests.protobuf.PointOrBuilder getPointOrBuilder() { return getPoint(); } private byte memoizedIsInitialized = -1; - @java.lang.Override + @Override public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; @@ -301,7 +301,7 @@ public final boolean isInitialized() { return true; } - @java.lang.Override + @Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (header_ != null) { @@ -328,7 +328,7 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) unknownFields.writeTo(output); } - @java.lang.Override + @Override public int getSerializedSize() { int size = memoizedSize; if (size != -1) return size; @@ -366,23 +366,23 @@ public int getSerializedSize() { return size; } - @java.lang.Override - public boolean equals(final java.lang.Object obj) { + @Override + public boolean equals(final Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.apicurio.tests.protobuf.ProtobufTestMessage)) { + if (!(obj instanceof ProtobufTestMessage)) { return super.equals(obj); } - io.apicurio.tests.protobuf.ProtobufTestMessage other = (io.apicurio.tests.protobuf.ProtobufTestMessage) obj; + ProtobufTestMessage other = (ProtobufTestMessage) obj; if (hasHeader() != other.hasHeader()) return false; if (hasHeader()) { if (!getHeader() .equals(other.getHeader())) return false; } - if (java.lang.Double.doubleToLongBits(getD1()) - != java.lang.Double.doubleToLongBits( + if (Double.doubleToLongBits(getD1()) + != Double.doubleToLongBits( other.getD1())) return false; if (!getS1() .equals(other.getS1())) return false; @@ -404,7 +404,7 @@ public boolean equals(final java.lang.Object obj) { return true; } - @java.lang.Override + @Override public int hashCode() { if (memoizedHashCode != 0) { return memoizedHashCode; @@ -417,7 +417,7 @@ public int hashCode() { } hash = (37 * hash) + D1_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashLong( - java.lang.Double.doubleToLongBits(getD1())); + Double.doubleToLongBits(getD1())); hash = (37 * hash) + S1_FIELD_NUMBER; hash = (53 * hash) + getS1().hashCode(); hash = (37 * hash) + I1_FIELD_NUMBER; @@ -438,69 +438,69 @@ public int hashCode() { return hash; } - public static io.apicurio.tests.protobuf.ProtobufTestMessage parseFrom( + public static ProtobufTestMessage parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.apicurio.tests.protobuf.ProtobufTestMessage parseFrom( + public static ProtobufTestMessage parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.apicurio.tests.protobuf.ProtobufTestMessage parseFrom( + public static ProtobufTestMessage parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.apicurio.tests.protobuf.ProtobufTestMessage parseFrom( + public static ProtobufTestMessage parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.apicurio.tests.protobuf.ProtobufTestMessage parseFrom(byte[] data) + public static ProtobufTestMessage parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.apicurio.tests.protobuf.ProtobufTestMessage parseFrom( + public static ProtobufTestMessage parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.apicurio.tests.protobuf.ProtobufTestMessage parseFrom(java.io.InputStream input) + public static ProtobufTestMessage parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static io.apicurio.tests.protobuf.ProtobufTestMessage parseFrom( + public static ProtobufTestMessage parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.apicurio.tests.protobuf.ProtobufTestMessage parseDelimitedFrom(java.io.InputStream input) + public static ProtobufTestMessage parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static io.apicurio.tests.protobuf.ProtobufTestMessage parseDelimitedFrom( + public static ProtobufTestMessage parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.apicurio.tests.protobuf.ProtobufTestMessage parseFrom( + public static ProtobufTestMessage parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static io.apicurio.tests.protobuf.ProtobufTestMessage parseFrom( + public static ProtobufTestMessage parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -508,23 +508,23 @@ public static io.apicurio.tests.protobuf.ProtobufTestMessage parseFrom( .parseWithIOException(PARSER, input, extensionRegistry); } - @java.lang.Override + @Override public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.apicurio.tests.protobuf.ProtobufTestMessage prototype) { + public static Builder newBuilder(ProtobufTestMessage prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } - @java.lang.Override + @Override public Builder toBuilder() { return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); } - @java.lang.Override + @Override protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + BuilderParent parent) { Builder builder = new Builder(parent); return builder; } @@ -534,18 +534,18 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder implements // @@protoc_insertion_point(builder_implements:io.apicurio.tests.protobuf.ProtobufTestMessage) - io.apicurio.tests.protobuf.ProtobufTestMessageOrBuilder { + ProtobufTestMessageOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_ProtobufTestMessage_descriptor; + return Testmessage.internal_static_io_apicurio_tests_protobuf_ProtobufTestMessage_descriptor; } - @java.lang.Override - protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + @Override + protected FieldAccessorTable internalGetFieldAccessorTable() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_ProtobufTestMessage_fieldAccessorTable + return Testmessage.internal_static_io_apicurio_tests_protobuf_ProtobufTestMessage_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.apicurio.tests.protobuf.ProtobufTestMessage.class, io.apicurio.tests.protobuf.ProtobufTestMessage.Builder.class); + ProtobufTestMessage.class, Builder.class); } // Construct using io.apicurio.tests.protobuf.ProtobufTestMessage.newBuilder() @@ -554,7 +554,7 @@ private Builder() { } private Builder( - com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + BuilderParent parent) { super(parent); maybeForceBuilderInitialization(); } @@ -563,7 +563,7 @@ private void maybeForceBuilderInitialization() { .alwaysUseFieldBuilders) { } } - @java.lang.Override + @Override public Builder clear() { super.clear(); if (headerBuilder_ == null) { @@ -595,29 +595,29 @@ public Builder clear() { return this; } - @java.lang.Override + @Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.apicurio.tests.protobuf.Testmessage.internal_static_io_apicurio_tests_protobuf_ProtobufTestMessage_descriptor; + return Testmessage.internal_static_io_apicurio_tests_protobuf_ProtobufTestMessage_descriptor; } - @java.lang.Override - public io.apicurio.tests.protobuf.ProtobufTestMessage getDefaultInstanceForType() { - return io.apicurio.tests.protobuf.ProtobufTestMessage.getDefaultInstance(); + @Override + public ProtobufTestMessage getDefaultInstanceForType() { + return ProtobufTestMessage.getDefaultInstance(); } - @java.lang.Override - public io.apicurio.tests.protobuf.ProtobufTestMessage build() { - io.apicurio.tests.protobuf.ProtobufTestMessage result = buildPartial(); + @Override + public ProtobufTestMessage build() { + ProtobufTestMessage result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } - @java.lang.Override - public io.apicurio.tests.protobuf.ProtobufTestMessage buildPartial() { - io.apicurio.tests.protobuf.ProtobufTestMessage result = new io.apicurio.tests.protobuf.ProtobufTestMessage(this); + @Override + public ProtobufTestMessage buildPartial() { + ProtobufTestMessage result = new ProtobufTestMessage(this); if (headerBuilder_ == null) { result.header_ = header_; } else { @@ -641,50 +641,50 @@ public io.apicurio.tests.protobuf.ProtobufTestMessage buildPartial() { return result; } - @java.lang.Override + @Override public Builder clone() { return super.clone(); } - @java.lang.Override + @Override public Builder setField( com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { + Object value) { return super.setField(field, value); } - @java.lang.Override + @Override public Builder clearField( com.google.protobuf.Descriptors.FieldDescriptor field) { return super.clearField(field); } - @java.lang.Override + @Override public Builder clearOneof( com.google.protobuf.Descriptors.OneofDescriptor oneof) { return super.clearOneof(oneof); } - @java.lang.Override + @Override public Builder setRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, - int index, java.lang.Object value) { + int index, Object value) { return super.setRepeatedField(field, index, value); } - @java.lang.Override + @Override public Builder addRepeatedField( com.google.protobuf.Descriptors.FieldDescriptor field, - java.lang.Object value) { + Object value) { return super.addRepeatedField(field, value); } - @java.lang.Override + @Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.apicurio.tests.protobuf.ProtobufTestMessage) { - return mergeFrom((io.apicurio.tests.protobuf.ProtobufTestMessage)other); + if (other instanceof ProtobufTestMessage) { + return mergeFrom((ProtobufTestMessage)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.apicurio.tests.protobuf.ProtobufTestMessage other) { - if (other == io.apicurio.tests.protobuf.ProtobufTestMessage.getDefaultInstance()) return this; + public Builder mergeFrom(ProtobufTestMessage other) { + if (other == ProtobufTestMessage.getDefaultInstance()) return this; if (other.hasHeader()) { mergeHeader(other.getHeader()); } @@ -712,21 +712,21 @@ public Builder mergeFrom(io.apicurio.tests.protobuf.ProtobufTestMessage other) { return this; } - @java.lang.Override + @Override public final boolean isInitialized() { return true; } - @java.lang.Override + @Override public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - io.apicurio.tests.protobuf.ProtobufTestMessage parsedMessage = null; + ProtobufTestMessage parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (io.apicurio.tests.protobuf.ProtobufTestMessage) e.getUnfinishedMessage(); + parsedMessage = (ProtobufTestMessage) e.getUnfinishedMessage(); throw e.unwrapIOException(); } finally { if (parsedMessage != null) { @@ -736,9 +736,9 @@ public Builder mergeFrom( return this; } - private io.apicurio.tests.protobuf.Header header_; + private Header header_; private com.google.protobuf.SingleFieldBuilderV3< - io.apicurio.tests.protobuf.Header, io.apicurio.tests.protobuf.Header.Builder, io.apicurio.tests.protobuf.HeaderOrBuilder> headerBuilder_; + Header, Header.Builder, io.apicurio.tests.protobuf.HeaderOrBuilder> headerBuilder_; /** * .io.apicurio.tests.protobuf.Header header = 1; * @return Whether the header field is set. @@ -750,9 +750,9 @@ public boolean hasHeader() { * .io.apicurio.tests.protobuf.Header header = 1; * @return The header. */ - public io.apicurio.tests.protobuf.Header getHeader() { + public Header getHeader() { if (headerBuilder_ == null) { - return header_ == null ? io.apicurio.tests.protobuf.Header.getDefaultInstance() : header_; + return header_ == null ? Header.getDefaultInstance() : header_; } else { return headerBuilder_.getMessage(); } @@ -760,7 +760,7 @@ public io.apicurio.tests.protobuf.Header getHeader() { /** * .io.apicurio.tests.protobuf.Header header = 1; */ - public Builder setHeader(io.apicurio.tests.protobuf.Header value) { + public Builder setHeader(Header value) { if (headerBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -777,7 +777,7 @@ public Builder setHeader(io.apicurio.tests.protobuf.Header value) { * .io.apicurio.tests.protobuf.Header header = 1; */ public Builder setHeader( - io.apicurio.tests.protobuf.Header.Builder builderForValue) { + Header.Builder builderForValue) { if (headerBuilder_ == null) { header_ = builderForValue.build(); onChanged(); @@ -790,11 +790,11 @@ public Builder setHeader( /** * .io.apicurio.tests.protobuf.Header header = 1; */ - public Builder mergeHeader(io.apicurio.tests.protobuf.Header value) { + public Builder mergeHeader(Header value) { if (headerBuilder_ == null) { if (header_ != null) { header_ = - io.apicurio.tests.protobuf.Header.newBuilder(header_).mergeFrom(value).buildPartial(); + Header.newBuilder(header_).mergeFrom(value).buildPartial(); } else { header_ = value; } @@ -822,7 +822,7 @@ public Builder clearHeader() { /** * .io.apicurio.tests.protobuf.Header header = 1; */ - public io.apicurio.tests.protobuf.Header.Builder getHeaderBuilder() { + public Header.Builder getHeaderBuilder() { onChanged(); return getHeaderFieldBuilder().getBuilder(); @@ -835,18 +835,18 @@ public io.apicurio.tests.protobuf.HeaderOrBuilder getHeaderOrBuilder() { return headerBuilder_.getMessageOrBuilder(); } else { return header_ == null ? - io.apicurio.tests.protobuf.Header.getDefaultInstance() : header_; + Header.getDefaultInstance() : header_; } } /** * .io.apicurio.tests.protobuf.Header header = 1; */ private com.google.protobuf.SingleFieldBuilderV3< - io.apicurio.tests.protobuf.Header, io.apicurio.tests.protobuf.Header.Builder, io.apicurio.tests.protobuf.HeaderOrBuilder> + Header, Header.Builder, io.apicurio.tests.protobuf.HeaderOrBuilder> getHeaderFieldBuilder() { if (headerBuilder_ == null) { headerBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< - io.apicurio.tests.protobuf.Header, io.apicurio.tests.protobuf.Header.Builder, io.apicurio.tests.protobuf.HeaderOrBuilder>( + Header, Header.Builder, io.apicurio.tests.protobuf.HeaderOrBuilder>( getHeader(), getParentForChildren(), isClean()); @@ -860,7 +860,7 @@ public io.apicurio.tests.protobuf.HeaderOrBuilder getHeaderOrBuilder() { * double d1 = 2; * @return The d1. */ - @java.lang.Override + @Override public double getD1() { return d1_; } @@ -886,21 +886,21 @@ public Builder clearD1() { return this; } - private java.lang.Object s1_ = ""; + private Object s1_ = ""; /** * string s1 = 4; * @return The s1. */ - public java.lang.String getS1() { - java.lang.Object ref = s1_; - if (!(ref instanceof java.lang.String)) { + public String getS1() { + Object ref = s1_; + if (!(ref instanceof String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); + String s = bs.toStringUtf8(); s1_ = s; return s; } else { - return (java.lang.String) ref; + return (String) ref; } } /** @@ -909,11 +909,11 @@ public java.lang.String getS1() { */ public com.google.protobuf.ByteString getS1Bytes() { - java.lang.Object ref = s1_; + Object ref = s1_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); + (String) ref); s1_ = b; return b; } else { @@ -926,7 +926,7 @@ public java.lang.String getS1() { * @return This builder for chaining. */ public Builder setS1( - java.lang.String value) { + String value) { if (value == null) { throw new NullPointerException(); } @@ -967,7 +967,7 @@ public Builder setS1Bytes( * int32 i1 = 7; * @return The i1. */ - @java.lang.Override + @Override public int getI1() { return i1_; } @@ -998,7 +998,7 @@ public Builder clearI1() { * int64 bi1 = 12; * @return The bi1. */ - @java.lang.Override + @Override public long getBi1() { return bi1_; } @@ -1261,13 +1261,13 @@ public io.apicurio.tests.protobuf.PointOrBuilder getPointOrBuilder() { } return pointBuilder_; } - @java.lang.Override + @Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); } - @java.lang.Override + @Override public final Builder mergeUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.mergeUnknownFields(unknownFields); @@ -1278,18 +1278,18 @@ public final Builder mergeUnknownFields( } // @@protoc_insertion_point(class_scope:io.apicurio.tests.protobuf.ProtobufTestMessage) - private static final io.apicurio.tests.protobuf.ProtobufTestMessage DEFAULT_INSTANCE; + private static final ProtobufTestMessage DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.apicurio.tests.protobuf.ProtobufTestMessage(); + DEFAULT_INSTANCE = new ProtobufTestMessage(); } - public static io.apicurio.tests.protobuf.ProtobufTestMessage getDefaultInstance() { + public static ProtobufTestMessage getDefaultInstance() { return DEFAULT_INSTANCE; } private static final com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { - @java.lang.Override + @Override public ProtobufTestMessage parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) @@ -1302,13 +1302,13 @@ public static com.google.protobuf.Parser parser() { return PARSER; } - @java.lang.Override + @Override public com.google.protobuf.Parser getParserForType() { return PARSER; } - @java.lang.Override - public io.apicurio.tests.protobuf.ProtobufTestMessage getDefaultInstanceForType() { + @Override + public ProtobufTestMessage getDefaultInstanceForType() { return DEFAULT_INSTANCE; } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessageOrBuilder.java b/integration-tests/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessageOrBuilder.java similarity index 91% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessageOrBuilder.java rename to integration-tests/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessageOrBuilder.java index 0dd9eedc98..3e447168f9 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessageOrBuilder.java +++ b/integration-tests/src/test/java/io/apicurio/tests/protobuf/ProtobufTestMessageOrBuilder.java @@ -16,11 +16,11 @@ public interface ProtobufTestMessageOrBuilder extends * .io.apicurio.tests.protobuf.Header header = 1; * @return The header. */ - io.apicurio.tests.protobuf.Header getHeader(); + Header getHeader(); /** * .io.apicurio.tests.protobuf.Header header = 1; */ - io.apicurio.tests.protobuf.HeaderOrBuilder getHeaderOrBuilder(); + HeaderOrBuilder getHeaderOrBuilder(); /** * double d1 = 2; @@ -32,7 +32,7 @@ public interface ProtobufTestMessageOrBuilder extends * string s1 = 4; * @return The s1. */ - java.lang.String getS1(); + String getS1(); /** * string s1 = 4; * @return The bytes for s1. @@ -76,7 +76,7 @@ public interface ProtobufTestMessageOrBuilder extends * .io.apicurio.tests.protobuf.Point point = 30; * @return The point. */ - io.apicurio.tests.protobuf.Point getPoint(); + Point getPoint(); /** * .io.apicurio.tests.protobuf.Point point = 30; */ diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/Testmessage.java b/integration-tests/src/test/java/io/apicurio/tests/protobuf/Testmessage.java similarity index 91% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/Testmessage.java rename to integration-tests/src/test/java/io/apicurio/tests/protobuf/Testmessage.java index b1eed6cb83..641164c889 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/protobuf/Testmessage.java +++ b/integration-tests/src/test/java/io/apicurio/tests/protobuf/Testmessage.java @@ -37,7 +37,7 @@ public static void registerAllExtensions( private static com.google.protobuf.Descriptors.FileDescriptor descriptor; static { - java.lang.String[] descriptorData = { + String[] descriptorData = { "\nGintegration-tests/testsuite/src/test/r" + "esources/serdes/testmessage.proto\022\032io.ap" + "icurio.tests.protobuf\032\037google/protobuf/t" + @@ -66,19 +66,19 @@ public static void registerAllExtensions( internal_static_io_apicurio_tests_protobuf_ProtobufTestMessage_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_io_apicurio_tests_protobuf_ProtobufTestMessage_descriptor, - new java.lang.String[] { "Header", "D1", "S1", "I1", "Bi1", "StateTime", "Point", }); + new String[] { "Header", "D1", "S1", "I1", "Bi1", "StateTime", "Point", }); internal_static_io_apicurio_tests_protobuf_Header_descriptor = getDescriptor().getMessageTypes().get(1); internal_static_io_apicurio_tests_protobuf_Header_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_io_apicurio_tests_protobuf_Header_descriptor, - new java.lang.String[] { "Time", "Source", "Destination", "Uuid", "SourceUuids", "MessageTypeId", "RawMessage", }); + new String[] { "Time", "Source", "Destination", "Uuid", "SourceUuids", "MessageTypeId", "RawMessage", }); internal_static_io_apicurio_tests_protobuf_Point_descriptor = getDescriptor().getMessageTypes().get(2); internal_static_io_apicurio_tests_protobuf_Point_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_io_apicurio_tests_protobuf_Point_descriptor, - new java.lang.String[] { "Longitude", "Latitude", "Altitude", "LongitudeOneof", "LatitudeOneof", "AltitudeOneof", }); + new String[] { "Longitude", "Latitude", "Altitude", "LongitudeOneof", "LatitudeOneof", "AltitudeOneof", }); com.google.protobuf.TimestampProto.getDescriptor(); } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/AvroGenericRecordSchemaFactory.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/AvroGenericRecordSchemaFactory.java similarity index 99% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/AvroGenericRecordSchemaFactory.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/AvroGenericRecordSchemaFactory.java index ffc7a8d46d..bd2fd352cc 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/AvroGenericRecordSchemaFactory.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/AvroGenericRecordSchemaFactory.java @@ -16,20 +16,20 @@ package io.apicurio.tests.serdes.apicurio; -import static org.junit.Assert.assertTrue; +import io.apicurio.registry.utils.IoUtil; +import io.apicurio.registry.utils.tests.TestUtils; +import org.apache.avro.Schema; +import org.apache.avro.generic.GenericData; +import org.apache.avro.generic.GenericRecord; import java.io.InputStream; import java.util.List; import java.util.Objects; -import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericRecord; -import io.apicurio.registry.utils.IoUtil; -import io.apicurio.registry.utils.tests.TestUtils; +import static org.junit.Assert.assertTrue; /** - * @author Fabian Martinez + * @author Carles Arnal */ public class AvroGenericRecordSchemaFactory { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/AvroSerdeIT.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/AvroSerdeIT.java similarity index 98% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/AvroSerdeIT.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/AvroSerdeIT.java index 47b5dfd0d7..4599117377 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/AvroSerdeIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/AvroSerdeIT.java @@ -16,24 +16,10 @@ package io.apicurio.tests.serdes.apicurio; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericRecord; -import org.apache.kafka.clients.consumer.Consumer; -import org.apache.kafka.clients.producer.Producer; -import org.apache.kafka.common.serialization.StringDeserializer; -import org.apache.kafka.common.serialization.StringSerializer; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.common.serdes.TestObject; +import io.apicurio.tests.utils.Constants; +import io.apicurio.tests.utils.KafkaFacade; import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; import io.apicurio.registry.serde.SerdeConfig; import io.apicurio.registry.serde.avro.AvroKafkaDeserializer; @@ -49,21 +35,41 @@ import io.apicurio.registry.utils.IoUtil; import io.apicurio.registry.utils.tests.TestUtils; import io.apicurio.registry.utils.tests.TooManyRequestsMock; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.KafkaFacade; -import io.apicurio.tests.common.serdes.TestObject; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import org.apache.avro.Schema; +import org.apache.avro.generic.GenericData; +import org.apache.avro.generic.GenericRecord; +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; /** - * @author Fabian Martinez + * @author Carles Arnal */ @Tag(Constants.SERDES) -public class AvroSerdeIT extends ApicurioV2BaseIT { +@QuarkusIntegrationTest +public class AvroSerdeIT extends ApicurioRegistryBaseIT { - private KafkaFacade kafkaCluster = KafkaFacade.getInstance(); + private final KafkaFacade kafkaCluster = KafkaFacade.getInstance(); - private Class serializer = AvroKafkaSerializer.class; - private Class deserializer = AvroKafkaDeserializer.class; + private final Class serializer = AvroKafkaSerializer.class; + private final Class deserializer = AvroKafkaDeserializer.class; + + @Override + public void cleanArtifacts() throws Exception { + //Don't clean up + } @BeforeAll void setupEnvironment() { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaMsgFactory.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaMsgFactory.java similarity index 98% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaMsgFactory.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaMsgFactory.java index 4f9a82647f..839d8ab97e 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaMsgFactory.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaMsgFactory.java @@ -16,19 +16,18 @@ package io.apicurio.tests.serdes.apicurio; -import java.io.InputStream; -import java.util.Date; -import java.util.Map; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; - -import io.apicurio.registry.utils.IoUtil; import io.apicurio.tests.common.serdes.json.Msg; import io.apicurio.tests.common.serdes.json.ValidMessage; +import io.apicurio.registry.utils.IoUtil; + +import java.io.InputStream; +import java.util.Date; +import java.util.Map; /** - * @author Fabian Martinez + * @author Carles Arnal */ public class JsonSchemaMsgFactory { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaSerdeIT.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaSerdeIT.java similarity index 95% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaSerdeIT.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaSerdeIT.java index be4ba0bfe9..037921426f 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaSerdeIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/JsonSchemaSerdeIT.java @@ -16,16 +16,12 @@ package io.apicurio.tests.serdes.apicurio; -import java.util.Map; - -import org.apache.kafka.connect.json.JsonSerializer; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - import com.fasterxml.jackson.databind.JsonNode; - +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.common.serdes.json.InvalidMessage; +import io.apicurio.tests.common.serdes.json.ValidMessage; +import io.apicurio.tests.utils.Constants; +import io.apicurio.tests.utils.KafkaFacade; import io.apicurio.registry.serde.SerdeConfig; import io.apicurio.registry.serde.jsonschema.JsonSchemaKafkaDeserializer; import io.apicurio.registry.serde.jsonschema.JsonSchemaKafkaSerializer; @@ -33,23 +29,32 @@ import io.apicurio.registry.serde.strategy.TopicIdStrategy; import io.apicurio.registry.types.ArtifactType; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.KafkaFacade; -import io.apicurio.tests.common.serdes.json.InvalidMessage; -import io.apicurio.tests.common.serdes.json.ValidMessage; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import org.apache.kafka.connect.json.JsonSerializer; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.util.Map; /** - * @author Fabian Martinez + * @author Carles Arnal */ @Tag(Constants.SERDES) -public class JsonSchemaSerdeIT extends ApicurioV2BaseIT { +@QuarkusIntegrationTest +public class JsonSchemaSerdeIT extends ApicurioRegistryBaseIT { private KafkaFacade kafkaCluster = KafkaFacade.getInstance(); private Class serializer = JsonSchemaKafkaSerializer.class; private Class deserializer = JsonSchemaKafkaDeserializer.class; + @Override + public void cleanArtifacts() throws Exception { + //Don't clean up + } + @BeforeAll void setupEnvironment() { kafkaCluster.startIfNeeded(); diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufSerdeIT.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufSerdeIT.java similarity index 98% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufSerdeIT.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufSerdeIT.java index e94c6b9a0f..60aca5c42f 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufSerdeIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufSerdeIT.java @@ -16,15 +16,13 @@ package io.apicurio.tests.serdes.apicurio; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - import com.google.protobuf.DynamicMessage; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.common.serdes.proto.TestCmmn; +import io.apicurio.tests.protobuf.ProtobufTestMessage; +import io.apicurio.tests.utils.Constants; +import io.apicurio.tests.utils.KafkaFacade; +import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; import io.apicurio.registry.serde.SerdeConfig; import io.apicurio.registry.serde.protobuf.ProtobufKafkaDeserializer; import io.apicurio.registry.serde.protobuf.ProtobufKafkaDeserializerConfig; @@ -34,17 +32,20 @@ import io.apicurio.registry.types.ArtifactType; import io.apicurio.registry.utils.IoUtil; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.KafkaFacade; -import io.apicurio.tests.common.serdes.proto.TestCmmn; -import io.apicurio.tests.protobuf.ProtobufTestMessage; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; /** - * @author Fabian Martinez + * @author Carles Arnal */ @Tag(Constants.SERDES) -public class ProtobufSerdeIT extends ApicurioV2BaseIT { +@QuarkusIntegrationTest +public class ProtobufSerdeIT extends ApicurioRegistryBaseIT { private KafkaFacade kafkaCluster = KafkaFacade.getInstance(); @@ -61,6 +62,11 @@ void teardownEnvironment() throws Exception { kafkaCluster.stopIfPossible(); } + @Override + public void cleanArtifacts() throws Exception { + //Don't clean up + } + @Test @Tag(Constants.ACCEPTANCE) void testTopicIdStrategyFindLatest() throws Exception { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufTestMessageFactory.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufTestMessageFactory.java similarity index 98% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufTestMessageFactory.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufTestMessageFactory.java index 6ebb36b453..47d40255af 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufTestMessageFactory.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufTestMessageFactory.java @@ -16,21 +16,21 @@ package io.apicurio.tests.serdes.apicurio; -import java.io.InputStream; -import java.util.Date; import com.google.protobuf.Descriptors; import com.google.protobuf.DynamicMessage; import com.google.protobuf.Timestamp; import com.squareup.wire.schema.internal.parser.ProtoFileElement; - -import io.apicurio.registry.utils.protobuf.schema.FileDescriptorUtils; -import io.apicurio.registry.utils.IoUtil; import io.apicurio.tests.protobuf.Header; import io.apicurio.tests.protobuf.Point; import io.apicurio.tests.protobuf.ProtobufTestMessage; +import io.apicurio.registry.utils.IoUtil; +import io.apicurio.registry.utils.protobuf.schema.FileDescriptorUtils; + +import java.io.InputStream; +import java.util.Date; /** - * @author Fabian Martinez + * @author Carles Arnal */ public class ProtobufTestMessageFactory { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufUUIDTestMessage.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufUUIDTestMessage.java similarity index 98% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufUUIDTestMessage.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufUUIDTestMessage.java index 8bc727ed2d..8a3491e009 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufUUIDTestMessage.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/ProtobufUUIDTestMessage.java @@ -16,18 +16,18 @@ package io.apicurio.tests.serdes.apicurio; -import java.io.InputStream; -import java.util.Date; import com.google.protobuf.Descriptors; import com.google.protobuf.DynamicMessage; import com.squareup.wire.schema.internal.parser.ProtoFileElement; - -import io.apicurio.registry.utils.protobuf.schema.FileDescriptorUtils; -import io.apicurio.registry.utils.IoUtil; import io.apicurio.tests.common.serdes.proto.TestCmmn; +import io.apicurio.registry.utils.IoUtil; +import io.apicurio.registry.utils.protobuf.schema.FileDescriptorUtils; + +import java.io.InputStream; +import java.util.Date; /** - * @author Fabian Martinez + * @author Carles Arnal */ public class ProtobufUUIDTestMessage { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/SerdesTester.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/SerdesTester.java similarity index 89% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/SerdesTester.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/SerdesTester.java index 1031b8d58b..1f18889f61 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/SerdesTester.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/SerdesTester.java @@ -16,20 +16,11 @@ package io.apicurio.tests.serdes.apicurio; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.time.Duration; -import java.util.Collections; -import java.util.Properties; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Predicate; - +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.KafkaFacade; +import io.apicurio.registry.serde.SerdeConfig; +import io.confluent.kafka.serializers.AbstractKafkaSchemaSerDeConfig; +import io.confluent.kafka.serializers.KafkaAvroSerializerConfig; import org.apache.kafka.clients.CommonClientConfigs; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; @@ -43,14 +34,22 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.apicurio.registry.serde.SerdeConfig; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.common.KafkaFacade; -import io.confluent.kafka.serializers.AbstractKafkaSchemaSerDeConfig; -import io.confluent.kafka.serializers.KafkaAvroSerializerConfig; +import java.time.Duration; +import java.util.Collections; +import java.util.Properties; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Predicate; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; /** - * @author Fabian Martinez + * @author Carles Arnal */ public class SerdesTester { @@ -58,6 +57,7 @@ public class SerdesTester { private static final int MILLIS_PER_MESSAGE = 700; private static final String BOOTSTRAP_SERVERS = "localhost:9092"; + private static final String MAC_OS_BOOTSTRAP_SERVERS = "docker.host.internal:9092"; private boolean autoClose = true; @@ -87,11 +87,11 @@ public Producer createProducer(Properties props, Class keySerializerCla props.putIfAbsent(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, valueSerializerClass.getName()); // Schema Registry location. if (valueSerializerClass.getName().contains("confluent")) { - props.putIfAbsent(KafkaAvroSerializerConfig.SCHEMA_REGISTRY_URL_CONFIG, TestUtils.getRegistryApiUrl() + "/ccompat/v6"); + props.putIfAbsent(KafkaAvroSerializerConfig.SCHEMA_REGISTRY_URL_CONFIG, ApicurioRegistryBaseIT.getRegistryApiUrl() + "/ccompat/v6"); props.putIfAbsent(AbstractKafkaSchemaSerDeConfig.AUTO_REGISTER_SCHEMAS, "false"); props.putIfAbsent(KafkaAvroSerializerConfig.VALUE_SUBJECT_NAME_STRATEGY, artifactIdStrategy.getName()); } else { - props.putIfAbsent(SerdeConfig.REGISTRY_URL, TestUtils.getRegistryV2ApiUrl()); + props.putIfAbsent(SerdeConfig.REGISTRY_URL, ApicurioRegistryBaseIT.getRegistryV2ApiUrl()); props.putIfAbsent(SerdeConfig.ARTIFACT_RESOLVER_STRATEGY, artifactIdStrategy.getName()); } @@ -115,9 +115,9 @@ public Consumer createConsumer(Properties props, Class keyDeserializer, props.putIfAbsent(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, valueDeserializer.getName()); //Schema registry location. if (valueDeserializer.getName().contains("confluent")) { - props.putIfAbsent(KafkaAvroSerializerConfig.SCHEMA_REGISTRY_URL_CONFIG, TestUtils.getRegistryApiUrl() + "/ccompat/v6"); + props.putIfAbsent(KafkaAvroSerializerConfig.SCHEMA_REGISTRY_URL_CONFIG, ApicurioRegistryBaseIT.getRegistryApiUrl() + "/ccompat/v6"); } else { - props.putIfAbsent(SerdeConfig.REGISTRY_URL, TestUtils.getRegistryV2ApiUrl()); + props.putIfAbsent(SerdeConfig.REGISTRY_URL, ApicurioRegistryBaseIT.getRegistryV2ApiUrl()); } return new KafkaConsumer<>(props); @@ -224,8 +224,13 @@ private static Properties connectionProperties() { String bootsrapServers = KafkaFacade.getInstance().bootstrapServers(); if (bootsrapServers == null) { Properties props = new Properties(); - props.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS); - return props; + if (System.getProperty("os.name").contains("Mac OS")) { + LOGGER.info("Picking mac os specific bootstrap servers"); + props.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, MAC_OS_BOOTSTRAP_SERVERS); + } else { + LOGGER.info("Picking linux specific bootstrap servers"); + props.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS); + } return props; } else { return KafkaFacade.getInstance().connectionProperties(); } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/SimpleSerdesTesterBuilder.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/SimpleSerdesTesterBuilder.java similarity index 94% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/SimpleSerdesTesterBuilder.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/SimpleSerdesTesterBuilder.java index 5bc192595a..0962efa6f7 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/SimpleSerdesTesterBuilder.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/SimpleSerdesTesterBuilder.java @@ -16,11 +16,7 @@ package io.apicurio.tests.serdes.apicurio; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.Objects; -import java.util.Properties; -import java.util.function.Predicate; +import io.apicurio.tests.serdes.apicurio.SerdesTester.DataGenerator; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.common.serialization.Deserializer; @@ -28,12 +24,17 @@ import org.apache.kafka.common.serialization.StringDeserializer; import org.apache.kafka.common.serialization.StringSerializer; -import io.apicurio.tests.serdes.apicurio.SerdesTester.DataGenerator; -import io.apicurio.tests.serdes.apicurio.SerdesTester.Validator; -import io.apicurio.tests.serdes.apicurio.Tester.TesterBuilder; +import java.util.Objects; +import java.util.Properties; +import java.util.function.Predicate; + +import static io.apicurio.tests.serdes.apicurio.SerdesTester.*; +import static io.apicurio.tests.serdes.apicurio.Tester.*; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** - * @author Fabian Martinez + * @author Carles Arnal */ public class SimpleSerdesTesterBuilder implements TesterBuilder { @@ -117,7 +118,7 @@ public SimpleSerdesTesterBuilder withAfterProduceValidator(Validator after } /** - * @see io.apicurio.tests.serdes.apicurio.SerdesTester.TesterBuilder#build() + * @see TesterBuilder#build() */ @Override public Tester build() { @@ -136,7 +137,7 @@ public Tester build() { private class SimpleSerdesTester extends SerdesTester implements Tester { /** - * @see io.apicurio.tests.serdes.apicurio.Tester#test() + * @see Tester#test() */ @Override public void test() throws Exception { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/Tester.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/Tester.java similarity index 96% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/Tester.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/Tester.java index e75b43af78..b2ff1274b5 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/Tester.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/Tester.java @@ -17,7 +17,7 @@ package io.apicurio.tests.serdes.apicurio; /** - * @author Fabian Martinez + * @author Carles Arnal */ public interface Tester { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredConsumerTesterBuilder.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredConsumerTesterBuilder.java similarity index 93% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredConsumerTesterBuilder.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredConsumerTesterBuilder.java index 791406c277..d53f40aad1 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredConsumerTesterBuilder.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredConsumerTesterBuilder.java @@ -16,24 +16,24 @@ package io.apicurio.tests.serdes.apicurio; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.Objects; -import java.util.concurrent.ExecutionException; - import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.common.serialization.StringDeserializer; import org.apache.kafka.common.serialization.StringSerializer; +import java.util.Objects; +import java.util.concurrent.ExecutionException; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** - * @author Fabian Martinez + * @author Carles Arnal */ public class WrongConfiguredConsumerTesterBuilder extends SimpleSerdesTesterBuilder { /** - * @see io.apicurio.tests.serdes.apicurio.SerdesTester.TesterBuilder#build() + * @see Tester.TesterBuilder#build() */ @Override public Tester build() { @@ -52,7 +52,7 @@ public Tester build() { private class FailingConsumerTester extends SerdesTester implements Tester { /** - * @see io.apicurio.tests.serdes.apicurio.Tester#test() + * @see Tester#test() */ @Override public void test() throws Exception { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredSerdesTesterBuilder.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredSerdesTesterBuilder.java similarity index 91% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredSerdesTesterBuilder.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredSerdesTesterBuilder.java index a79d138f74..b646b064ad 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredSerdesTesterBuilder.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/apicurio/WrongConfiguredSerdesTesterBuilder.java @@ -16,19 +16,21 @@ package io.apicurio.tests.serdes.apicurio; -import static org.junit.jupiter.api.Assertions.assertThrows; -import java.util.Objects; -import java.util.Properties; -import java.util.concurrent.ExecutionException; + +import io.apicurio.tests.serdes.apicurio.SerdesTester.DataGenerator; import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.common.serialization.Serializer; import org.apache.kafka.common.serialization.StringSerializer; -import io.apicurio.tests.serdes.apicurio.SerdesTester.DataGenerator; -import io.apicurio.tests.serdes.apicurio.Tester.TesterBuilder; +import java.util.Objects; +import java.util.Properties; +import java.util.concurrent.ExecutionException; + +import static io.apicurio.tests.serdes.apicurio.Tester.*; +import static org.junit.jupiter.api.Assertions.assertThrows; /** - * @author Fabian Martinez + * @author Carles Arnal */ public class WrongConfiguredSerdesTesterBuilder

implements TesterBuilder { @@ -66,13 +68,13 @@ public WrongConfiguredSerdesTesterBuilder

withStrategy(Class strategy) { return this; } - public WrongConfiguredSerdesTesterBuilder

withDataGenerator(DataGenerator

generator) { + public WrongConfiguredSerdesTesterBuilder

withDataGenerator(SerdesTester.DataGenerator

generator) { this.dataGenerator = generator; return this; } /** - * @see io.apicurio.tests.serdes.apicurio.SerdesTester.TesterBuilder#build() + * @see TesterBuilder#build() */ @Override public Tester build() { @@ -88,7 +90,7 @@ public Tester build() { private class WrongConfiguredSerdesTester extends SerdesTester implements Tester { /** - * @see io.apicurio.tests.serdes.apicurio.Tester#test() + * @see Tester#test() */ @Override public void test() throws Exception { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/confluent/BasicConfluentSerDesIT.java b/integration-tests/src/test/java/io/apicurio/tests/serdes/confluent/BasicConfluentSerDesIT.java similarity index 98% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/confluent/BasicConfluentSerDesIT.java rename to integration-tests/src/test/java/io/apicurio/tests/serdes/confluent/BasicConfluentSerDesIT.java index d1b31cdc74..780ffd4414 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/serdes/confluent/BasicConfluentSerDesIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/serdes/confluent/BasicConfluentSerDesIT.java @@ -16,22 +16,13 @@ package io.apicurio.tests.serdes.confluent; -import static io.apicurio.tests.common.Constants.SERDES; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.avro.generic.GenericRecord; -import org.apache.kafka.clients.consumer.Consumer; -import org.apache.kafka.clients.producer.Producer; -import org.apache.kafka.common.serialization.StringDeserializer; -import org.apache.kafka.common.serialization.StringSerializer; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - +import io.apicurio.tests.ConfluentBaseIT; +import io.apicurio.tests.serdes.apicurio.SerdesTester; +import io.apicurio.tests.serdes.apicurio.SimpleSerdesTesterBuilder; +import io.apicurio.tests.serdes.apicurio.WrongConfiguredSerdesTesterBuilder; +import io.apicurio.tests.utils.AvroGenericRecordSchemaFactory; +import io.apicurio.tests.utils.Constants; +import io.apicurio.tests.utils.KafkaFacade; import io.apicurio.registry.serde.SerdeConfig; import io.apicurio.registry.serde.avro.AvroKafkaDeserializer; import io.apicurio.registry.serde.avro.AvroKafkaSerializer; @@ -40,13 +31,7 @@ import io.apicurio.registry.types.ArtifactType; import io.apicurio.registry.utils.IoUtil; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ConfluentBaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.KafkaFacade; -import io.apicurio.tests.serdes.apicurio.AvroGenericRecordSchemaFactory; -import io.apicurio.tests.serdes.apicurio.SerdesTester; -import io.apicurio.tests.serdes.apicurio.SimpleSerdesTesterBuilder; -import io.apicurio.tests.serdes.apicurio.WrongConfiguredSerdesTesterBuilder; + import io.confluent.kafka.schemaregistry.ParsedSchema; import io.confluent.kafka.schemaregistry.avro.AvroSchema; import io.confluent.kafka.serializers.KafkaAvroDeserializer; @@ -54,8 +39,25 @@ import io.confluent.kafka.serializers.subject.RecordNameStrategy; import io.confluent.kafka.serializers.subject.TopicNameStrategy; import io.confluent.kafka.serializers.subject.TopicRecordNameStrategy; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import org.apache.avro.generic.GenericRecord; +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import static io.apicurio.tests.utils.Constants.SERDES; +import static org.junit.jupiter.api.Assertions.assertEquals; @Tag(SERDES) +@QuarkusIntegrationTest public class BasicConfluentSerDesIT extends ConfluentBaseIT { private KafkaFacade kafkaCluster = KafkaFacade.getInstance(); diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/AllArtifactTypesIT.java b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/AllArtifactTypesIT.java similarity index 95% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/AllArtifactTypesIT.java rename to integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/AllArtifactTypesIT.java index d9837654d7..ca70106419 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/AllArtifactTypesIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/AllArtifactTypesIT.java @@ -15,8 +15,7 @@ */ package io.apicurio.tests.smokeTests.apicurio; -import static io.apicurio.tests.common.Constants.SMOKE; - +import io.apicurio.tests.ApicurioRegistryBaseIT; import io.apicurio.registry.rest.client.exception.RuleViolationException; import io.apicurio.registry.rest.v2.beans.Rule; import io.apicurio.registry.rest.v2.beans.VersionMetaData; @@ -24,19 +23,20 @@ import io.apicurio.registry.types.RuleType; import io.apicurio.registry.utils.IoUtil; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ApicurioV2BaseIT; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; - +import io.quarkus.test.junit.QuarkusIntegrationTest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import java.util.List; + +import static io.apicurio.tests.utils.Constants.SMOKE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + @Tag(SMOKE) -class AllArtifactTypesIT extends ApicurioV2BaseIT { +@QuarkusIntegrationTest +class AllArtifactTypesIT extends ApicurioRegistryBaseIT { void doTest(String v1Resource, String v2Resource, String atype) throws Exception { String groupId = TestUtils.generateGroupId(); diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/ArtifactsIT.java b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/ArtifactsIT.java similarity index 94% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/ArtifactsIT.java rename to integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/ArtifactsIT.java index 6328d8d621..778aae7f70 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/ArtifactsIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/ArtifactsIT.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,9 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.AvroGenericRecordSchemaFactory; +import io.apicurio.tests.utils.Constants; import io.apicurio.registry.rest.client.exception.ArtifactAlreadyExistsException; import io.apicurio.registry.rest.client.exception.ArtifactNotFoundException; import io.apicurio.registry.rest.client.exception.InvalidArtifactIdException; @@ -35,10 +38,7 @@ import io.apicurio.registry.types.RuleType; import io.apicurio.registry.utils.IoUtil; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.serdes.apicurio.AvroGenericRecordSchemaFactory; -import io.apicurio.tests.utils.ArtifactUtils; +import io.quarkus.test.junit.QuarkusIntegrationTest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Tag; @@ -54,15 +54,15 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import static io.apicurio.registry.utils.tests.TestUtils.assertClientError; import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; @Tag(Constants.SMOKE) -class ArtifactsIT extends ApicurioV2BaseIT { +@QuarkusIntegrationTest +class ArtifactsIT extends ApicurioRegistryBaseIT { private static final Logger LOGGER = LoggerFactory.getLogger(ArtifactsIT.class); @@ -134,15 +134,15 @@ void createAndDeleteMultipleArtifacts() throws Exception { String groupId = TestUtils.generateGroupId(); List artifacts = IntStream.range(0, 10) - .mapToObj(i -> { - String artifactId = TestUtils.generateSubject(); - try { - return super.createArtifact(groupId, artifactId, ArtifactType.AVRO, new AvroGenericRecordSchemaFactory(groupId, artifactId, List.of("foo")).generateSchemaStream()); - } catch (Exception e) { - throw new RuntimeException(e); - } - }) - .collect(Collectors.toList()); + .mapToObj(i -> { + String artifactId = TestUtils.generateSubject(); + try { + return super.createArtifact(groupId, artifactId, ArtifactType.AVRO, new AvroGenericRecordSchemaFactory(groupId, artifactId, List.of("foo")).generateSchemaStream()); + } catch (Exception e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toList()); LOGGER.info("Created {} artifacts", artifacts.size()); @@ -226,7 +226,7 @@ void testDisableEnableArtifact() throws Exception { String artifactData = "{\"type\":\"record\",\"name\":\"myrecord1\",\"fields\":[{\"name\":\"foo\",\"type\":\"string\"}]}"; // Create the artifact - ArtifactMetaData metaData = createArtifact(groupId, artifactId , ArtifactType.AVRO, IoUtil.toStream(artifactData)); + ArtifactMetaData metaData = createArtifact(groupId, artifactId, ArtifactType.AVRO, IoUtil.toStream(artifactData)); LOGGER.info("Created artifact {} with metadata {}", artifactId, metaData.toString()); // Disable the artifact @@ -405,7 +405,7 @@ void forbiddenSpecialCharactersTestClient(String artifactId) { registryClient.createArtifact(groupId, artifactId, ArtifactType.AVRO, artifactData); }); - ArtifactUtils.createArtifact(groupId, artifactId, content, 400); + createArtifact(groupId, artifactId, content, 400); } @@ -430,7 +430,7 @@ void testAllowedSpecialCharacters() throws Exception { registryClient.getLatestArtifact(groupId, artifactId); - ArtifactUtils.getArtifact(groupId, artifactId); + getArtifact(groupId, artifactId); } @Test @@ -440,9 +440,9 @@ void testAllowedSpecialCharactersCreateViaApi() throws Exception { String content = "{\"type\":\"record\",\"name\":\"myrecord1\",\"fields\":[{\"name\":\"foo\",\"type\":\"string\"}]}"; - ArtifactUtils.createArtifact(groupId, artifactId, content, 200); + createArtifact(groupId, artifactId, content, 200); - retryOp((rc) -> rc.getArtifactMetaData(groupId,artifactId)); + retryOp((rc) -> rc.getArtifactMetaData(groupId, artifactId)); registryClient.getArtifactMetaData(groupId, artifactId); @@ -456,7 +456,7 @@ void testAllowedSpecialCharactersCreateViaApi() throws Exception { registryClient.getLatestArtifact(groupId, artifactId); - ArtifactUtils.getArtifact(groupId, artifactId); + getArtifact(groupId, artifactId); } @Test @@ -467,7 +467,7 @@ public void testSearchOrderBy() throws Exception { for (int idx = 0; idx < 5; idx++) { String artifactId = "test-" + idx; - Thread.sleep(idx == 0 ? 0 : 1500/idx); + Thread.sleep(idx == 0 ? 0 : 1500 / idx); this.createArtifact(group, artifactId, ArtifactType.OPENAPI, new ByteArrayInputStream(content.getBytes())); } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/LoadIT.java b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/LoadIT.java similarity index 96% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/LoadIT.java rename to integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/LoadIT.java index 8cddfa3755..ce6ff63550 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/LoadIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/LoadIT.java @@ -15,20 +15,21 @@ */ package io.apicurio.tests.smokeTests.apicurio; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.quarkus.test.junit.QuarkusIntegrationTest; import org.junit.jupiter.api.Disabled; -import io.apicurio.tests.ApicurioV2BaseIT; - /** * Disabled because this is too flaky and it needs to be redesigned to align better * with common usage of the registry, which is frequent reads sporadic writes. * - * @author Fabian Martinez + * @author Carles Arnal * */ //@Tag(SMOKE) @Disabled -public class LoadIT extends ApicurioV2BaseIT { +@QuarkusIntegrationTest +public class LoadIT extends ApicurioRegistryBaseIT { // private static final Logger LOGGER = LoggerFactory.getLogger(LoadIT.class); // diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/MetadataIT.java b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/MetadataIT.java similarity index 96% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/MetadataIT.java rename to integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/MetadataIT.java index 1582ec44b7..14936d4f99 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/MetadataIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/MetadataIT.java @@ -16,30 +16,31 @@ package io.apicurio.tests.smokeTests.apicurio; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.CoreMatchers.nullValue; - -import java.io.ByteArrayInputStream; -import java.nio.charset.StandardCharsets; - +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.Constants; +import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; +import io.apicurio.registry.rest.v2.beans.EditableMetaData; +import io.apicurio.registry.rest.v2.beans.VersionMetaData; +import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.utils.tests.TestUtils; +import io.quarkus.test.junit.QuarkusIntegrationTest; import org.hamcrest.number.OrderingComparison; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; -import io.apicurio.registry.rest.v2.beans.EditableMetaData; -import io.apicurio.registry.rest.v2.beans.VersionMetaData; -import io.apicurio.registry.types.ArtifactType; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; @Tag(Constants.SMOKE) -class MetadataIT extends ApicurioV2BaseIT { +@QuarkusIntegrationTest +class MetadataIT extends ApicurioRegistryBaseIT { private static final Logger LOGGER = LoggerFactory.getLogger(MetadataIT.class); diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/RulesResourceIT.java b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/RulesResourceIT.java similarity index 97% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/RulesResourceIT.java rename to integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/RulesResourceIT.java index 96fb2ccdc6..617a639bda 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/apicurio/RulesResourceIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/apicurio/RulesResourceIT.java @@ -16,39 +16,38 @@ package io.apicurio.tests.smokeTests.apicurio; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.hasItems; - -import java.io.ByteArrayInputStream; -import java.nio.charset.StandardCharsets; - +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.Constants; +import io.apicurio.registry.rest.client.exception.ArtifactNotFoundException; +import io.apicurio.registry.rest.client.exception.RuleAlreadyExistsException; +import io.apicurio.registry.rest.client.exception.RuleNotFoundException; +import io.apicurio.registry.rest.client.exception.RuleViolationException; +import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; +import io.apicurio.registry.rest.v2.beans.Rule; +import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.types.RuleType; +import io.apicurio.registry.utils.IoUtil; +import io.apicurio.registry.utils.tests.TestUtils; +import io.quarkus.test.junit.QuarkusIntegrationTest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; -import io.apicurio.registry.types.ArtifactType; -import io.apicurio.registry.utils.IoUtil; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; - +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; import java.util.List; -import io.apicurio.registry.rest.client.exception.ArtifactNotFoundException; -import io.apicurio.registry.rest.client.exception.RuleAlreadyExistsException; -import io.apicurio.registry.rest.client.exception.RuleNotFoundException; -import io.apicurio.registry.rest.client.exception.RuleViolationException; -import io.apicurio.registry.rest.v2.beans.Rule; -import io.apicurio.registry.types.RuleType; +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; @Tag(Constants.SMOKE) -class RulesResourceIT extends ApicurioV2BaseIT { +@QuarkusIntegrationTest +class RulesResourceIT extends ApicurioRegistryBaseIT { private static final Logger LOGGER = LoggerFactory.getLogger(RulesResourceIT.class); diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/subUtils/ConfluentConfigUtils.java b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/ConfluentConfigUtils.java similarity index 75% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/subUtils/ConfluentConfigUtils.java rename to integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/ConfluentConfigUtils.java index 9b6545e4fd..93b6e52656 100644 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/subUtils/ConfluentConfigUtils.java +++ b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/ConfluentConfigUtils.java @@ -14,24 +14,25 @@ * limitations under the License. */ -package io.apicurio.tests.common.utils.subUtils; +package io.apicurio.tests.smokeTests.confluent; + +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.BaseHttpUtils; +import io.apicurio.tests.utils.RestConstants; +import io.restassured.response.Response; import java.io.UncheckedIOException; import java.net.MalformedURLException; import java.net.URL; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.common.utils.BaseHttpUtils; -import io.restassured.response.Response; - /** - * @author Fabian Martinez + * @author Carles Arnal */ public class ConfluentConfigUtils { public static Response testCompatibility(String body, String schemaName, int returnCode) { try { - URL url = new URL(TestUtils.getRegistryApiUrl() + "/ccompat/v6/compatibility/subjects/" + schemaName + "/versions/latest"); + URL url = new URL(ApicurioRegistryBaseIT.getRegistryApiUrl() + "/ccompat/v6/compatibility/subjects/" + schemaName + "/versions/latest"); return BaseHttpUtils.rulesPostRequest(RestConstants.SR, body, url, returnCode); } catch (MalformedURLException e) { throw new UncheckedIOException(e); @@ -40,7 +41,7 @@ public static Response testCompatibility(String body, String schemaName, int ret public static Response createGlobalCompatibilityConfig(String typeOfCompatibility) { try { - URL url = new URL(TestUtils.getRegistryApiUrl() + "/ccompat/v6/config"); + URL url = new URL(ApicurioRegistryBaseIT.getRegistryApiUrl() + "/ccompat/v6/config"); return BaseHttpUtils.putRequest(RestConstants.SR, "{\"compatibility\":\"" + typeOfCompatibility + "\"}", url, 200); } catch (MalformedURLException e) { throw new UncheckedIOException(e); @@ -49,7 +50,7 @@ public static Response createGlobalCompatibilityConfig(String typeOfCompatibilit public static Response getGlobalCompatibilityConfig() { try { - URL url = new URL(TestUtils.getRegistryApiUrl() + "/ccompat/v6/config"); + URL url = new URL(ApicurioRegistryBaseIT.getRegistryApiUrl() + "/ccompat/v6/config"); return BaseHttpUtils.getRequest(RestConstants.JSON, url, 204); } catch (MalformedURLException e) { throw new UncheckedIOException(e); diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/subUtils/ConfluentSubjectsUtils.java b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/ConfluentSubjectsUtils.java similarity index 83% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/subUtils/ConfluentSubjectsUtils.java rename to integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/ConfluentSubjectsUtils.java index 94f62d029e..cd5ef31561 100644 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/subUtils/ConfluentSubjectsUtils.java +++ b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/ConfluentSubjectsUtils.java @@ -14,20 +14,22 @@ * limitations under the License. */ -package io.apicurio.tests.common.utils.subUtils; +package io.apicurio.tests.smokeTests.confluent; -import static io.apicurio.tests.common.utils.BaseHttpUtils.putRequest; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.utils.BaseHttpUtils; +import io.apicurio.tests.utils.RestConstants; +import io.restassured.response.Response; import java.io.UncheckedIOException; import java.net.MalformedURLException; import java.net.URL; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.common.utils.BaseHttpUtils; -import io.restassured.response.Response; +import static io.apicurio.tests.utils.BaseHttpUtils.putRequest; + /** - * @author Fabian Martinez + * @author Carles Arnal */ public class ConfluentSubjectsUtils { @@ -49,7 +51,7 @@ public static Response updateSchemaMetadata(String schemaName, String metadata, private static URL getCCompatURL(String ccompatPath) { try { - return new URL(TestUtils.getRegistryApiUrl() + ccompatPath); + return new URL(ApicurioRegistryBaseIT.getRegistryApiUrl() + ccompatPath); } catch (MalformedURLException e) { throw new UncheckedIOException(e); } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/confluent/MetadataConfluentIT.java b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/MetadataConfluentIT.java similarity index 95% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/confluent/MetadataConfluentIT.java rename to integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/MetadataConfluentIT.java index b9ea73fc3e..b73021c4be 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/confluent/MetadataConfluentIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/MetadataConfluentIT.java @@ -16,26 +16,27 @@ package io.apicurio.tests.smokeTests.confluent; -import static io.apicurio.tests.common.Constants.SMOKE; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -import java.io.IOException; -import java.util.concurrent.TimeoutException; - -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.apicurio.registry.utils.tests.TestUtils; import io.apicurio.tests.ConfluentBaseIT; +import io.apicurio.registry.utils.tests.TestUtils; import io.confluent.kafka.schemaregistry.ParsedSchema; import io.confluent.kafka.schemaregistry.avro.AvroSchema; import io.confluent.kafka.schemaregistry.client.SchemaMetadata; import io.confluent.kafka.schemaregistry.client.rest.exceptions.RestClientException; +import io.quarkus.test.junit.QuarkusIntegrationTest; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.concurrent.TimeoutException; + +import static io.apicurio.tests.utils.Constants.SMOKE; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; @Tag(SMOKE) +@QuarkusIntegrationTest public class MetadataConfluentIT extends ConfluentBaseIT { private static final Logger LOGGER = LoggerFactory.getLogger(MetadataConfluentIT.class); diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/confluent/RulesResourceConfluentIT.java b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/RulesResourceConfluentIT.java similarity index 96% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/confluent/RulesResourceConfluentIT.java rename to integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/RulesResourceConfluentIT.java index 36c9d1a335..2a3fb4688c 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/confluent/RulesResourceConfluentIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/RulesResourceConfluentIT.java @@ -16,12 +16,12 @@ package io.apicurio.tests.smokeTests.confluent; +import io.apicurio.tests.ConfluentBaseIT; import io.apicurio.registry.types.RuleType; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ConfluentBaseIT; -import io.apicurio.tests.common.utils.subUtils.ConfluentConfigUtils; import io.confluent.kafka.schemaregistry.ParsedSchema; import io.confluent.kafka.schemaregistry.avro.AvroSchema; +import io.quarkus.test.junit.QuarkusIntegrationTest; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -30,10 +30,11 @@ import java.util.List; -import static io.apicurio.tests.common.Constants.SMOKE; +import static io.apicurio.tests.utils.Constants.SMOKE; import static org.junit.jupiter.api.Assertions.assertEquals; @Tag(SMOKE) +@QuarkusIntegrationTest class RulesResourceConfluentIT extends ConfluentBaseIT { private static final Logger LOGGER = LoggerFactory.getLogger(MetadataConfluentIT.class); diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/confluent/SchemasConfluentIT.java b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/SchemasConfluentIT.java similarity index 96% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/confluent/SchemasConfluentIT.java rename to integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/SchemasConfluentIT.java index 0b1b8ec50c..14d7b05d29 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/smokeTests/confluent/SchemasConfluentIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/smokeTests/confluent/SchemasConfluentIT.java @@ -16,26 +16,19 @@ package io.apicurio.tests.smokeTests.confluent; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.hasItems; - +import io.apicurio.tests.ConfluentBaseIT; +import io.apicurio.tests.utils.ArtifactUtils; +import io.apicurio.tests.utils.Constants; import io.apicurio.registry.rest.client.exception.ArtifactNotFoundException; import io.apicurio.registry.rest.client.exception.ContentNotFoundException; import io.apicurio.registry.rest.v2.beans.Rule; import io.apicurio.registry.types.RuleType; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ConfluentBaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.utils.subUtils.ConfluentSubjectsUtils; -import io.apicurio.tests.utils.ArtifactUtils; import io.confluent.kafka.schemaregistry.ParsedSchema; import io.confluent.kafka.schemaregistry.avro.AvroSchema; import io.confluent.kafka.schemaregistry.client.rest.exceptions.RestClientException; +import io.quarkus.test.junit.QuarkusIntegrationTest; import io.restassured.response.Response; - import org.apache.avro.SchemaParseException; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -43,14 +36,19 @@ import org.slf4j.LoggerFactory; import jakarta.ws.rs.WebApplicationException; - -import static io.apicurio.tests.common.Constants.SMOKE; - import java.io.IOException; import java.util.List; import java.util.concurrent.TimeoutException; +import static io.apicurio.tests.utils.Constants.SMOKE; +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + @Tag(SMOKE) +@QuarkusIntegrationTest public class SchemasConfluentIT extends ConfluentBaseIT { private static final Logger LOGGER = LoggerFactory.getLogger(SchemasConfluentIT.class); @@ -166,13 +164,11 @@ void deleteNonexistingSchema() { } @Test - void createInvalidSchemaDefinition() throws TimeoutException { + void createInvalidSchemaDefinition() throws TimeoutException, RestClientException, IOException { String subjectName = TestUtils.generateArtifactId(); - - ConfluentSubjectsUtils.createSchema("{\"schema\": \"{\\\"type\\\": \\\"record\\\",\\\"name\\\": \\\"myrecord1\\\",\\\"fields\\\": [{\\\"name\\\": \\\"foo1\\\",\\\"type\\\": \\\"string\\\"}]}\"}\"", subjectName, 200); - + ParsedSchema schema = new AvroSchema("{\"type\":\"record\",\"name\":\"myrecord1\",\"fields\":[{\"name\":\"foo\",\"type\":\"string\"}]}"); + createArtifactViaConfluentClient(schema, subjectName); TestUtils.waitFor("artifactCreated", Constants.POLL_INTERVAL, Constants.TIMEOUT_GLOBAL, () -> registryClient.getArtifactMetaData(null, subjectName) != null); - String invalidSchema = "{\"schema\":\"{\\\"type\\\": \\\"bloop\\\"}\"}"; Rule rule = new Rule(); diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/DeleteArtifactIT.java b/integration-tests/src/test/java/io/apicurio/tests/ui/DeleteArtifactIT.java similarity index 94% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/DeleteArtifactIT.java rename to integration-tests/src/test/java/io/apicurio/tests/ui/DeleteArtifactIT.java index 1a525cf37b..db4a466adc 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/DeleteArtifactIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ui/DeleteArtifactIT.java @@ -15,32 +15,33 @@ */ package io.apicurio.tests.ui; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.hamcrest.CoreMatchers.hasItems; -import static org.hamcrest.MatcherAssert.assertThat; - -import java.time.Duration; -import java.util.List; -import java.util.stream.Collectors; - +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.ui.selenium.SeleniumChrome; +import io.apicurio.tests.ui.selenium.SeleniumProvider; +import io.apicurio.tests.ui.selenium.resources.ArtifactListItem; +import io.apicurio.tests.utils.Constants; +import io.apicurio.registry.rest.client.exception.ArtifactNotFoundException; +import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.utils.tests.TestUtils; +import io.quarkus.test.junit.QuarkusIntegrationTest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; -import io.apicurio.registry.rest.client.exception.ArtifactNotFoundException; -import io.apicurio.registry.types.ArtifactType; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.selenium.SeleniumChrome; -import io.apicurio.tests.selenium.SeleniumProvider; -import io.apicurio.tests.selenium.resources.ArtifactListItem; +import java.time.Duration; +import java.util.List; +import java.util.stream.Collectors; + +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; @Tag(Constants.UI) @SeleniumChrome -public class DeleteArtifactIT extends ApicurioV2BaseIT { +@QuarkusIntegrationTest +public class DeleteArtifactIT extends ApicurioRegistryBaseIT { SeleniumProvider selenium = SeleniumProvider.getInstance(); diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/RegistryUITester.java b/integration-tests/src/test/java/io/apicurio/tests/ui/RegistryUITester.java similarity index 98% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/RegistryUITester.java rename to integration-tests/src/test/java/io/apicurio/tests/ui/RegistryUITester.java index 207a10b3ac..bb9225095d 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/RegistryUITester.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ui/RegistryUITester.java @@ -15,7 +15,14 @@ */ package io.apicurio.tests.ui; -import static org.junit.Assert.assertNotNull; +import io.apicurio.tests.ui.selenium.SeleniumProvider; +import io.apicurio.tests.ui.selenium.resources.ArtifactListItem; +import io.apicurio.tests.ui.pages.ArtifactDetailsPage; +import io.apicurio.tests.ui.pages.ArtifactsListPage; +import io.apicurio.tests.ui.pages.UploadArtifactDialog; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; @@ -23,15 +30,7 @@ import java.time.Duration; import java.util.List; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.apicurio.tests.selenium.SeleniumProvider; -import io.apicurio.tests.selenium.resources.ArtifactListItem; -import io.apicurio.tests.ui.pages.ArtifactDetailsPage; -import io.apicurio.tests.ui.pages.ArtifactsListPage; -import io.apicurio.tests.ui.pages.UploadArtifactDialog; +import static org.junit.Assert.assertNotNull; public class RegistryUITester { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/UploadArtifactsIT.java b/integration-tests/src/test/java/io/apicurio/tests/ui/UploadArtifactsIT.java similarity index 95% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/UploadArtifactsIT.java rename to integration-tests/src/test/java/io/apicurio/tests/ui/UploadArtifactsIT.java index a67a10f75d..02f9e8f231 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/UploadArtifactsIT.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ui/UploadArtifactsIT.java @@ -15,12 +15,18 @@ */ package io.apicurio.tests.ui; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.io.ByteArrayInputStream; -import java.util.List; - +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.tests.ui.selenium.SeleniumChrome; +import io.apicurio.tests.ui.selenium.SeleniumProvider; +import io.apicurio.tests.ui.selenium.resources.ArtifactListItem; +import io.apicurio.tests.ui.pages.ArtifactDetailsPage; +import io.apicurio.tests.ui.pages.UploadArtifactDialog; +import io.apicurio.tests.utils.Constants; +import io.apicurio.registry.rest.client.RegistryClient; +import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; +import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.utils.tests.TestUtils; +import io.quarkus.test.junit.QuarkusIntegrationTest; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -29,21 +35,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.apicurio.registry.rest.client.RegistryClient; -import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; -import io.apicurio.registry.types.ArtifactType; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.selenium.SeleniumChrome; -import io.apicurio.tests.selenium.SeleniumProvider; -import io.apicurio.tests.selenium.resources.ArtifactListItem; -import io.apicurio.tests.ui.pages.ArtifactDetailsPage; -import io.apicurio.tests.ui.pages.UploadArtifactDialog; +import java.io.ByteArrayInputStream; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; @Tag(Constants.UI) @SeleniumChrome -public class UploadArtifactsIT extends ApicurioV2BaseIT { +@QuarkusIntegrationTest +public class UploadArtifactsIT extends ApicurioRegistryBaseIT { private static final Logger LOGGER = LoggerFactory.getLogger(UploadArtifactsIT.class); diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/pages/ArtifactDetailsPage.java b/integration-tests/src/test/java/io/apicurio/tests/ui/pages/ArtifactDetailsPage.java similarity index 96% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/pages/ArtifactDetailsPage.java rename to integration-tests/src/test/java/io/apicurio/tests/ui/pages/ArtifactDetailsPage.java index 8fe6b97293..bf17fcb223 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/pages/ArtifactDetailsPage.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ui/pages/ArtifactDetailsPage.java @@ -15,15 +15,14 @@ */ package io.apicurio.tests.ui.pages; -import static org.junit.Assert.assertNotNull; - -import java.time.Duration; - +import io.apicurio.tests.ui.selenium.SeleniumProvider; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedConditions; -import io.apicurio.tests.selenium.SeleniumProvider; +import java.time.Duration; + +import static org.junit.Assert.assertNotNull; public class ArtifactDetailsPage extends BasePage { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/pages/ArtifactsListPage.java b/integration-tests/src/test/java/io/apicurio/tests/ui/pages/ArtifactsListPage.java similarity index 97% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/pages/ArtifactsListPage.java rename to integration-tests/src/test/java/io/apicurio/tests/ui/pages/ArtifactsListPage.java index b1076487cc..c48499be3d 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/pages/ArtifactsListPage.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ui/pages/ArtifactsListPage.java @@ -15,12 +15,9 @@ */ package io.apicurio.tests.ui.pages; -import static org.junit.Assert.assertNotNull; -import java.time.Duration; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import io.apicurio.tests.ui.selenium.SeleniumProvider; +import io.apicurio.tests.ui.selenium.resources.ArtifactListItem; import org.openqa.selenium.By; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebElement; @@ -28,8 +25,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.apicurio.tests.selenium.SeleniumProvider; -import io.apicurio.tests.selenium.resources.ArtifactListItem; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertNotNull; public class ArtifactsListPage extends BasePage { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/pages/BasePage.java b/integration-tests/src/test/java/io/apicurio/tests/ui/pages/BasePage.java similarity index 95% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/pages/BasePage.java rename to integration-tests/src/test/java/io/apicurio/tests/ui/pages/BasePage.java index eadb42708f..157fef92fc 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/pages/BasePage.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ui/pages/BasePage.java @@ -15,10 +15,9 @@ */ package io.apicurio.tests.ui.pages; +import io.apicurio.tests.ui.selenium.SeleniumProvider; import org.openqa.selenium.By; -import io.apicurio.tests.selenium.SeleniumProvider; - public abstract class BasePage { protected SeleniumProvider selenium; diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/pages/UploadArtifactDialog.java b/integration-tests/src/test/java/io/apicurio/tests/ui/pages/UploadArtifactDialog.java similarity index 98% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/pages/UploadArtifactDialog.java rename to integration-tests/src/test/java/io/apicurio/tests/ui/pages/UploadArtifactDialog.java index 1ef07217ee..ab0cb9df36 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ui/pages/UploadArtifactDialog.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ui/pages/UploadArtifactDialog.java @@ -15,11 +15,10 @@ */ package io.apicurio.tests.ui.pages; +import io.apicurio.tests.ui.selenium.SeleniumProvider; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; -import io.apicurio.tests.selenium.SeleniumProvider; - public class UploadArtifactDialog extends BasePage { public UploadArtifactDialog(SeleniumProvider selenium) { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/SeleniumChrome.java b/integration-tests/src/test/java/io/apicurio/tests/ui/selenium/SeleniumChrome.java similarity index 93% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/SeleniumChrome.java rename to integration-tests/src/test/java/io/apicurio/tests/ui/selenium/SeleniumChrome.java index 406e5dcfd0..12d59a7bb0 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/SeleniumChrome.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ui/selenium/SeleniumChrome.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apicurio.tests.selenium; +package io.apicurio.tests.ui.selenium; + +import org.junit.jupiter.api.extension.ExtendWith; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import org.junit.jupiter.api.extension.ExtendWith; - import static java.lang.annotation.RetentionPolicy.RUNTIME; diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/SeleniumChromeExtension.java b/integration-tests/src/test/java/io/apicurio/tests/ui/selenium/SeleniumChromeExtension.java similarity index 82% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/SeleniumChromeExtension.java rename to integration-tests/src/test/java/io/apicurio/tests/ui/selenium/SeleniumChromeExtension.java index a87a6f1b28..5cafbb4757 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/SeleniumChromeExtension.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ui/selenium/SeleniumChromeExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,12 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apicurio.tests.selenium; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; +package io.apicurio.tests.ui.selenium; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.apicurio.registry.utils.tests.TestUtils; import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.AfterTestExecutionCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; @@ -33,7 +31,9 @@ import org.testcontainers.Testcontainers; import org.testcontainers.containers.BrowserWebDriverContainer; -import io.apicurio.registry.utils.tests.TestUtils; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; public class SeleniumChromeExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback, BeforeAllCallback, AfterAllCallback { @@ -78,20 +78,11 @@ private void deployChrome() throws Exception { LOGGER.info("Deploying chrome browser"); String uiUrl; WebDriver driver; - if (TestUtils.isExternalRegistry()) { - // we are supposing that if registry is deployed externally selenium will be as well - driver = getRemoteChromeDriver(); - String registrySeleniumHost = System.getenv().getOrDefault("REGISTRY_SELENIUM_HOST", TestUtils.getRegistryHost()); - String registrySeleniumPort = System.getenv().getOrDefault("REGISTRY_SELENIUM_PORT", Integer.toString(TestUtils.getRegistryPort())); - uiUrl = String.format("http://%s:%s/ui", registrySeleniumHost, registrySeleniumPort); - } else { - Testcontainers.exposeHostPorts(TestUtils.getRegistryPort()); - uiUrl = TestUtils.getRegistryUIUrl().replace("localhost", "host.testcontainers.internal"); - chrome = new BrowserWebDriverContainer() - .withCapabilities(buildChromeOptions()); - chrome.start(); - driver = chrome.getWebDriver(); - } + Testcontainers.exposeHostPorts(ApicurioRegistryBaseIT.getRegistryPort()); + uiUrl = ApicurioRegistryBaseIT.getRegistryUIUrl().replace("localhost", "host.testcontainers.internal"); + chrome = new BrowserWebDriverContainer().withCapabilities(buildChromeOptions()); + chrome.start(); + driver = chrome.getWebDriver(); SeleniumProvider.getInstance().setupDriver(driver); SeleniumProvider.getInstance().setUiUrl(uiUrl); deployed = true; @@ -107,7 +98,7 @@ private void deleteChrome() { } public static RemoteWebDriver getRemoteChromeDriver() throws Exception { - String seleniumHost = System.getenv().getOrDefault("SELENIUM_HOST", "localhost"); + String seleniumHost = System.getenv().getOrDefault("SELENIUM_HOST", "localhost"); String seleniumPort = System.getenv().getOrDefault("SELENIUM_PORT", "80"); return getRemoteDriver(seleniumHost, seleniumPort, buildChromeOptions()); } diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/SeleniumProvider.java b/integration-tests/src/test/java/io/apicurio/tests/ui/selenium/SeleniumProvider.java similarity index 98% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/SeleniumProvider.java rename to integration-tests/src/test/java/io/apicurio/tests/ui/selenium/SeleniumProvider.java index 0745d21588..74f6c658a0 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/SeleniumProvider.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ui/selenium/SeleniumProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apicurio.tests.selenium; +package io.apicurio.tests.ui.selenium; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.selenium.resources.WebItem; +import io.apicurio.tests.ui.selenium.resources.WebItem; import io.apicurio.tests.ui.pages.BasePage; +import io.apicurio.tests.utils.Constants; import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.extension.ExtensionContext; import org.openqa.selenium.By; diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/resources/ArtifactListItem.java b/integration-tests/src/test/java/io/apicurio/tests/ui/selenium/resources/ArtifactListItem.java similarity index 96% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/resources/ArtifactListItem.java rename to integration-tests/src/test/java/io/apicurio/tests/ui/selenium/resources/ArtifactListItem.java index 7d4471db55..2b24d88efb 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/resources/ArtifactListItem.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ui/selenium/resources/ArtifactListItem.java @@ -13,16 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apicurio.tests.selenium.resources; +package io.apicurio.tests.ui.selenium.resources; -import static io.apicurio.tests.ui.pages.BasePage.byDataTestId; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; +import static io.apicurio.tests.ui.pages.BasePage.byDataTestId; public class ArtifactListItem extends WebItem { @@ -70,7 +70,7 @@ public WebElement getViewArtifactLink() { } /** - * @see java.lang.Object#toString() + * @see Object#toString() */ @Override public String toString() { diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/resources/WebItem.java b/integration-tests/src/test/java/io/apicurio/tests/ui/selenium/resources/WebItem.java similarity index 94% rename from integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/resources/WebItem.java rename to integration-tests/src/test/java/io/apicurio/tests/ui/selenium/resources/WebItem.java index a3d0be81b4..8cec5931b4 100644 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/selenium/resources/WebItem.java +++ b/integration-tests/src/test/java/io/apicurio/tests/ui/selenium/resources/WebItem.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apicurio.tests.selenium.resources; +package io.apicurio.tests.ui.selenium.resources; import org.openqa.selenium.WebElement; diff --git a/integration-tests/src/test/java/io/apicurio/tests/utils/AbstractTestDataInitializer.java b/integration-tests/src/test/java/io/apicurio/tests/utils/AbstractTestDataInitializer.java new file mode 100644 index 0000000000..a115dfa22c --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/AbstractTestDataInitializer.java @@ -0,0 +1,67 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.tests.utils; + +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; + +import java.util.Collections; +import java.util.Map; + +public abstract class AbstractTestDataInitializer implements QuarkusTestResourceLifecycleManager { + + GenericContainer registryContainer; + String registryUrl; + + @Override + public int order() { + return 10000; + } + + @Override + public Map start() { + startRegistryApplication("quay.io/apicurio/apicurio-registry-mem:latest-release"); + return Collections.emptyMap(); + } + + @Override + public void stop() { + //Once the data is set, stop the old registry before running the tests. + if (registryContainer != null && registryContainer.isRunning()) { + registryContainer.stop(); + } + } + + public String startRegistryApplication(String imageName) { + registryContainer = new GenericContainer<>(imageName) + .withEnv(Map.of( + "QUARKUS_HTTP_PORT", "8081")) + .withNetworkMode("host"); + + registryContainer.start(); + registryContainer.waitingFor(Wait.forLogMessage(".*Installed features:*", 1)); + + this.registryUrl = "http://localhost:8081"; + + return registryUrl; + } + + public String getRegistryUrl() { + return registryUrl; + } +} diff --git a/integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/ArtifactUtils.java b/integration-tests/src/test/java/io/apicurio/tests/utils/ArtifactUtils.java similarity index 80% rename from integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/ArtifactUtils.java rename to integration-tests/src/test/java/io/apicurio/tests/utils/ArtifactUtils.java index 3c00bdf355..1e61658c87 100644 --- a/integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/ArtifactUtils.java +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/ArtifactUtils.java @@ -16,16 +16,16 @@ package io.apicurio.tests.utils; +import io.apicurio.tests.ApicurioRegistryBaseIT; +import io.restassured.response.Response; + import java.io.UncheckedIOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import io.apicurio.tests.common.utils.BaseHttpUtils; -import io.apicurio.tests.common.utils.subUtils.RestConstants; -import io.restassured.response.Response; /** - * @author Fabian Martinez + * @author Carles Arnal */ public class ArtifactUtils { @@ -40,11 +40,11 @@ public static Response getArtifact(String groupId, String artifactId, int return public static Response getArtifact(String groupId, String artifactId, String version, int returnCode) { return - BaseHttpUtils.getRequest(RestConstants.JSON, "/groups/" + encodeURIComponent(groupId) + "/artifacts/" + encodeURIComponent(artifactId) + "/" + version, returnCode); + BaseHttpUtils.getRequest(RestConstants.JSON, ApicurioRegistryBaseIT.getRegistryV2ApiUrl() + "/groups/" + encodeURIComponent(groupId) + "/artifacts/" + encodeURIComponent(artifactId) + "/" + version, returnCode); } public static Response createArtifact(String groupId, String artifactId, String artifact, int returnCode) { - return BaseHttpUtils.artifactPostRequest(artifactId, RestConstants.JSON, artifact, "/groups/" + encodeURIComponent(groupId) + "/artifacts", returnCode); + return BaseHttpUtils.artifactPostRequest(artifactId, RestConstants.JSON, artifact, ApicurioRegistryBaseIT.getRegistryV2ApiUrl() + "/groups/" + encodeURIComponent(groupId) + "/artifacts", returnCode); } // ================================================================================ diff --git a/integration-tests/src/test/java/io/apicurio/tests/utils/AvroGenericRecordSchemaFactory.java b/integration-tests/src/test/java/io/apicurio/tests/utils/AvroGenericRecordSchemaFactory.java new file mode 100644 index 0000000000..fb657d48c1 --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/AvroGenericRecordSchemaFactory.java @@ -0,0 +1,123 @@ +/* + * Copyright 2021 Red Hat + * + * Licensed 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 io.apicurio.tests.utils; + +import io.apicurio.registry.utils.IoUtil; +import io.apicurio.registry.utils.tests.TestUtils; +import org.apache.avro.Schema; +import org.apache.avro.generic.GenericData; +import org.apache.avro.generic.GenericRecord; + +import java.io.InputStream; +import java.util.List; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author Carles Arnal + */ +public class AvroGenericRecordSchemaFactory { + + private String namespace; + private String recordName; + private List schemaKeys; + private Schema schema; + + public AvroGenericRecordSchemaFactory(String namespace, String recordName, List schemaKeys) { + Objects.requireNonNull(namespace); + Objects.requireNonNull(recordName); + Objects.requireNonNull(schemaKeys); + this.namespace = namespace; + this.recordName = recordName; + this.schemaKeys = schemaKeys; + assertTrue(this.schemaKeys.size() > 0); + generateSchema(); + } + + public AvroGenericRecordSchemaFactory(String recordName, List schemaKeys) { + Objects.requireNonNull(recordName); + Objects.requireNonNull(schemaKeys); + this.recordName = recordName; + this.schemaKeys = schemaKeys; + assertTrue(this.schemaKeys.size() > 0); + generateSchema(); + } + + public AvroGenericRecordSchemaFactory(List schemaKeys) { + Objects.requireNonNull(schemaKeys); + this.recordName = TestUtils.generateSubject(); + this.schemaKeys = schemaKeys; + assertTrue(this.schemaKeys.size() > 0); + generateSchema(); + } + + public Schema generateSchema() { + if (schema == null) { + StringBuilder builder = new StringBuilder() + .append("{\"type\":\"record\"") + .append(",") + .append("\"name\":") + .append("\"") + .append(recordName) + .append("\""); + if (this.namespace != null) { + builder.append(",") + .append("\"namespace\":") + .append("\"") + .append(this.namespace) + .append("\""); + } + builder.append(",") + .append("\"fields\":["); + boolean first = true; + for (String schemaKey : schemaKeys) { + if (!first) { + builder.append(","); + } + builder.append("{\"name\":\"" + schemaKey + "\",\"type\":\"string\"}"); + first = false; + } + builder.append("]}"); + schema = new Schema.Parser().parse(builder.toString()); + } + return schema; + } + + public InputStream generateSchemaStream() { + return IoUtil.toStream(generateSchema().toString()); + } + + public byte[] generateSchemaBytes() { + return IoUtil.toBytes(generateSchema().toString()); + } + + public GenericRecord generateRecord(int count) { + Objects.requireNonNull(schema); + GenericRecord record = new GenericData.Record(schema); + String message = "value-" + count; + for (String schemaKey : schemaKeys) { + record.put(schemaKey, message); + } + return record; + } + + public boolean validateRecord(GenericRecord record) { + return this.schema.equals(record.getSchema()); + } + +} diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/BaseHttpUtils.java b/integration-tests/src/test/java/io/apicurio/tests/utils/BaseHttpUtils.java similarity index 99% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/BaseHttpUtils.java rename to integration-tests/src/test/java/io/apicurio/tests/utils/BaseHttpUtils.java index c25d58662a..cce1a544d0 100644 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/BaseHttpUtils.java +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/BaseHttpUtils.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package io.apicurio.tests.common.utils; +package io.apicurio.tests.utils; import io.restassured.response.Response; -import static io.restassured.RestAssured.given; - import java.net.URL; +import static io.restassured.RestAssured.given; + public class BaseHttpUtils { public static Response getRequest(String contentType, String endpoint, int returnCode) { diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/Constants.java b/integration-tests/src/test/java/io/apicurio/tests/utils/Constants.java similarity index 91% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/Constants.java rename to integration-tests/src/test/java/io/apicurio/tests/utils/Constants.java index 0f9f1b7221..53641cecaf 100644 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/Constants.java +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apicurio.tests.common; +package io.apicurio.tests.utils; import java.nio.file.Path; import java.nio.file.Paths; @@ -95,9 +95,4 @@ public interface Constants { public static final String CURRENT_ENV = "CURRENT_ENV"; public static final String CURRENT_ENV_MAS_REGEX = ".*mas.*"; - /** - * Env var used by the e2e testsuite to provide an already deployed kafka cluster in kubernetes in order to use it in the tests - */ - public static final String TESTS_SHARED_KAFKA_ENV_VAR = "TESTS_SHARED_KAFKA"; - } diff --git a/integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/CustomTestsUtils.java b/integration-tests/src/test/java/io/apicurio/tests/utils/CustomTestsUtils.java similarity index 73% rename from integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/CustomTestsUtils.java rename to integration-tests/src/test/java/io/apicurio/tests/utils/CustomTestsUtils.java index 3c9d778e5c..974523232c 100644 --- a/integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/CustomTestsUtils.java +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/CustomTestsUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,49 +16,53 @@ package io.apicurio.tests.utils; -import static org.junit.jupiter.api.Assertions.assertNotNull; - +import io.apicurio.registry.rest.client.RegistryClient; +import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; import io.apicurio.registry.rest.v2.beans.ArtifactReference; import io.apicurio.registry.rest.v2.beans.IfExists; import io.apicurio.registry.types.ContentTypes; -import org.apache.commons.codec.digest.DigestUtils; - -import io.apicurio.registry.rest.client.RegistryClient; -import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; import io.apicurio.registry.utils.IoUtil; import io.apicurio.registry.utils.tests.TestUtils; +import org.apache.commons.codec.digest.DigestUtils; import java.util.List; -/** - * @author Fabian Martinez - */ +import static org.junit.jupiter.api.Assertions.assertNotNull; + public class CustomTestsUtils { public static ArtifactData createArtifact(RegistryClient client, String type, String content) throws Exception { + return createArtifact(client, null, type, content); + } + + public static ArtifactData createArtifact(RegistryClient client, String group, String type, String content) throws Exception { String artifactId = TestUtils.generateArtifactId(); - ArtifactMetaData meta = client.createArtifact(null, artifactId, type, IoUtil.toStream(content)); + ArtifactMetaData meta = client.createArtifact(group, artifactId, type, IoUtil.toStream(content)); TestUtils.retry(() -> client.getContentByGlobalId(meta.getGlobalId())); assertNotNull(client.getLatestArtifact(meta.getGroupId(), meta.getId())); String contentHash = DigestUtils.sha256Hex(IoUtil.toBytes(content)); return new ArtifactData(meta, contentHash); } - public static ArtifactData createArtifactWithReferences(String artifactId, RegistryClient client, String type, String content, List references) throws Exception { - ArtifactMetaData meta = client.createArtifact(null, artifactId, null, type, IfExists.RETURN, false, null, null, ContentTypes.APPLICATION_CREATE_EXTENDED,null, null, IoUtil.toStream(content), references); + public static ArtifactData createArtifactWithReferences(String groupId, String artifactId, RegistryClient client, String type, String content, List references) throws Exception { + ArtifactMetaData meta = client.createArtifact(groupId, artifactId, null, type, IfExists.RETURN, false, null, null, ContentTypes.APPLICATION_CREATE_EXTENDED, null, null, IoUtil.toStream(content), references); TestUtils.retry(() -> client.getContentByGlobalId(meta.getGlobalId())); assertNotNull(client.getLatestArtifact(meta.getGroupId(), meta.getId())); String contentHash = DigestUtils.sha256Hex(IoUtil.toBytes(content)); return new ArtifactData(meta, contentHash); } + public static ArtifactData createArtifactWithReferences(String artifactId, RegistryClient client, String type, String content, List references) throws Exception { + return createArtifactWithReferences(null, artifactId, client, type, content, references); + } + public static class ArtifactData { public ArtifactMetaData meta; public String contentHash; + public ArtifactData(ArtifactMetaData meta, String contentHash) { this.meta = meta; this.contentHash = contentHash; } } - -} +} \ No newline at end of file diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/interfaces/ExtensionContextParameterResolver.java b/integration-tests/src/test/java/io/apicurio/tests/utils/ExtensionContextParameterResolver.java similarity index 94% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/interfaces/ExtensionContextParameterResolver.java rename to integration-tests/src/test/java/io/apicurio/tests/utils/ExtensionContextParameterResolver.java index 87a2948b78..838cfdd412 100644 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/interfaces/ExtensionContextParameterResolver.java +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/ExtensionContextParameterResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apicurio.tests.common.interfaces; +package io.apicurio.tests.utils; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ParameterContext; diff --git a/integration-tests/src/test/java/io/apicurio/tests/utils/KafkaFacade.java b/integration-tests/src/test/java/io/apicurio/tests/utils/KafkaFacade.java new file mode 100644 index 0000000000..cf9d60f518 --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/KafkaFacade.java @@ -0,0 +1,112 @@ +/* + * Copyright 2020 Red Hat + * + * Licensed 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 io.apicurio.tests.utils; + +import org.apache.kafka.clients.CommonClientConfigs; +import org.apache.kafka.clients.admin.AdminClient; +import org.apache.kafka.clients.admin.NewTopic; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.redpanda.RedpandaContainer; + +import java.util.Arrays; +import java.util.Properties; + +/** + * Facade class for simulate Kafka cluster + */ +public class KafkaFacade implements AutoCloseable { + static final Logger LOGGER = LoggerFactory.getLogger(KafkaFacade.class); + + private AdminClient client; + + private static KafkaFacade instance; + private RedpandaContainer kafkaContainer; + + public static KafkaFacade getInstance() { + if (instance == null) { + instance = new KafkaFacade(); + } + return instance; + } + + private KafkaFacade() { + //hidden constructor, singleton class + } + + public void createTopic(String topic, int partitions, int replicationFactor) { + adminClient().createTopics(Arrays.asList(new NewTopic(topic, partitions, (short) replicationFactor))); + } + + public String bootstrapServers() { + return kafkaContainer.getBootstrapServers(); + } + + public Properties connectionProperties() { + Properties properties = new Properties(); + properties.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers()); + properties.put(CommonClientConfigs.CONNECTIONS_MAX_IDLE_MS_CONFIG, 10000); + properties.put(CommonClientConfigs.REQUEST_TIMEOUT_MS_CONFIG, 5000); + return properties; + } + + private boolean isRunning() { + return kafkaContainer != null && kafkaContainer.isRunning(); + } + + public void startIfNeeded() { + if (isRunning()) { + LOGGER.info("Skipping deployment of kafka, because it's already deployed"); + } else { + start(); + } + } + + public void start() { + if (isRunning()) { + throw new IllegalStateException("Kafka cluster is already running"); + } + + LOGGER.info("Starting kafka container"); + this.kafkaContainer = new RedpandaContainer("docker.redpanda.com/vectorized/redpanda"); + kafkaContainer.addEnv("KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR", "1"); + kafkaContainer.addEnv("KAFKA_TRANSACTION_STATE_LOG_MIN_ISR", "1"); + kafkaContainer.start(); + + } + + public void stopIfPossible() throws Exception { + if (isRunning()) { + close(); + } + } + + public AdminClient adminClient() { + if (client == null) { + client = AdminClient.create(connectionProperties()); + } + return client; + } + + @Override + public void close() throws Exception { + LOGGER.info("Stopping kafka container"); + if (client != null) { + client.close(); + client = null; + } + } +} diff --git a/integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/LimitingProxy.java b/integration-tests/src/test/java/io/apicurio/tests/utils/LimitingProxy.java similarity index 99% rename from integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/LimitingProxy.java rename to integration-tests/src/test/java/io/apicurio/tests/utils/LimitingProxy.java index 05eecf8f67..2ff5422ab1 100644 --- a/integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/LimitingProxy.java +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/LimitingProxy.java @@ -30,7 +30,7 @@ import java.util.concurrent.CompletableFuture; /** - * @author Fabian Martinez + * @author Carles Arnal */ public abstract class LimitingProxy { diff --git a/integration-tests/testsuite/src/main/java/io/apicurio/tests/LoadBalanceRegistryClient.java b/integration-tests/src/test/java/io/apicurio/tests/utils/LoadBalanceRegistryClient.java similarity index 64% rename from integration-tests/testsuite/src/main/java/io/apicurio/tests/LoadBalanceRegistryClient.java rename to integration-tests/src/test/java/io/apicurio/tests/utils/LoadBalanceRegistryClient.java index d61ebe62bd..6473394b85 100644 --- a/integration-tests/testsuite/src/main/java/io/apicurio/tests/LoadBalanceRegistryClient.java +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/LoadBalanceRegistryClient.java @@ -14,30 +14,20 @@ * limitations under the License. */ -package io.apicurio.tests; - -import java.io.IOException; -import java.io.InputStream; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ThreadLocalRandom; - -import io.apicurio.registry.rest.v2.beans.ArtifactContent; -import io.apicurio.registry.rest.v2.beans.ArtifactOwner; -import io.apicurio.registry.rest.v2.beans.ArtifactReference; -import io.apicurio.registry.rest.v2.beans.GroupMetaData; -import io.apicurio.registry.rest.v2.beans.GroupSearchResults; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +package io.apicurio.tests.utils; import io.apicurio.registry.rest.client.RegistryClient; import io.apicurio.registry.rest.client.RegistryClientFactory; +import io.apicurio.registry.rest.v2.beans.ArtifactContent; import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; +import io.apicurio.registry.rest.v2.beans.ArtifactOwner; +import io.apicurio.registry.rest.v2.beans.ArtifactReference; import io.apicurio.registry.rest.v2.beans.ArtifactSearchResults; import io.apicurio.registry.rest.v2.beans.Comment; import io.apicurio.registry.rest.v2.beans.ConfigurationProperty; import io.apicurio.registry.rest.v2.beans.EditableMetaData; +import io.apicurio.registry.rest.v2.beans.GroupMetaData; +import io.apicurio.registry.rest.v2.beans.GroupSearchResults; import io.apicurio.registry.rest.v2.beans.IfExists; import io.apicurio.registry.rest.v2.beans.LogConfiguration; import io.apicurio.registry.rest.v2.beans.NamedLogConfiguration; @@ -52,9 +42,18 @@ import io.apicurio.registry.rest.v2.beans.VersionSearchResults; import io.apicurio.registry.types.RoleType; import io.apicurio.registry.types.RuleType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; /** - * @author Fabian Martinez + * @author Carles Arnal */ @SuppressWarnings("deprecation") public class LoadBalanceRegistryClient implements RegistryClient { @@ -70,6 +69,7 @@ public class RegistryClientHolder { /** * Constructor. + * * @param hosts */ public LoadBalanceRegistryClient(List hosts) { @@ -77,12 +77,12 @@ public LoadBalanceRegistryClient(List hosts) { this.targets = new LinkedList<>(); hosts.stream() - .forEach(h -> { - RegistryClientHolder c = new RegistryClientHolder(); - c.client = RegistryClientFactory.create(h); - c.host = h; - targets.add(c); - }); + .forEach(h -> { + RegistryClientHolder c = new RegistryClientHolder(); + c.client = RegistryClientFactory.create(h); + c.host = h; + targets.add(c); + }); } @@ -101,7 +101,7 @@ private synchronized RegistryClient getTarget() { * @param groupId * @param artifactId * @return - * @see io.apicurio.registry.rest.client.RegistryClient#getLatestArtifact(java.lang.String, java.lang.String) + * @see RegistryClient#getLatestArtifact(String, String) */ @Override public InputStream getLatestArtifact(String groupId, String artifactId) { @@ -109,7 +109,7 @@ public InputStream getLatestArtifact(String groupId, String artifactId) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#updateArtifact(java.lang.String, java.lang.String, java.io.InputStream) + * @see RegistryClient#updateArtifact(String, String, InputStream) */ @Override public ArtifactMetaData updateArtifact(String groupId, String artifactId, String version, String name, String description, String contentType, InputStream data) { @@ -117,7 +117,7 @@ public ArtifactMetaData updateArtifact(String groupId, String artifactId, String } /** - * @see io.apicurio.registry.rest.client.RegistryClient#updateArtifact(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.io.InputStream, java.util.List) + * @see RegistryClient#updateArtifact(String, String, String, String, String, InputStream, List) */ @Override public ArtifactMetaData updateArtifact(String groupId, String artifactId, String version, String name, String description, InputStream data, List references) { @@ -125,7 +125,7 @@ public ArtifactMetaData updateArtifact(String groupId, String artifactId, String } /** - * @see io.apicurio.registry.rest.client.RegistryClient#deleteArtifact(java.lang.String, java.lang.String) + * @see RegistryClient#deleteArtifact(String, String) */ @Override public void deleteArtifact(String groupId, String artifactId) { @@ -133,7 +133,7 @@ public void deleteArtifact(String groupId, String artifactId) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getArtifactMetaData(java.lang.String, java.lang.String) + * @see RegistryClient#getArtifactMetaData(String, String) */ @Override public ArtifactMetaData getArtifactMetaData(String groupId, String artifactId) { @@ -146,7 +146,7 @@ public ArtifactOwner getArtifactOwner(String groupId, String artifactId) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#updateArtifactMetaData(java.lang.String, java.lang.String, io.apicurio.registry.rest.v2.beans.EditableMetaData) + * @see RegistryClient#updateArtifactMetaData(String, String, EditableMetaData) */ @Override public void updateArtifactMetaData(String groupId, String artifactId, EditableMetaData data) { @@ -159,11 +159,11 @@ public void updateArtifactOwner(String groupId, String artifactId, ArtifactOwner } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getArtifactVersionMetaDataByContent(java.lang.String, java.lang.String, java.lang.Boolean, java.io.InputStream) + * @see RegistryClient#getArtifactVersionMetaDataByContent(String, String, Boolean, InputStream) */ @Override public VersionMetaData getArtifactVersionMetaDataByContent(String groupId, String artifactId, - Boolean canonical, String contentType, InputStream data) { + Boolean canonical, String contentType, InputStream data) { return getTarget().getArtifactVersionMetaDataByContent(groupId, artifactId, canonical, contentType, data); } @@ -173,16 +173,16 @@ public VersionMetaData getArtifactVersionMetaDataByContent(String groupId, Strin } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getArtifactVersionMetaDataByContent(java.lang.String, java.lang.String, java.io.InputStream) + * @see RegistryClient#getArtifactVersionMetaDataByContent(String, String, InputStream) */ @Override public VersionMetaData getArtifactVersionMetaDataByContent(String groupId, String artifactId, - InputStream data) { + InputStream data) { return getTarget().getArtifactVersionMetaDataByContent(groupId, artifactId, data); } /** - * @see io.apicurio.registry.rest.client.RegistryClient#listArtifactRules(java.lang.String, java.lang.String) + * @see RegistryClient#listArtifactRules(String, String) */ @Override public List listArtifactRules(String groupId, String artifactId) { @@ -190,7 +190,7 @@ public List listArtifactRules(String groupId, String artifactId) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#createArtifactRule(java.lang.String, java.lang.String, io.apicurio.registry.rest.v2.beans.Rule) + * @see RegistryClient#createArtifactRule(String, String, Rule) */ @Override public void createArtifactRule(String groupId, String artifactId, Rule data) { @@ -198,7 +198,7 @@ public void createArtifactRule(String groupId, String artifactId, Rule data) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#deleteArtifactRules(java.lang.String, java.lang.String) + * @see RegistryClient#deleteArtifactRules(String, String) */ @Override public void deleteArtifactRules(String groupId, String artifactId) { @@ -206,7 +206,7 @@ public void deleteArtifactRules(String groupId, String artifactId) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getArtifactRuleConfig(java.lang.String, java.lang.String, io.apicurio.registry.types.RuleType) + * @see RegistryClient#getArtifactRuleConfig(String, String, RuleType) */ @Override public Rule getArtifactRuleConfig(String groupId, String artifactId, RuleType rule) { @@ -214,7 +214,7 @@ public Rule getArtifactRuleConfig(String groupId, String artifactId, RuleType ru } /** - * @see io.apicurio.registry.rest.client.RegistryClient#updateArtifactRuleConfig(java.lang.String, java.lang.String, io.apicurio.registry.types.RuleType, io.apicurio.registry.rest.v2.beans.Rule) + * @see RegistryClient#updateArtifactRuleConfig(String, String, RuleType, Rule) */ @Override public Rule updateArtifactRuleConfig(String groupId, String artifactId, RuleType rule, Rule data) { @@ -222,7 +222,7 @@ public Rule updateArtifactRuleConfig(String groupId, String artifactId, RuleType } /** - * @see io.apicurio.registry.rest.client.RegistryClient#deleteArtifactRule(java.lang.String, java.lang.String, io.apicurio.registry.types.RuleType) + * @see RegistryClient#deleteArtifactRule(String, String, RuleType) */ @Override public void deleteArtifactRule(String groupId, String artifactId, RuleType rule) { @@ -230,7 +230,7 @@ public void deleteArtifactRule(String groupId, String artifactId, RuleType rule) } /** - * @see io.apicurio.registry.rest.client.RegistryClient#updateArtifactState(java.lang.String, java.lang.String, io.apicurio.registry.rest.v2.beans.UpdateState) + * @see RegistryClient#updateArtifactState(String, String, UpdateState) */ @Override public void updateArtifactState(String groupId, String artifactId, UpdateState data) { @@ -238,7 +238,7 @@ public void updateArtifactState(String groupId, String artifactId, UpdateState d } /** - * @see io.apicurio.registry.rest.client.RegistryClient#testUpdateArtifact(java.lang.String, java.lang.String, java.io.InputStream) + * @see RegistryClient#testUpdateArtifact(String, String, InputStream) */ @Override public void testUpdateArtifact(String groupId, String artifactId, String contentType, InputStream data) { @@ -246,7 +246,7 @@ public void testUpdateArtifact(String groupId, String artifactId, String content } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getArtifactVersion(java.lang.String, java.lang.String, java.lang.String) + * @see RegistryClient#getArtifactVersion(String, String, String) */ @Override public InputStream getArtifactVersion(String groupId, String artifactId, String version) { @@ -254,7 +254,7 @@ public InputStream getArtifactVersion(String groupId, String artifactId, String } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getArtifactVersionMetaData(java.lang.String, java.lang.String, java.lang.String) + * @see RegistryClient#getArtifactVersionMetaData(String, String, String) */ @Override public VersionMetaData getArtifactVersionMetaData(String groupId, String artifactId, String version) { @@ -262,16 +262,16 @@ public VersionMetaData getArtifactVersionMetaData(String groupId, String artifac } /** - * @see io.apicurio.registry.rest.client.RegistryClient#updateArtifactVersionMetaData(java.lang.String, java.lang.String, java.lang.String, io.apicurio.registry.rest.v2.beans.EditableMetaData) + * @see RegistryClient#updateArtifactVersionMetaData(String, String, String, EditableMetaData) */ @Override public void updateArtifactVersionMetaData(String groupId, String artifactId, String version, - EditableMetaData data) { + EditableMetaData data) { getTarget().updateArtifactVersionMetaData(groupId, artifactId, version, data); } /** - * @see io.apicurio.registry.rest.client.RegistryClient#deleteArtifactVersionMetaData(java.lang.String, java.lang.String, java.lang.String) + * @see RegistryClient#deleteArtifactVersionMetaData(String, String, String) */ @Override public void deleteArtifactVersionMetaData(String groupId, String artifactId, String version) { @@ -279,43 +279,43 @@ public void deleteArtifactVersionMetaData(String groupId, String artifactId, Str } /** - * @see io.apicurio.registry.rest.client.RegistryClient#updateArtifactVersionState(java.lang.String, java.lang.String, java.lang.String, io.apicurio.registry.rest.v2.beans.UpdateState) + * @see RegistryClient#updateArtifactVersionState(String, String, String, UpdateState) */ @Override public void updateArtifactVersionState(String groupId, String artifactId, String version, - UpdateState data) { + UpdateState data) { getTarget().updateArtifactVersionState(groupId, artifactId, version, data); } /** - * @see io.apicurio.registry.rest.client.RegistryClient#listArtifactVersions(java.lang.String, java.lang.String, java.lang.Integer, java.lang.Integer) + * @see RegistryClient#listArtifactVersions(String, String, Integer, Integer) */ @Override public VersionSearchResults listArtifactVersions(String groupId, String artifactId, Integer offset, - Integer limit) { + Integer limit) { return getTarget().listArtifactVersions(groupId, artifactId, offset, limit); } /** - * @see io.apicurio.registry.rest.client.RegistryClient#createArtifactVersion(java.lang.String, java.lang.String, java.lang.String, java.io.InputStream) + * @see RegistryClient#createArtifactVersion(String, String, String, InputStream) */ @Override public VersionMetaData createArtifactVersion(String groupId, String artifactId, String version, String name, String description, String contentType, - InputStream data) { - return getTarget().createArtifactVersion(groupId, artifactId, version, name, description,contentType, data); + InputStream data) { + return getTarget().createArtifactVersion(groupId, artifactId, version, name, description, contentType, data); } /** - * @see io.apicurio.registry.rest.client.RegistryClient#listArtifactsInGroup(java.lang.String, io.apicurio.registry.rest.v2.beans.SortBy, io.apicurio.registry.rest.v2.beans.SortOrder, java.lang.Integer, java.lang.Integer) + * @see RegistryClient#listArtifactsInGroup(String, SortBy, SortOrder, Integer, Integer) */ @Override public ArtifactSearchResults listArtifactsInGroup(String groupId, SortBy orderBy, SortOrder order, - Integer offset, Integer limit) { + Integer offset, Integer limit) { return getTarget().listArtifactsInGroup(groupId, orderBy, order, offset, limit); } /** - * @see io.apicurio.registry.rest.client.RegistryClient#listArtifactsInGroup(java.lang.String) + * @see RegistryClient#listArtifactsInGroup(String) */ @Override public ArtifactSearchResults listArtifactsInGroup(String groupId) { @@ -323,11 +323,11 @@ public ArtifactSearchResults listArtifactsInGroup(String groupId) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#createArtifact(java.lang.String, java.lang.String, java.lang.String, io.apicurio.registry.types.ArtifactType, io.apicurio.registry.rest.v2.beans.IfExists, java.lang.Boolean, java.io.InputStream) + * @see RegistryClient#createArtifact(String, String, String, io.apicurio.registry.types.ArtifactType, IfExists, Boolean, InputStream) */ @Override public ArtifactMetaData createArtifact(String groupId, String artifactId, String version, - String artifactType, IfExists ifExists, Boolean canonical, String name, String description, String contentType, String fromURL, String artifactSHA, InputStream data) { + String artifactType, IfExists ifExists, Boolean canonical, String name, String description, String contentType, String fromURL, String artifactSHA, InputStream data) { return getTarget().createArtifact(groupId, artifactId, version, artifactType, ifExists, canonical, name, description, contentType, fromURL, artifactSHA, data); } @@ -337,7 +337,7 @@ public ArtifactMetaData createArtifact(String groupId, String artifactId, String } /** - * @see io.apicurio.registry.rest.client.RegistryClient#createArtifact(java.lang.String, java.lang.String, java.io.InputStream) + * @see RegistryClient#createArtifact(String, String, InputStream) */ @Override public ArtifactMetaData createArtifact(String groupId, String artifactId, InputStream data) { @@ -345,7 +345,7 @@ public ArtifactMetaData createArtifact(String groupId, String artifactId, InputS } /** - * @see io.apicurio.registry.rest.client.RegistryClient#createArtifact(java.lang.String, java.lang.String, java.io.InputStream, java.util.List) + * @see RegistryClient#createArtifact(String, String, InputStream, List) */ @Override public ArtifactMetaData createArtifact(String groupId, String artifactId, InputStream data, List references) { @@ -353,34 +353,34 @@ public ArtifactMetaData createArtifact(String groupId, String artifactId, InputS } /** - * @see io.apicurio.registry.rest.client.RegistryClient#createArtifact(java.lang.String, java.lang.String, java.lang.String, java.io.InputStream) + * @see RegistryClient#createArtifact(String, String, String, InputStream) */ @Override public ArtifactMetaData createArtifactWithVersion(String groupId, String artifactId, String version, - InputStream data) { + InputStream data) { return getTarget().createArtifactWithVersion(groupId, artifactId, version, data); } /** - * @see io.apicurio.registry.rest.client.RegistryClient#createArtifact(java.lang.String, java.lang.String, io.apicurio.registry.types.ArtifactType, java.io.InputStream) + * @see RegistryClient#createArtifact(String, String, io.apicurio.registry.types.ArtifactType, InputStream) */ @Override public ArtifactMetaData createArtifact(String groupId, String artifactId, String artifactType, - InputStream data) { + InputStream data) { return getTarget().createArtifact(groupId, artifactId, artifactType, data); } /** - * @see io.apicurio.registry.rest.client.RegistryClient#createArtifact(java.lang.String, java.lang.String, io.apicurio.registry.types.ArtifactType, io.apicurio.registry.rest.v2.beans.IfExists, java.io.InputStream) + * @see RegistryClient#createArtifact(String, String, io.apicurio.registry.types.ArtifactType, IfExists, InputStream) */ @Override public ArtifactMetaData createArtifact(String groupId, String artifactId, String artifactType, - IfExists ifExists, InputStream data) { + IfExists ifExists, InputStream data) { return getTarget().createArtifact(groupId, artifactId, artifactType, ifExists, data); } /** - * @see io.apicurio.registry.rest.client.RegistryClient#deleteArtifactsInGroup(java.lang.String) + * @see RegistryClient#deleteArtifactsInGroup(String) */ @Override public void deleteArtifactsInGroup(String groupId) { @@ -408,7 +408,7 @@ public GroupSearchResults listGroups(SortBy orderBy, SortOrder order, Integer of } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getContentById(long) + * @see RegistryClient#getContentById(long) */ @Override public InputStream getContentById(long contentId) { @@ -416,7 +416,7 @@ public InputStream getContentById(long contentId) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getContentByGlobalId(long) + * @see RegistryClient#getContentByGlobalId(long) */ @Override public InputStream getContentByGlobalId(long globalId) { @@ -429,7 +429,7 @@ public InputStream getContentByGlobalId(long globalId, Boolean canonical, Boolea } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getContentByHash(java.lang.String, java.lang.Boolean) + * @see RegistryClient#getContentByHash(String, Boolean) */ @Override public InputStream getContentByHash(String contentHash, Boolean canonical) { @@ -437,7 +437,7 @@ public InputStream getContentByHash(String contentHash, Boolean canonical) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getContentByHash(java.lang.String) + * @see RegistryClient#getContentByHash(String) */ @Override public InputStream getContentByHash(String contentHash) { @@ -445,26 +445,26 @@ public InputStream getContentByHash(String contentHash) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#searchArtifacts(java.lang.String, java.lang.String, java.lang.String, java.util.List, java.util.List, java.lang.Long, java.lang.Long, io.apicurio.registry.rest.v2.beans.SortBy, io.apicurio.registry.rest.v2.beans.SortOrder, java.lang.Integer, java.lang.Integer) + * @see RegistryClient#searchArtifacts(String, String, String, List, List, Long, Long, SortBy, SortOrder, Integer, Integer) */ @Override public ArtifactSearchResults searchArtifacts(String group, String name, String description, - List labels, List properties, Long globalId, Long contentId, SortBy orderBy, - SortOrder order, Integer offset, Integer limit) { + List labels, List properties, Long globalId, Long contentId, SortBy orderBy, + SortOrder order, Integer offset, Integer limit) { return getTarget().searchArtifacts(group, name, description, labels, properties, globalId, contentId, orderBy, order, offset, limit); } /** - * @see io.apicurio.registry.rest.client.RegistryClient#searchArtifactsByContent(java.io.InputStream, io.apicurio.registry.rest.v2.beans.SortBy, io.apicurio.registry.rest.v2.beans.SortOrder, java.lang.Integer, java.lang.Integer) + * @see RegistryClient#searchArtifactsByContent(InputStream, SortBy, SortOrder, Integer, Integer) */ @Override public ArtifactSearchResults searchArtifactsByContent(InputStream data, SortBy orderBy, SortOrder order, - Integer offset, Integer limit) { + Integer offset, Integer limit) { return getTarget().searchArtifactsByContent(data, orderBy, order, offset, limit); } /** - * @see io.apicurio.registry.rest.client.RegistryClient#listGlobalRules() + * @see RegistryClient#listGlobalRules() */ @Override public List listGlobalRules() { @@ -472,7 +472,7 @@ public List listGlobalRules() { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#createGlobalRule(io.apicurio.registry.rest.v2.beans.Rule) + * @see RegistryClient#createGlobalRule(Rule) */ @Override public void createGlobalRule(Rule data) { @@ -480,8 +480,7 @@ public void createGlobalRule(Rule data) { } /** - * - * @see io.apicurio.registry.rest.client.RegistryClient#deleteAllGlobalRules() + * @see RegistryClient#deleteAllGlobalRules() */ @Override public void deleteAllGlobalRules() { @@ -489,7 +488,7 @@ public void deleteAllGlobalRules() { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getGlobalRuleConfig(io.apicurio.registry.types.RuleType) + * @see RegistryClient#getGlobalRuleConfig(RuleType) */ @Override public Rule getGlobalRuleConfig(RuleType rule) { @@ -497,7 +496,7 @@ public Rule getGlobalRuleConfig(RuleType rule) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#updateGlobalRuleConfig(io.apicurio.registry.types.RuleType, io.apicurio.registry.rest.v2.beans.Rule) + * @see RegistryClient#updateGlobalRuleConfig(RuleType, Rule) */ @Override public Rule updateGlobalRuleConfig(RuleType rule, Rule data) { @@ -505,7 +504,7 @@ public Rule updateGlobalRuleConfig(RuleType rule, Rule data) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#deleteGlobalRule(io.apicurio.registry.types.RuleType) + * @see RegistryClient#deleteGlobalRule(RuleType) */ @Override public void deleteGlobalRule(RuleType rule) { @@ -513,7 +512,7 @@ public void deleteGlobalRule(RuleType rule) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#listLogConfigurations() + * @see RegistryClient#listLogConfigurations() */ @Override public List listLogConfigurations() { @@ -521,7 +520,7 @@ public List listLogConfigurations() { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getLogConfiguration(java.lang.String) + * @see RegistryClient#getLogConfiguration(String) */ @Override public NamedLogConfiguration getLogConfiguration(String logger) { @@ -529,7 +528,7 @@ public NamedLogConfiguration getLogConfiguration(String logger) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#setLogConfiguration(java.lang.String, io.apicurio.registry.rest.v2.beans.LogConfiguration) + * @see RegistryClient#setLogConfiguration(String, LogConfiguration) */ @Override public NamedLogConfiguration setLogConfiguration(String logger, LogConfiguration data) { @@ -537,7 +536,7 @@ public NamedLogConfiguration setLogConfiguration(String logger, LogConfiguration } /** - * @see io.apicurio.registry.rest.client.RegistryClient#removeLogConfiguration(java.lang.String) + * @see RegistryClient#removeLogConfiguration(String) */ @Override public NamedLogConfiguration removeLogConfiguration(String logger) { @@ -565,7 +564,7 @@ public List getArtifactReferencesByCoordinates(String groupId } /** - * @see io.apicurio.registry.rest.client.RegistryClient#setNextRequestHeaders(java.util.Map) + * @see RegistryClient#setNextRequestHeaders(Map) */ @Override public void setNextRequestHeaders(Map requestHeaders) { @@ -573,7 +572,7 @@ public void setNextRequestHeaders(Map requestHeaders) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getHeaders() + * @see RegistryClient#getHeaders() */ @Override public Map getHeaders() { @@ -581,7 +580,7 @@ public Map getHeaders() { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#exportData() + * @see RegistryClient#exportData() */ @Override public InputStream exportData() { @@ -589,7 +588,7 @@ public InputStream exportData() { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#importData(java.io.InputStream) + * @see RegistryClient#importData(InputStream) */ @Override public void importData(InputStream data) { @@ -597,7 +596,7 @@ public void importData(InputStream data) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#importData(java.io.InputStream, boolean, boolean) + * @see RegistryClient#importData(InputStream, boolean, boolean) */ @Override public void importData(InputStream data, boolean preserveGlobalIds, boolean preserveContentIds) { @@ -605,7 +604,7 @@ public void importData(InputStream data, boolean preserveGlobalIds, boolean pres } /** - * @see io.apicurio.registry.rest.client.RegistryClient#createRoleMapping(io.apicurio.registry.rest.v2.beans.RoleMapping) + * @see RegistryClient#createRoleMapping(RoleMapping) */ @Override public void createRoleMapping(RoleMapping data) { @@ -613,7 +612,7 @@ public void createRoleMapping(RoleMapping data) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#deleteRoleMapping(java.lang.String) + * @see RegistryClient#deleteRoleMapping(String) */ @Override public void deleteRoleMapping(String principalId) { @@ -621,7 +620,7 @@ public void deleteRoleMapping(String principalId) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getRoleMapping(java.lang.String) + * @see RegistryClient#getRoleMapping(String) */ @Override public RoleMapping getRoleMapping(String principalId) { @@ -629,7 +628,7 @@ public RoleMapping getRoleMapping(String principalId) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#listRoleMappings() + * @see RegistryClient#listRoleMappings() */ @Override public List listRoleMappings() { @@ -637,7 +636,7 @@ public List listRoleMappings() { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#updateRoleMapping(java.lang.String, io.apicurio.registry.types.RoleType) + * @see RegistryClient#updateRoleMapping(String, RoleType) */ @Override public void updateRoleMapping(String principalId, RoleType role) { @@ -645,7 +644,7 @@ public void updateRoleMapping(String principalId, RoleType role) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#listConfigProperties() + * @see RegistryClient#listConfigProperties() */ @Override public List listConfigProperties() { @@ -653,7 +652,7 @@ public List listConfigProperties() { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getConfigProperty(java.lang.String) + * @see RegistryClient#getConfigProperty(String) */ @Override public ConfigurationProperty getConfigProperty(String propertyName) { @@ -661,7 +660,7 @@ public ConfigurationProperty getConfigProperty(String propertyName) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#setConfigProperty(java.lang.String, java.lang.String) + * @see RegistryClient#setConfigProperty(String, String) */ @Override public void setConfigProperty(String propertyName, String propertyValue) { @@ -669,7 +668,7 @@ public void setConfigProperty(String propertyName, String propertyValue) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#deleteConfigProperty(java.lang.String) + * @see RegistryClient#deleteConfigProperty(String) */ @Override public void deleteConfigProperty(String propertyName) { @@ -677,39 +676,39 @@ public void deleteConfigProperty(String propertyName) { } /** - * @see io.apicurio.registry.rest.client.RegistryClient#getCurrentUserInfo() + * @see RegistryClient#getCurrentUserInfo() */ @Override public UserInfo getCurrentUserInfo() { return getTarget().getCurrentUserInfo(); } - + /** - * @see io.apicurio.registry.rest.client.RegistryClient#getArtifactVersionComments(java.lang.String, java.lang.String, java.lang.String) + * @see RegistryClient#getArtifactVersionComments(String, String, String) */ @Override public List getArtifactVersionComments(String groupId, String artifactId, String version) { return getTarget().getArtifactVersionComments(groupId, artifactId, version); } - + /** - * @see io.apicurio.registry.rest.client.RegistryClient#addArtifactVersionComment(java.lang.String, java.lang.String, java.lang.String, io.apicurio.registry.rest.v2.beans.NewComment) + * @see RegistryClient#addArtifactVersionComment(String, String, String, NewComment) */ @Override public Comment addArtifactVersionComment(String groupId, String artifactId, String version, NewComment comment) { return getTarget().addArtifactVersionComment(groupId, artifactId, version, comment); } - + /** - * @see io.apicurio.registry.rest.client.RegistryClient#deleteArtifactVersionComment(java.lang.String, java.lang.String, java.lang.String, java.lang.String) + * @see RegistryClient#deleteArtifactVersionComment(String, String, String, String) */ @Override public void deleteArtifactVersionComment(String groupId, String artifactId, String version, String commentId) { getTarget().deleteArtifactVersionComment(groupId, artifactId, version, commentId); } - + /** - * @see io.apicurio.registry.rest.client.RegistryClient#editArtifactVersionComment(java.lang.String, java.lang.String, java.lang.String, java.lang.String, io.apicurio.registry.rest.v2.beans.NewComment) + * @see RegistryClient#editArtifactVersionComment(String, String, String, String, NewComment) */ @Override public void editArtifactVersionComment(String groupId, String artifactId, String version, String commentId, NewComment comment) { diff --git a/integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/RateLimitingProxy.java b/integration-tests/src/test/java/io/apicurio/tests/utils/RateLimitingProxy.java similarity index 98% rename from integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/RateLimitingProxy.java rename to integration-tests/src/test/java/io/apicurio/tests/utils/RateLimitingProxy.java index 747890d008..97ff227058 100644 --- a/integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/RateLimitingProxy.java +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/RateLimitingProxy.java @@ -20,7 +20,7 @@ import org.slf4j.LoggerFactory; /** - * @author Fabian Martinez + * @author Carles Arnal */ public class RateLimitingProxy extends LimitingProxy { diff --git a/integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/RegistryWaitUtils.java b/integration-tests/src/test/java/io/apicurio/tests/utils/RegistryWaitUtils.java similarity index 88% rename from integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/RegistryWaitUtils.java rename to integration-tests/src/test/java/io/apicurio/tests/utils/RegistryWaitUtils.java index f8038b1b33..ee40ac3dd0 100644 --- a/integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/RegistryWaitUtils.java +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/RegistryWaitUtils.java @@ -18,11 +18,9 @@ import io.apicurio.registry.rest.client.RegistryClient; import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.LoadBalanceRegistryClient; -import io.apicurio.tests.LoadBalanceRegistryClient.RegistryClientHolder; /** - * @author Fabian Martinez + * @author Carles Arnal */ public class RegistryWaitUtils { @@ -43,7 +41,7 @@ public static void retry(RegistryClient registryClient, ConsumerExc { - for (RegistryClientHolder target : nodes) { + for (LoadBalanceRegistryClient.RegistryClientHolder target : nodes) { registryOp.run(target.client); } }); diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/subUtils/RestConstants.java b/integration-tests/src/test/java/io/apicurio/tests/utils/RestConstants.java similarity index 94% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/subUtils/RestConstants.java rename to integration-tests/src/test/java/io/apicurio/tests/utils/RestConstants.java index 6993ed45cf..87e3a4bef1 100644 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/utils/subUtils/RestConstants.java +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/RestConstants.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apicurio.tests.common.utils.subUtils; +package io.apicurio.tests.utils; /** * @author Ales Justin diff --git a/integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/RetryLimitingProxy.java b/integration-tests/src/test/java/io/apicurio/tests/utils/RetryLimitingProxy.java similarity index 95% rename from integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/RetryLimitingProxy.java rename to integration-tests/src/test/java/io/apicurio/tests/utils/RetryLimitingProxy.java index b9e23e8db7..17195630ea 100644 --- a/integration-tests/testsuite/src/main/java/io/apicurio/tests/utils/RetryLimitingProxy.java +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/RetryLimitingProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ /** * Block `n` first requests, then allow the rest through. * - * @author Fabian Martinez + * @author Carles Arnal * @author Jakub Senko m@jsenko.net */ public class RetryLimitingProxy extends LimitingProxy { @@ -44,4 +44,4 @@ protected boolean allowed() { } return true; } -} +} \ No newline at end of file diff --git a/integration-tests/src/test/java/io/apicurio/tests/utils/TenantManagerTestResource.java b/integration-tests/src/test/java/io/apicurio/tests/utils/TenantManagerTestResource.java new file mode 100644 index 0000000000..7af9502f18 --- /dev/null +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/TenantManagerTestResource.java @@ -0,0 +1,122 @@ +/* + * Copyright 2023 Red Hat + * + * Licensed 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 io.apicurio.tests.utils; + +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.model.ExposedPort; +import com.github.dockerjava.api.model.PortBinding; +import com.github.dockerjava.api.model.Ports; +import io.apicurio.registry.utils.tests.TestUtils; +import io.apicurio.tenantmanager.api.datamodel.SortBy; +import io.apicurio.tenantmanager.api.datamodel.SortOrder; +import io.apicurio.tenantmanager.api.datamodel.TenantStatusValue; +import io.apicurio.tenantmanager.client.TenantManagerClient; +import io.apicurio.tenantmanager.client.TenantManagerClientImpl; +import io.apicurio.tests.dbupgrade.SqlStorageUpgradeIT; +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; +import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.Collections; +import java.util.Map; +import java.util.function.Consumer; + +public class TenantManagerTestResource implements QuarkusTestResourceLifecycleManager { + + private static final Logger logger = LoggerFactory.getLogger(SqlStorageUpgradeIT.class); + + GenericContainer tenantManagerContainer; + EmbeddedPostgres database; + TenantManagerClient tenantManager; + + @Override + public int order() { + return 10000; + } + + @Override + public Map start() { + if (!Boolean.parseBoolean(System.getProperty("cluster.tests"))) { + try { + database = EmbeddedPostgres.builder().setPort(5431).start(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + + String datasourceUrl = database.getJdbcUrl("postgres", "postgres"); + + if (System.getProperty("os.name").contains("Mac OS")) { + datasourceUrl = datasourceUrl.replace("localhost", "docker.for.mac.host.internal"); + } + + String tenantManagerUrl = startTenantManagerApplication("quay.io/apicurio/apicurio-tenant-manager-api:latest", datasourceUrl, "postgres", "postgres"); + + try { + //Warm up until the tenant manager is ready. + TestUtils.retry(() -> { + getTenantManagerClient(tenantManagerUrl).listTenants(TenantStatusValue.READY, 0, 1, SortOrder.asc, SortBy.tenantId); + }); + + } catch (Exception ex) { + logger.warn("Error filling old registry with information: ", ex); + } + } + + return Collections.emptyMap(); + } + + private String startTenantManagerApplication(String tenantManagerImageName, String jdbcUrl, String username, String password) { + int hostPort = 8585; + int containerExposedPort = 8585; + //Using a deprecated feature is ok, this test will be gone in Registry 3.x + Consumer cmd = e -> e.withPortBindings(new PortBinding(Ports.Binding.bindPort(hostPort), new ExposedPort(containerExposedPort))); + + tenantManagerContainer = new GenericContainer<>(tenantManagerImageName) + .withEnv(Map.of("DATASOURCE_URL", jdbcUrl, + "REGISTRY_ROUTE_URL", "", + "DATASOURCE_USERNAME", username, + "DATASOURCE_PASSWORD", password, + "QUARKUS_HTTP_PORT", "8585", + "ENABLE_TEST_STATUS_TRANSITION", "true")) + .withExposedPorts(containerExposedPort) + .withCreateContainerCmdModifier(cmd); + + tenantManagerContainer.start(); + tenantManagerContainer.waitingFor(Wait.forLogMessage(".*Installed features:*", 1)); + + return "http://localhost:" + tenantManagerContainer.getMappedPort(8585); + } + + @Override + public void stop() { + if (tenantManagerContainer != null && tenantManagerContainer.isRunning()) { + tenantManagerContainer.stop(); + } + } + + public synchronized TenantManagerClient getTenantManagerClient(String tenantManagerUrl) { + if (tenantManager == null) { + tenantManager = new TenantManagerClientImpl(tenantManagerUrl, Collections.emptyMap(), null); + } + return tenantManager; + } +} diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/interfaces/TestSeparator.java b/integration-tests/src/test/java/io/apicurio/tests/utils/TestSeparator.java similarity index 95% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/interfaces/TestSeparator.java rename to integration-tests/src/test/java/io/apicurio/tests/utils/TestSeparator.java index 8349417a03..0149edde03 100644 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/interfaces/TestSeparator.java +++ b/integration-tests/src/test/java/io/apicurio/tests/utils/TestSeparator.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Red Hat + * Copyright 2023 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apicurio.tests.common.interfaces; +package io.apicurio.tests.utils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Collections; diff --git a/integration-tests/src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener b/integration-tests/src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener new file mode 100644 index 0000000000..913442603b --- /dev/null +++ b/integration-tests/src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener @@ -0,0 +1 @@ +io.apicurio.deployment.RegistryDeploymentManager \ No newline at end of file diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v1.json b/integration-tests/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v1.json similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v1.json rename to integration-tests/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v1.json diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v2.json b/integration-tests/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v2.json similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v2.json rename to integration-tests/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v2.json diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/avro/multi-field_v1.json b/integration-tests/src/test/resources/artifactTypes/avro/multi-field_v1.json similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/avro/multi-field_v1.json rename to integration-tests/src/test/resources/artifactTypes/avro/multi-field_v1.json diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/avro/multi-field_v2.json b/integration-tests/src/test/resources/artifactTypes/avro/multi-field_v2.json similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/avro/multi-field_v2.json rename to integration-tests/src/test/resources/artifactTypes/avro/multi-field_v2.json diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/graphql/swars_v1.graphql b/integration-tests/src/test/resources/artifactTypes/graphql/swars_v1.graphql similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/graphql/swars_v1.graphql rename to integration-tests/src/test/resources/artifactTypes/graphql/swars_v1.graphql diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/graphql/swars_v2.graphql b/integration-tests/src/test/resources/artifactTypes/graphql/swars_v2.graphql similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/graphql/swars_v2.graphql rename to integration-tests/src/test/resources/artifactTypes/graphql/swars_v2.graphql diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/jsonSchema/person_v1.json b/integration-tests/src/test/resources/artifactTypes/jsonSchema/person_v1.json similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/jsonSchema/person_v1.json rename to integration-tests/src/test/resources/artifactTypes/jsonSchema/person_v1.json diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/jsonSchema/person_v2.json b/integration-tests/src/test/resources/artifactTypes/jsonSchema/person_v2.json similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/jsonSchema/person_v2.json rename to integration-tests/src/test/resources/artifactTypes/jsonSchema/person_v2.json diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/kafkaConnect/simple_v1.json b/integration-tests/src/test/resources/artifactTypes/kafkaConnect/simple_v1.json similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/kafkaConnect/simple_v1.json rename to integration-tests/src/test/resources/artifactTypes/kafkaConnect/simple_v1.json diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/kafkaConnect/simple_v2.json b/integration-tests/src/test/resources/artifactTypes/kafkaConnect/simple_v2.json similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/kafkaConnect/simple_v2.json rename to integration-tests/src/test/resources/artifactTypes/kafkaConnect/simple_v2.json diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/openapi/2.0-petstore_v1.json b/integration-tests/src/test/resources/artifactTypes/openapi/2.0-petstore_v1.json similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/openapi/2.0-petstore_v1.json rename to integration-tests/src/test/resources/artifactTypes/openapi/2.0-petstore_v1.json diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/openapi/2.0-petstore_v2.json b/integration-tests/src/test/resources/artifactTypes/openapi/2.0-petstore_v2.json similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/openapi/2.0-petstore_v2.json rename to integration-tests/src/test/resources/artifactTypes/openapi/2.0-petstore_v2.json diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/openapi/3.0-petstore_v1.json b/integration-tests/src/test/resources/artifactTypes/openapi/3.0-petstore_v1.json similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/openapi/3.0-petstore_v1.json rename to integration-tests/src/test/resources/artifactTypes/openapi/3.0-petstore_v1.json diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/openapi/3.0-petstore_v2.json b/integration-tests/src/test/resources/artifactTypes/openapi/3.0-petstore_v2.json similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/openapi/3.0-petstore_v2.json rename to integration-tests/src/test/resources/artifactTypes/openapi/3.0-petstore_v2.json diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/protobuf/tutorial_v1.proto b/integration-tests/src/test/resources/artifactTypes/protobuf/tutorial_v1.proto similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/protobuf/tutorial_v1.proto rename to integration-tests/src/test/resources/artifactTypes/protobuf/tutorial_v1.proto diff --git a/integration-tests/integration-tests-common/src/test/resources/artifactTypes/protobuf/tutorial_v2.proto b/integration-tests/src/test/resources/artifactTypes/protobuf/tutorial_v2.proto similarity index 100% rename from integration-tests/integration-tests-common/src/test/resources/artifactTypes/protobuf/tutorial_v2.proto rename to integration-tests/src/test/resources/artifactTypes/protobuf/tutorial_v2.proto diff --git a/new-system-tests/src/test/resources/keycloak/01_realm.yaml b/integration-tests/src/test/resources/infra/auth/keycloak.yml similarity index 67% rename from new-system-tests/src/test/resources/keycloak/01_realm.yaml rename to integration-tests/src/test/resources/infra/auth/keycloak.yml index a39ca493ca..05bc29ecb5 100644 --- a/new-system-tests/src/test/resources/keycloak/01_realm.yaml +++ b/integration-tests/src/test/resources/infra/auth/keycloak.yml @@ -1,15 +1,10 @@ apiVersion: v1 -kind: ConfigMap -metadata: - name: keycloak-realm data: realm.json: | { "id": "registry", "realm": "registry", - "displayName": "Registry", - "displayNameHtml": "", - "notBefore": 0, + "notBefore": 1600933598, "defaultSignatureAlgorithm": "RS256", "revokeRefreshToken": false, "refreshTokenMaxReuse": 0, @@ -34,14 +29,14 @@ data: "oauth2DeviceCodeLifespan": 600, "oauth2DevicePollingInterval": 5, "enabled": true, - "sslRequired": "none", - "registrationAllowed": false, + "sslRequired": "external", + "registrationAllowed": true, "registrationEmailAsUsername": false, - "rememberMe": false, + "rememberMe": true, "verifyEmail": false, "loginWithEmailAllowed": true, "duplicateEmailsAllowed": false, - "resetPasswordAllowed": false, + "resetPasswordAllowed": true, "editUsernameAllowed": false, "bruteForceProtected": false, "permanentLockout": false, @@ -54,15 +49,7 @@ data: "roles": { "realm": [ { - "id": "e48f2083-2d50-43a9-ba9b-d72c3f6e5729", - "name": "sr-readonly", - "composite": false, - "clientRole": false, - "containerId": "registry", - "attributes": {} - }, - { - "id": "318f2243-0488-4529-9894-89e2c732e3b4", + "id": "91363f21-2a57-4d65-954b-b3cd45d9f69c", "name": "sr-admin", "composite": false, "clientRole": false, @@ -70,59 +57,53 @@ data: "attributes": {} }, { - "id": "17c6e003-925a-4224-bb97-d78c8c800ed8", - "name": "sr-developer", - "composite": false, - "clientRole": false, - "containerId": "registry", - "attributes": {} - }, - { - "id": "8c78bd37-f32f-4469-b83a-8f80904d8126", - "name": "test-admin-role", + "id": "b2a0eee7-c761-49a1-9426-441d467f3f98", + "name": "offline_access", + "description": "${role_offline-access}", "composite": false, "clientRole": false, "containerId": "registry", "attributes": {} }, { - "id": "47c2690a-e3cd-480e-af92-b8f9344db129", - "name": "offline_access", - "description": "${role_offline-access}", + "id": "2c0937ba-7b1f-424c-927c-33cd2ccfdc62", + "name": "sr-developer", "composite": false, "clientRole": false, "containerId": "registry", "attributes": {} }, { - "id": "aa492438-73a7-4b64-b5cd-dfc5d0365767", - "name": "test-developer-role", + "id": "1ffdda65-2476-4ad5-b1e8-9f8af44a897b", + "name": "uma_authorization", + "description": "${role_uma_authorization}", "composite": false, "clientRole": false, "containerId": "registry", "attributes": {} }, { - "id": "963b835d-1510-4232-b5ea-9cd7dbfee834", - "name": "uma_authorization", - "description": "${role_uma_authorization}", + "id": "a06b0184-e5bc-44c2-ae5b-4315754405f1", + "name": "sr-readonly", "composite": false, "clientRole": false, "containerId": "registry", "attributes": {} }, { - "id": "a9f90ac2-f83f-4c71-b878-cb38dac76244", + "id": "33a21208-808d-444f-9aa7-fdf3dc9536ce", "name": "default-roles-registry", "description": "${role_default-roles}", "composite": true, "composites": { "realm": [ + "User", "offline_access", "uma_authorization" ], "client": { "account": [ + "view-applications", "view-profile", "manage-account" ] @@ -133,8 +114,8 @@ data: "attributes": {} }, { - "id": "e6318643-c14e-4eca-82b4-3d415f00aeaa", - "name": "test-readonly-role", + "id": "43dd3a54-4447-4703-ad0e-cd558f78c803", + "name": "User", "composite": false, "clientRole": false, "containerId": "registry", @@ -142,273 +123,267 @@ data: } ], "client": { + "admin-client": [], "realm-management": [ { - "id": "b9adae2b-cb5f-4024-aa3b-86d8debd386d", - "name": "query-groups", - "description": "${role_query-groups}", + "id": "dcd9e6f5-3158-4e90-ba06-e5e80e0fa05c", + "name": "query-users", + "description": "${role_query-users}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "3a5308e8-5123-41b5-968f-e13e685abba5", - "name": "view-events", - "description": "${role_view-events}", + "id": "0b4d5891-c2d9-409d-b4bd-b5daa11e059e", + "name": "view-identity-providers", + "description": "${role_view-identity-providers}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "5b091c48-11a3-453c-b329-ec0c6608a738", - "name": "view-users", - "description": "${role_view-users}", + "id": "2fee03d5-f4da-418f-843e-0a70cba351c7", + "name": "view-clients", + "description": "${role_view-clients}", "composite": true, "composites": { "client": { "realm-management": [ - "query-groups", - "query-users" + "query-clients" ] } }, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "b4e28a9e-eb3f-4610-a948-cd238e516b17", - "name": "query-realms", - "description": "${role_query-realms}", + "id": "82e5542a-8ec4-4e76-aa2f-75c0eb707aad", + "name": "manage-realm", + "description": "${role_manage-realm}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "4f0382c4-d828-430c-b753-5c059b1818c0", - "name": "manage-users", - "description": "${role_manage-users}", + "id": "4d0d41a7-ac3f-47c6-a227-de0dc1c861de", + "name": "query-groups", + "description": "${role_query-groups}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "8a86f1ad-3628-485b-a3c9-2871b6427cd0", - "name": "query-clients", - "description": "${role_query-clients}", + "id": "4d69772c-08d4-4735-954c-4115788cecbc", + "name": "view-events", + "description": "${role_view-events}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "b75c389f-30b7-4262-98d5-9ab591239614", - "name": "manage-realm", - "description": "${role_manage-realm}", + "id": "8a79c5f9-2d14-44e4-b2bc-7e4cb955b721", + "name": "query-realms", + "description": "${role_query-realms}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "d5711b9d-96ca-4e4b-96e7-7fc1c14b207e", - "name": "query-users", - "description": "${role_query-users}", + "id": "0b54c521-9672-49b5-89ab-603fe4da9693", + "name": "manage-events", + "description": "${role_manage-events}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "555f350f-c3a4-47e2-b95c-9806a39e3821", - "name": "impersonation", - "description": "${role_impersonation}", + "id": "3fa4a674-d449-4576-b207-f89e556ba617", + "name": "manage-authorization", + "description": "${role_manage-authorization}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "840bc8e3-657f-4712-bc95-a402b38ec876", - "name": "view-clients", - "description": "${role_view-clients}", + "id": "7a9c60b9-f2e6-4fec-ac85-7b3633a0f116", + "name": "realm-admin", + "description": "${role_realm-admin}", "composite": true, "composites": { "client": { "realm-management": [ - "query-clients" + "query-users", + "view-identity-providers", + "view-clients", + "manage-realm", + "query-groups", + "view-events", + "query-realms", + "manage-events", + "manage-authorization", + "view-users", + "view-authorization", + "manage-identity-providers", + "impersonation", + "query-clients", + "manage-clients", + "view-realm", + "create-client", + "manage-users" ] } }, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "6e8cb1c1-12e9-4bd2-9204-5db7f6b2a501", - "name": "view-realm", - "description": "${role_view-realm}", - "composite": false, + "id": "f7c5550f-8233-4347-967d-4905cbd36cec", + "name": "view-users", + "description": "${role_view-users}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "query-users", + "query-groups" + ] + } + }, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "feae0bae-58d3-4203-82db-fa90c350566a", - "name": "manage-clients", - "description": "${role_manage-clients}", + "id": "05c8c44f-8554-4a91-b9cb-be6995144040", + "name": "view-authorization", + "description": "${role_view-authorization}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "90178bb2-c2fa-401a-a09b-9b297f401ccf", - "name": "create-client", - "description": "${role_create-client}", + "id": "e91f859e-d5c3-48d6-b0b0-5ff2710db3c9", + "name": "impersonation", + "description": "${role_impersonation}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "32d8bfd0-8ab2-4258-b907-a0fbff303bb1", - "name": "manage-events", - "description": "${role_manage-events}", + "id": "a0c6b281-3915-45c2-9af7-d7d4f669419a", + "name": "manage-identity-providers", + "description": "${role_manage-identity-providers}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "1765333a-dcfb-4171-a164-ccdbf7fafe80", - "name": "manage-identity-providers", - "description": "${role_manage-identity-providers}", + "id": "e6e6d63d-d161-444f-a58d-30875b076d16", + "name": "query-clients", + "description": "${role_query-clients}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "9128df3d-4c89-497f-9776-071c68ce5c74", - "name": "view-authorization", - "description": "${role_view-authorization}", + "id": "4c592e93-ba00-4661-af7d-bc50b800c060", + "name": "manage-clients", + "description": "${role_manage-clients}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "98235a5d-5de9-43d9-b43e-6b456aa623af", - "name": "view-identity-providers", - "description": "${role_view-identity-providers}", + "id": "e50b557e-c79e-4e5a-92ee-a56b9c3925e1", + "name": "view-realm", + "description": "${role_view-realm}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "418bbf83-ff93-4ade-85ad-6e2ac0b2323e", - "name": "realm-admin", - "description": "${role_realm-admin}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "view-events", - "query-groups", - "view-users", - "query-realms", - "manage-users", - "query-clients", - "manage-realm", - "query-users", - "impersonation", - "view-clients", - "view-realm", - "manage-clients", - "create-client", - "manage-events", - "manage-identity-providers", - "view-identity-providers", - "view-authorization", - "manage-authorization" - ] - } - }, + "id": "34b1cafe-ee16-42d0-9ec1-c6829e01f78c", + "name": "create-client", + "description": "${role_create-client}", + "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} }, { - "id": "694b7458-4d03-4d29-9a7f-b4e2084b09fa", - "name": "manage-authorization", - "description": "${role_manage-authorization}", + "id": "7d1d9c1e-6c1c-41eb-b8d9-6460e4d243f0", + "name": "manage-users", + "description": "${role_manage-users}", "composite": false, "clientRole": true, - "containerId": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", + "containerId": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", "attributes": {} } ], + "apicurio-registry": [], + "readonly-client": [], "security-admin-console": [], "admin-cli": [], - "registry-client-api": [], "account-console": [], + "developer-client": [], + "wrong-client": [], "broker": [ { - "id": "caec3768-ab15-4f4e-be7b-849cc6f6e698", + "id": "1ec1b34a-682d-44e7-b1fb-1d235b27b9d0", "name": "read-token", "description": "${role_read-token}", "composite": false, "clientRole": true, - "containerId": "da152db3-ae2e-4eea-a66d-f4440ecaa34b", + "containerId": "717c272b-ed48-4d5a-a3cb-da5d3d3ba528", "attributes": {} } ], - "test-client-api": [], "account": [ { - "id": "b566ff36-853b-4749-9586-fa821eb62929", - "name": "manage-account-links", - "description": "${role_manage-account-links}", - "composite": false, - "clientRole": true, - "containerId": "d9209155-32c2-4d4e-9620-63836f5f502e", - "attributes": {} - }, - { - "id": "268d318d-b5da-434c-8529-00e6750d3c22", - "name": "view-applications", - "description": "${role_view-applications}", + "id": "e81eb004-b1ac-49a7-84ab-d2b86228c89d", + "name": "delete-account", + "description": "${role_delete-account}", "composite": false, "clientRole": true, - "containerId": "d9209155-32c2-4d4e-9620-63836f5f502e", + "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", "attributes": {} }, { - "id": "1c0e354a-3106-411a-85e3-05467a20727c", - "name": "view-consent", - "description": "${role_view-consent}", + "id": "a49e7c09-b2df-4468-96f0-65b8591774ad", + "name": "manage-account-links", + "description": "${role_manage-account-links}", "composite": false, "clientRole": true, - "containerId": "d9209155-32c2-4d4e-9620-63836f5f502e", + "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", "attributes": {} }, { - "id": "32911cea-a527-4a4a-913f-055f857fea6b", - "name": "delete-account", - "description": "${role_delete-account}", + "id": "b6e07306-8781-4538-800b-32b2ffc5d57c", + "name": "view-applications", + "description": "${role_view-applications}", "composite": false, "clientRole": true, - "containerId": "d9209155-32c2-4d4e-9620-63836f5f502e", + "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", "attributes": {} }, { - "id": "f3cf9880-5b40-4e7e-8018-3d420c3ae93d", + "id": "aa763dea-9699-4899-95bc-f2cef6692b1d", "name": "manage-consent", "description": "${role_manage-consent}", "composite": true, @@ -420,20 +395,29 @@ data: } }, "clientRole": true, - "containerId": "d9209155-32c2-4d4e-9620-63836f5f502e", + "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", + "attributes": {} + }, + { + "id": "6b67af9e-5c96-4944-8189-7d6c7ecc1f80", + "name": "view-consent", + "description": "${role_view-consent}", + "composite": false, + "clientRole": true, + "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", "attributes": {} }, { - "id": "84728845-7283-405b-aa10-4f27bfe35aae", + "id": "aad246c6-eb26-4cfd-b840-e113021f5b9b", "name": "view-profile", "description": "${role_view-profile}", "composite": false, "clientRole": true, - "containerId": "d9209155-32c2-4d4e-9620-63836f5f502e", + "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", "attributes": {} }, { - "id": "5544eee6-28c5-4b10-ab8a-7e0f9b4ee7c9", + "id": "de065b56-c31c-41df-b110-186a798d7f17", "name": "manage-account", "description": "${role_manage-account}", "composite": true, @@ -445,16 +429,16 @@ data: } }, "clientRole": true, - "containerId": "d9209155-32c2-4d4e-9620-63836f5f502e", + "containerId": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", "attributes": {} } ], - "registry-client-ui": [] + "registry-api": [] } }, "groups": [], "defaultRole": { - "id": "a9f90ac2-f83f-4c71-b878-cb38dac76244", + "id": "33a21208-808d-444f-9aa7-fdf3dc9536ce", "name": "default-roles-registry", "description": "${role_default-roles}", "composite": true, @@ -500,20 +484,125 @@ data: "webAuthnPolicyPasswordlessAcceptableAaguids": [], "users": [ { - "id": "0d51fa42-7fc1-4785-8965-554ba1883e25", - "createdTimestamp": 1669368265017, - "username": "service-account-test-client-api", + "id": "5d3833aa-2aba-4fc4-a546-00dfe1d56bb5", + "createdTimestamp": 1687335757025, + "username": "service-account-admin-client", "enabled": true, "totp": false, "emailVerified": false, - "serviceAccountClientId": "test-client-api", + "serviceAccountClientId": "admin-client", "disableableCredentialTypes": [], "requiredActions": [], "realmRoles": [ + "sr-admin", "default-roles-registry" ], "notBefore": 0, "groups": [] + }, + { + "id": "0f1c31e8-a357-4f05-90cc-3374973b6088", + "createdTimestamp": 1608543288931, + "username": "service-account-developer-client", + "enabled": true, + "totp": false, + "emailVerified": false, + "serviceAccountClientId": "developer-client", + "disableableCredentialTypes": [], + "requiredActions": [], + "realmRoles": [ + "offline_access", + "uma_authorization", + "sr-developer", + "User" + ], + "clientRoles": { + "account": [ + "view-applications", + "view-profile", + "manage-account" + ] + }, + "notBefore": 0, + "groups": [] + }, + { + "id": "0f1d31e8-a358-4f05-90cc-3374453b7088", + "createdTimestamp": 1608543288931, + "username": "service-account-wrong-client", + "enabled": true, + "totp": false, + "emailVerified": false, + "serviceAccountClientId": "wrong-client", + "disableableCredentialTypes": [], + "requiredActions": [], + "realmRoles": [ + "offline_access", + "uma_authorization", + "sr-developer", + "User" + ], + "clientRoles": { + "account": [ + "view-applications", + "view-profile", + "manage-account" + ] + }, + "notBefore": 0, + "groups": [] + }, + { + "id": "06fec980-2e11-4c7f-a8fb-3d285f30b0b0", + "createdTimestamp": 1608543552621, + "username": "service-account-readonly-client", + "enabled": true, + "totp": false, + "emailVerified": false, + "serviceAccountClientId": "readonly-client", + "disableableCredentialTypes": [], + "requiredActions": [], + "realmRoles": [ + "offline_access", + "uma_authorization", + "sr-readonly", + "User" + ], + "clientRoles": { + "account": [ + "view-applications", + "view-profile", + "manage-account" + ] + }, + "notBefore": 0, + "groups": [] + }, + { + "id": "70dbaf4a-fcef-449c-9184-121b6cedb115", + "createdTimestamp": 1607594319706, + "username": "service-account-registry-api", + "enabled": true, + "totp": false, + "emailVerified": false, + "serviceAccountClientId": "registry-api", + "disableableCredentialTypes": [], + "requiredActions": [], + "realmRoles": [ + "sr-admin", + "offline_access", + "uma_authorization", + "User" + ], + "clientRoles": { + "account": [ + "view-applications", + "view-profile", + "manage-account" + ] + }, + "notBefore": 0, + "groups": [] } ], "scopeMappings": [ @@ -536,7 +625,7 @@ data: }, "clients": [ { - "id": "d9209155-32c2-4d4e-9620-63836f5f502e", + "id": "d7c9d8ec-d826-4979-970e-4d5c4d9e358b", "clientId": "account", "name": "${client_account}", "rootUrl": "${authBaseUrl}", @@ -545,6 +634,7 @@ data: "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", + "secret": "test1", "redirectUris": [ "/realms/registry/account/*" ], @@ -556,20 +646,17 @@ data: "implicitFlowEnabled": false, "directAccessGrantsEnabled": false, "serviceAccountsEnabled": false, - "publicClient": true, + "publicClient": false, "frontchannelLogout": false, "protocol": "openid-connect", - "attributes": { - "post.logout.redirect.uris": "+" - }, + "attributes": {}, "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": false, "nodeReRegistrationTimeout": 0, "defaultClientScopes": [ "web-origins", - "acr", - "profile", "roles", + "profile", "email" ], "optionalClientScopes": [ @@ -580,7 +667,7 @@ data: ] }, { - "id": "211a6686-c36d-4d4e-85ff-113d1d00df5e", + "id": "ae8d8aa5-5991-42a1-8ca8-eec12b6717f7", "clientId": "account-console", "name": "${client_account-console}", "rootUrl": "${authBaseUrl}", @@ -589,6 +676,7 @@ data: "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", + "secret": "test1", "redirectUris": [ "/realms/registry/account/*" ], @@ -604,7 +692,6 @@ data: "frontchannelLogout": false, "protocol": "openid-connect", "attributes": { - "post.logout.redirect.uris": "+", "pkce.code.challenge.method": "S256" }, "authenticationFlowBindingOverrides": {}, @@ -612,7 +699,7 @@ data: "nodeReRegistrationTimeout": 0, "protocolMappers": [ { - "id": "a6eb9b91-d678-4852-8ccb-9df28f9d63a2", + "id": "b852b0a0-768e-4f42-badd-14cf7d2d227a", "name": "audience resolve", "protocol": "openid-connect", "protocolMapper": "oidc-audience-resolve-mapper", @@ -622,9 +709,8 @@ data: ], "defaultClientScopes": [ "web-origins", - "acr", - "profile", "roles", + "profile", "email" ], "optionalClientScopes": [ @@ -635,13 +721,14 @@ data: ] }, { - "id": "7e801f70-6c2b-4a8d-a948-da701cddf4ef", + "id": "80b79538-8665-4188-921d-f4d0ad1f3113", "clientId": "admin-cli", "name": "${client_admin-cli}", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", + "secret": "test1", "redirectUris": [], "webOrigins": [], "notBefore": 0, @@ -660,9 +747,8 @@ data: "nodeReRegistrationTimeout": 0, "defaultClientScopes": [ "web-origins", - "acr", - "profile", "roles", + "profile", "email" ], "optionalClientScopes": [ @@ -673,72 +759,111 @@ data: ] }, { - "id": "da152db3-ae2e-4eea-a66d-f4440ecaa34b", - "clientId": "broker", - "name": "${client_broker}", + "id": "21c5668a-4fba-46e9-8ac3-831e5d907eb6", + "clientId": "admin-client", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "redirectUris": [], - "webOrigins": [], + "secret": "test1", + "redirectUris": [ + "*" + ], + "webOrigins": [ + "*" + ], "notBefore": 0, - "bearerOnly": true, + "bearerOnly": false, "consentRequired": false, "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "acr", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "f3cdc4a2-2a41-47f3-b1b3-c3f457ae2dee", - "clientId": "realm-management", - "name": "${client_realm-management}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": true, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, + "implicitFlowEnabled": true, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": true, "publicClient": false, "frontchannelLogout": false, "protocol": "openid-connect", - "attributes": {}, + "attributes": { + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "frontchannel.logout.session.required": "false", + "oauth2.device.authorization.grant.enabled": "false", + "backchannel.logout.revoke.offline.tokens": "false", + "saml.server.signature.keyinfo.ext": "false", + "use.refresh.tokens": "true", + "oidc.ciba.grant.enabled": "false", + "backchannel.logout.session.required": "true", + "client_credentials.use_refresh_token": "false", + "require.pushed.authorization.requests": "false", + "saml.client.signature": "false", + "saml.allow.ecp.flow": "false", + "id.token.as.detached.signature": "false", + "saml.assertion.signature": "false", + "client.secret.creation.time": "1687335786", + "saml.encrypt": "false", + "login_theme": "keycloak", + "saml.server.signature": "false", + "exclude.session.state.from.auth.response": "false", + "saml.artifact.binding": "false", + "saml_force_name_id_format": "false", + "acr.loa.map": "{}", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "token.response.type.bearer.lower-case": "false", + "saml.onetimeuse.condition": "false" + }, "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "protocolMappers": [ + { + "id": "ef8fe948-b172-4d59-bffe-4ba46d0c0b09", + "name": "Client IP Address", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientAddress", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientAddress", + "jsonType.label": "String" + } + }, + { + "id": "7e443600-bf35-49df-b0ea-5b5c51f9c590", + "name": "Client ID", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientId", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientId", + "jsonType.label": "String" + } + }, + { + "id": "605d578d-5532-4f83-bd97-fe6bf72c5fee", + "name": "Client Host", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientHost", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientHost", + "jsonType.label": "String" + } + } + ], "defaultClientScopes": [ "web-origins", "acr", - "profile", "roles", + "profile", "email" ], "optionalClientScopes": [ @@ -749,12 +874,13 @@ data: ] }, { - "id": "013ef9eb-c05b-4cfc-bbc7-825f032a64af", - "clientId": "registry-client-api", + "id": "1fa15256-6427-47fa-a144-b0b784e834c6", + "clientId": "apicurio-registry", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", + "secret": "test1", "redirectUris": [ "*" ], @@ -765,25 +891,35 @@ data: "bearerOnly": false, "consentRequired": false, "standardFlowEnabled": true, - "implicitFlowEnabled": true, + "implicitFlowEnabled": false, "directAccessGrantsEnabled": true, "serviceAccountsEnabled": false, "publicClient": true, "frontchannelLogout": false, "protocol": "openid-connect", "attributes": { - "post.logout.redirect.uris": "+" + "saml.assertion.signature": "false", + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "saml.encrypt": "false", + "saml.server.signature": "false", + "saml.server.signature.keyinfo.ext": "false", + "exclude.session.state.from.auth.response": "false", + "saml_force_name_id_format": "false", + "saml.client.signature": "false", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "saml.onetimeuse.condition": "false" }, "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": true, "nodeReRegistrationTimeout": -1, "defaultClientScopes": [ "web-origins", - "acr", - "profile", "roles", - "email", - "user-attributes" + "profile", + "email" ], "optionalClientScopes": [ "address", @@ -793,39 +929,34 @@ data: ] }, { - "id": "f29295a2-042b-4206-99ef-7fc18429bf0d", - "clientId": "registry-client-ui", + "id": "717c272b-ed48-4d5a-a3cb-da5d3d3ba528", + "clientId": "broker", + "name": "${client_broker}", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "redirectUris": [ - "*" - ], - "webOrigins": [ - "*" - ], + "secret": "test1", + "redirectUris": [], + "webOrigins": [], "notBefore": 0, "bearerOnly": false, "consentRequired": false, "standardFlowEnabled": true, - "implicitFlowEnabled": true, + "implicitFlowEnabled": false, "directAccessGrantsEnabled": false, "serviceAccountsEnabled": false, - "publicClient": true, + "publicClient": false, "frontchannelLogout": false, "protocol": "openid-connect", - "attributes": { - "post.logout.redirect.uris": "+" - }, + "attributes": {}, "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, "defaultClientScopes": [ "web-origins", - "acr", - "profile", "roles", + "profile", "email" ], "optionalClientScopes": [ @@ -836,60 +967,113 @@ data: ] }, { - "id": "910840ea-2e8b-48d1-a045-cf2615fe7d22", - "clientId": "security-admin-console", - "name": "${client_security-admin-console}", - "rootUrl": "${authAdminUrl}", - "baseUrl": "/admin/registry/console/", + "id": "af889033-76c2-41ae-a368-67d5789f4b87", + "clientId": "developer-client", + "rootUrl": "", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", + "secret": "test1", "redirectUris": [ - "/admin/registry/console/*" + "*" ], "webOrigins": [ - "+" + "*" ], "notBefore": 0, "bearerOnly": false, "consentRequired": false, "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, + "implicitFlowEnabled": true, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": true, + "publicClient": false, "frontchannelLogout": false, "protocol": "openid-connect", "attributes": { - "post.logout.redirect.uris": "+", - "pkce.code.challenge.method": "S256" + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "frontchannel.logout.session.required": "false", + "oauth2.device.authorization.grant.enabled": "false", + "backchannel.logout.revoke.offline.tokens": "false", + "saml.server.signature.keyinfo.ext": "false", + "use.refresh.tokens": "true", + "oidc.ciba.grant.enabled": "false", + "backchannel.logout.session.required": "false", + "client_credentials.use_refresh_token": "false", + "require.pushed.authorization.requests": "false", + "saml.client.signature": "false", + "saml.allow.ecp.flow": "false", + "id.token.as.detached.signature": "false", + "saml.assertion.signature": "false", + "saml.encrypt": "false", + "login_theme": "keycloak", + "saml.server.signature": "false", + "exclude.session.state.from.auth.response": "false", + "saml.artifact.binding": "false", + "saml_force_name_id_format": "false", + "acr.loa.map": "{}", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "token.response.type.bearer.lower-case": "false", + "saml.onetimeuse.condition": "false" }, "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, "protocolMappers": [ { - "id": "d662ba4f-ec24-488e-b9b9-5540de77426e", - "name": "locale", + "id": "aeb67b03-0bbd-432c-a329-0a04363e974a", + "name": "Client ID", "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", + "protocolMapper": "oidc-usersessionmodel-note-mapper", "consentRequired": false, "config": { + "user.session.note": "clientId", "userinfo.token.claim": "true", - "user.attribute": "locale", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "locale", + "claim.name": "clientId", + "jsonType.label": "String" + } + }, + { + "id": "7c29a433-d724-4b5b-86fe-d9cf9f6b7ba1", + "name": "Client IP Address", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientAddress", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientAddress", + "jsonType.label": "String" + } + }, + { + "id": "d2bda4a4-e2cc-498e-838e-60a7840ccad9", + "name": "Client Host", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientHost", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientHost", "jsonType.label": "String" } } ], "defaultClientScopes": [ "web-origins", - "acr", - "profile", "roles", + "profile", "email" ], "optionalClientScopes": [ @@ -900,19 +1084,134 @@ data: ] }, { - "id": "9a0bff1a-45b0-4afa-94f0-e3522c437cdd", - "clientId": "test-client-api", + "id": "af889034-77c2-41le-a368-67d5789f4b87", + "clientId": "wrong-client", + "rootUrl": "", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "test1", + "redirectUris": [ + "*" + ], + "webOrigins": [ + "*" + ], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": true, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": true, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "frontchannel.logout.session.required": "false", + "oauth2.device.authorization.grant.enabled": "false", + "backchannel.logout.revoke.offline.tokens": "false", + "saml.server.signature.keyinfo.ext": "false", + "use.refresh.tokens": "true", + "oidc.ciba.grant.enabled": "false", + "backchannel.logout.session.required": "false", + "client_credentials.use_refresh_token": "false", + "require.pushed.authorization.requests": "false", + "saml.client.signature": "false", + "saml.allow.ecp.flow": "false", + "id.token.as.detached.signature": "false", + "saml.assertion.signature": "false", + "saml.encrypt": "false", + "login_theme": "keycloak", + "saml.server.signature": "false", + "exclude.session.state.from.auth.response": "false", + "saml.artifact.binding": "false", + "saml_force_name_id_format": "false", + "acr.loa.map": "{}", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "token.response.type.bearer.lower-case": "false", + "saml.onetimeuse.condition": "false" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "protocolMappers": [ + { + "id": "ytb67b03-0yyd-432c-a329-0a04363e974a", + "name": "Client ID", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientId", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientId", + "jsonType.label": "String" + } + }, + { + "id": "4c29a235-d731-4b5b-84fe-d9cf9f6b7ba1", + "name": "Client IP Address", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientAddress", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientAddress", + "jsonType.label": "String" + } + }, + { + "id": "d2bda3a3-e2cc-498e-838e-60a7840hhod5", + "name": "Client Host", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientHost", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientHost", + "jsonType.label": "String" + } + } + ], + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "57e89899-9c1a-498d-96fd-c9bcbd3f3121", + "clientId": "readonly-client", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "secret": "**********", + "secret": "test1", "redirectUris": [ "*" ], - "webOrigins": [ - "*" - ], + "webOrigins": [], "notBefore": 0, "bearerOnly": false, "consentRequired": false, @@ -924,49 +1223,64 @@ data: "frontchannelLogout": false, "protocol": "openid-connect", "attributes": { - "post.logout.redirect.uris": "+", - "client.secret.creation.time": "1669368263" + "saml.assertion.signature": "false", + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "saml.encrypt": "false", + "login_theme": "keycloak", + "saml.server.signature": "false", + "saml.server.signature.keyinfo.ext": "false", + "exclude.session.state.from.auth.response": "false", + "saml_force_name_id_format": "false", + "saml.client.signature": "false", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "saml.onetimeuse.condition": "false" }, "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": true, "nodeReRegistrationTimeout": -1, "protocolMappers": [ { - "id": "fbfb4ef9-e5c4-4334-a6d7-658beb122ae4", - "name": "Client ID", + "id": "574cef06-3ccf-4ed0-9001-edd83606ff57", + "name": "Client Host", "protocol": "openid-connect", "protocolMapper": "oidc-usersessionmodel-note-mapper", "consentRequired": false, "config": { - "user.session.note": "clientId", + "user.session.note": "clientHost", + "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "clientId", + "claim.name": "clientHost", "jsonType.label": "String" } }, { - "id": "a79a435c-5e74-449e-8f7d-5cd375ab4532", - "name": "Client Host", + "id": "eae693c7-5b00-4c10-bf8c-c8959925659a", + "name": "Client ID", "protocol": "openid-connect", "protocolMapper": "oidc-usersessionmodel-note-mapper", "consentRequired": false, "config": { - "user.session.note": "clientHost", + "user.session.note": "clientId", + "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "clientHost", + "claim.name": "clientId", "jsonType.label": "String" } }, { - "id": "4064c7ff-5828-448d-bdd9-162e83b1584d", + "id": "c1861851-a5ae-4da0-9110-469abc9bd64d", "name": "Client IP Address", "protocol": "openid-connect", "protocolMapper": "oidc-usersessionmodel-note-mapper", "consentRequired": false, "config": { "user.session.note": "clientAddress", + "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", "claim.name": "clientAddress", @@ -976,9 +1290,8 @@ data: ], "defaultClientScopes": [ "web-origins", - "acr", - "profile", "roles", + "profile", "email" ], "optionalClientScopes": [ @@ -987,79 +1300,199 @@ data: "offline_access", "microprofile-jwt" ] - } - ], - "clientScopes": [ - { - "id": "c2763f2d-2763-4c37-976a-732cb6efafd8", - "name": "microprofile-jwt", - "description": "Microprofile - JWT built-in scope", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "false" - }, - "protocolMappers": [ - { - "id": "e3266515-7123-4de2-b50c-fb50f4072e70", - "name": "groups", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "multivalued": "true", - "user.attribute": "foo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "groups", - "jsonType.label": "String" - } - }, - { - "id": "9d8a914f-8887-4f56-b46d-20edf5eb1b56", - "name": "upn", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "upn", - "jsonType.label": "String" - } - } - ] }, { - "id": "e9510480-0c09-4a52-82eb-2e1def1a5257", - "name": "profile", - "description": "OpenID Connect built-in scope: profile", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${profileScopeConsentText}" - }, + "id": "ff7205a6-6580-4cc3-9e97-7c4a39c7562e", + "clientId": "realm-management", + "name": "${client_realm-management}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "test1", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": {}, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "69afe60b-7329-440a-9b4c-0ebec33d8902", + "clientId": "registry-api", + "rootUrl": "", + "adminUrl": "http://localhost:8080", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "test1", + "redirectUris": [ + "*" + ], + "webOrigins": [ + "*" + ], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": true, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": true, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "frontchannel.logout.session.required": "false", + "oauth2.device.authorization.grant.enabled": "false", + "backchannel.logout.revoke.offline.tokens": "false", + "saml.server.signature.keyinfo.ext": "false", + "use.refresh.tokens": "true", + "oidc.ciba.grant.enabled": "false", + "backchannel.logout.session.required": "false", + "client_credentials.use_refresh_token": "false", + "require.pushed.authorization.requests": "false", + "saml.client.signature": "false", + "saml.allow.ecp.flow": "false", + "id.token.as.detached.signature": "false", + "saml.assertion.signature": "false", + "saml.encrypt": "false", + "login_theme": "keycloak", + "saml.server.signature": "false", + "exclude.session.state.from.auth.response": "false", + "saml.artifact.binding": "false", + "saml_force_name_id_format": "false", + "acr.loa.map": "{}", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "token.response.type.bearer.lower-case": "false", + "saml.onetimeuse.condition": "false" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, "protocolMappers": [ { - "id": "2711c8bd-bca1-4592-9845-8be7811c3441", - "name": "family name", + "id": "83a4a269-207b-4818-bbbb-a04abebb2997", + "name": "Client IP Address", "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", + "protocolMapper": "oidc-usersessionmodel-note-mapper", "consentRequired": false, "config": { + "user.session.note": "clientAddress", "userinfo.token.claim": "true", - "user.attribute": "lastName", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "family_name", + "claim.name": "clientAddress", "jsonType.label": "String" } }, { - "id": "aca228b7-fc7f-47bc-b56d-6947e2e2358d", + "id": "20241caf-ebb6-467f-acae-7543b143c289", + "name": "Client ID", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientId", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientId", + "jsonType.label": "String" + } + }, + { + "id": "eb3a14a2-5c4c-4dd7-99dc-e2734c8c5d98", + "name": "Client Host", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "clientHost", + "userinfo.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "clientHost", + "jsonType.label": "String" + } + } + ], + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + }, + { + "id": "f1beca1a-0756-4dc6-9719-9234cd9b779f", + "clientId": "security-admin-console", + "name": "${client_security-admin-console}", + "rootUrl": "${authAdminUrl}", + "baseUrl": "/admin/registry/console/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "test1", + "redirectUris": [ + "/admin/registry/console/*" + ], + "webOrigins": [ + "+" + ], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "pkce.code.challenge.method": "S256" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "cb9b9e1a-63a0-460e-a42f-14d1ace49da3", "name": "locale", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", @@ -1072,111 +1505,298 @@ data: "claim.name": "locale", "jsonType.label": "String" } + } + ], + "defaultClientScopes": [ + "web-origins", + "roles", + "profile", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] + } + ], + "clientScopes": [ + { + "id": "db64f4f6-e562-4e43-9f17-255b8a21c5ca", + "name": "roles", + "description": "OpenID Connect scope for add user roles to the access token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "true", + "consent.screen.text": "${rolesScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "bfdfc98c-59eb-4a05-9a74-dd1bb4dea691", + "name": "client roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-client-role-mapper", + "consentRequired": false, + "config": { + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "resource_access.${client_id}.roles", + "jsonType.label": "String", + "multivalued": "true" + } }, { - "id": "a2af0d22-d0bc-49db-b497-f488208ed13b", - "name": "website", + "id": "e285b5a4-2854-46d8-bd06-6ca2911dde8a", + "name": "realm roles", "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "consentRequired": false, + "config": { + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "realm_access.roles", + "jsonType.label": "String", + "multivalued": "true" + } + }, + { + "id": "c6da4bb5-fc32-4e34-88ac-72ca671afd3f", + "name": "audience resolve", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-resolve-mapper", + "consentRequired": false, + "config": {} + } + ] + }, + { + "id": "5539a2b5-6e75-4533-aaaa-800101d0df4d", + "name": "address", + "description": "OpenID Connect built-in scope: address", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${addressScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "f7c31e38-1dda-4dcc-82b6-c7d958416962", + "name": "address", + "protocol": "openid-connect", + "protocolMapper": "oidc-address-mapper", "consentRequired": false, "config": { + "user.attribute.formatted": "formatted", + "user.attribute.country": "country", + "user.attribute.postal_code": "postal_code", "userinfo.token.claim": "true", - "user.attribute": "website", + "user.attribute.street": "street", "id.token.claim": "true", + "user.attribute.region": "region", "access.token.claim": "true", - "claim.name": "website", + "user.attribute.locality": "locality" + } + } + ] + }, + { + "id": "ab66a766-4d9d-40ac-bcc9-264cd5471b92", + "name": "web-origins", + "description": "OpenID Connect scope for add allowed web origins to the access token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "false", + "consent.screen.text": "" + }, + "protocolMappers": [ + { + "id": "1b1867ba-1a17-412d-ab97-0ae88963d5b5", + "name": "allowed web origins", + "protocol": "openid-connect", + "protocolMapper": "oidc-allowed-origins-mapper", + "consentRequired": false, + "config": {} + } + ] + }, + { + "id": "a2766301-ac7f-42f4-bfbe-87d2fdcef382", + "name": "email", + "description": "OpenID Connect built-in scope: email", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${emailScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "35bbe3f0-d5a3-4785-b3dc-d187330b699d", + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", "jsonType.label": "String" } }, { - "id": "2285dfbc-8ce1-48c7-be85-0a0c1e627489", - "name": "zoneinfo", + "id": "d439a3d1-c6da-4138-87df-c1b851e7b9c8", + "name": "email verified", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "emailVerified", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email_verified", + "jsonType.label": "boolean" + } + } + ] + }, + { + "id": "90c61a9b-39ac-4dbd-af49-9123739f98f9", + "name": "phone", + "description": "OpenID Connect built-in scope: phone", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${phoneScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "9170cc7f-5624-4a15-b50d-cd1b9a0ffb6f", + "name": "phone number verified", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, "config": { "userinfo.token.claim": "true", - "user.attribute": "zoneinfo", + "user.attribute": "phoneNumberVerified", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "zoneinfo", - "jsonType.label": "String" + "claim.name": "phone_number_verified", + "jsonType.label": "boolean" } }, { - "id": "35ce806c-c921-46c6-83e1-263c95993aaa", - "name": "nickname", + "id": "f2d44f21-de2f-47d8-b0d5-4e46f9de581b", + "name": "phone number", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, "config": { "userinfo.token.claim": "true", - "user.attribute": "nickname", + "user.attribute": "phoneNumber", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "nickname", + "claim.name": "phone_number", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "9f0f742e-6202-4543-80e3-80fb2fbfc042", + "name": "profile", + "description": "OpenID Connect built-in scope: profile", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${profileScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "033dab17-488c-400d-b603-f75ebe1949b7", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", "jsonType.label": "String" } }, { - "id": "1b8651dd-52c5-4040-9df8-b1d7c0393340", - "name": "picture", + "id": "c87aca2f-23dd-4fc7-b79f-a9b061c165e4", + "name": "nickname", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, "config": { "userinfo.token.claim": "true", - "user.attribute": "picture", + "user.attribute": "nickname", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "picture", + "claim.name": "nickname", "jsonType.label": "String" } }, { - "id": "657fc2a1-5ee3-43af-bcbf-b7192c13c22f", - "name": "middle name", + "id": "4361eae6-7021-49e1-a387-3d8bc4f50247", + "name": "birthdate", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, "config": { "userinfo.token.claim": "true", - "user.attribute": "middleName", + "user.attribute": "birthdate", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "middle_name", + "claim.name": "birthdate", "jsonType.label": "String" } }, { - "id": "7621fcea-111b-43ff-ada8-4971033a6ac3", - "name": "profile", + "id": "35c03d95-ce9d-4fd2-823b-23e896dbb105", + "name": "gender", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, "config": { "userinfo.token.claim": "true", - "user.attribute": "profile", + "user.attribute": "gender", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "profile", + "claim.name": "gender", "jsonType.label": "String" } }, { - "id": "19638d91-57d5-46c5-a3ae-f9589b4e5898", - "name": "full name", + "id": "0ff4cd3c-6567-4935-bbe8-0191a9bcdd72", + "name": "locale", "protocol": "openid-connect", - "protocolMapper": "oidc-full-name-mapper", + "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, "config": { + "userinfo.token.claim": "true", + "user.attribute": "locale", "id.token.claim": "true", "access.token.claim": "true", - "userinfo.token.claim": "true" + "claim.name": "locale", + "jsonType.label": "String" } }, { - "id": "98154213-f45e-4823-9808-2ec6c8669a7b", + "id": "8e087dfd-2978-4ea5-9ed2-32efca9a98c5", "name": "given name", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", @@ -1191,37 +1811,37 @@ data: } }, { - "id": "4b4a0f9e-8e8f-4a89-ae67-d1ccc9ad69bd", - "name": "gender", + "id": "31a3c477-3aab-46cd-81e3-2b76b2c8c21c", + "name": "profile", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, "config": { "userinfo.token.claim": "true", - "user.attribute": "gender", + "user.attribute": "profile", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "gender", + "claim.name": "profile", "jsonType.label": "String" } }, { - "id": "fbbb7ee4-8641-4843-8cf4-6226d5577533", - "name": "updated at", + "id": "a3606512-379b-4bcb-999d-29cf17812012", + "name": "website", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, "config": { "userinfo.token.claim": "true", - "user.attribute": "updatedAt", + "user.attribute": "website", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "updated_at", - "jsonType.label": "long" + "claim.name": "website", + "jsonType.label": "String" } }, { - "id": "f3f91b7f-ef5e-4836-ae73-40642b9c6d9c", + "id": "2f535da7-ea99-4f8d-acbe-988a3691034b", "name": "username", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", @@ -1236,202 +1856,115 @@ data: } }, { - "id": "7f0d06a2-8514-43d1-96bf-200b7a1af998", - "name": "birthdate", + "id": "2fbfe26c-b175-4b16-97ea-edea4072181a", + "name": "picture", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, "config": { "userinfo.token.claim": "true", - "user.attribute": "birthdate", + "user.attribute": "picture", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "birthdate", + "claim.name": "picture", "jsonType.label": "String" } - } - ] - }, - { - "id": "93d2ef97-e473-4633-94db-7c14f4915b9d", - "name": "role_list", - "description": "SAML role list", - "protocol": "saml", - "attributes": { - "consent.screen.text": "${samlRoleListScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "67a328f6-4297-4d71-a98b-41b549afee3a", - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, - "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" - } - } - ] - }, - { - "id": "a09e5798-970c-43ab-9447-108c84cc536f", - "name": "offline_access", - "description": "OpenID Connect built-in scope: offline_access", - "protocol": "openid-connect", - "attributes": { - "consent.screen.text": "${offlineAccessScopeConsentText}", - "display.on.consent.screen": "true" - } - }, - { - "id": "b427d964-519d-4e54-ad84-e1bb377a517e", - "name": "web-origins", - "description": "OpenID Connect scope for add allowed web origins to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "false", - "consent.screen.text": "" - }, - "protocolMappers": [ - { - "id": "46832292-c6c9-43d5-911d-706bf72b7e96", - "name": "allowed web origins", - "protocol": "openid-connect", - "protocolMapper": "oidc-allowed-origins-mapper", - "consentRequired": false, - "config": {} - } - ] - }, - { - "id": "e495f5f3-62ef-411d-9bd6-751650a29357", - "name": "roles", - "description": "OpenID Connect scope for add user roles to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "true", - "consent.screen.text": "${rolesScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "0c5b1be5-d872-424a-aa6d-937be243e3c9", - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": {} }, { - "id": "048c8458-64a3-4cf0-9dcb-202896879d96", - "name": "realm roles", + "id": "17e5a7d4-2e77-4ff4-8c71-b93e41e4e1bb", + "name": "full name", "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", + "protocolMapper": "oidc-full-name-mapper", "consentRequired": false, "config": { - "user.attribute": "foo", + "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "realm_access.roles", - "jsonType.label": "String", - "multivalued": "true" + "userinfo.token.claim": "true" } }, { - "id": "91043f8b-6573-480c-9948-2a9b93b8e6e4", - "name": "client roles", + "id": "ca64060a-1d26-43ca-aae7-23c62ed805d4", + "name": "zoneinfo", "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-client-role-mapper", + "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, "config": { - "user.attribute": "foo", + "userinfo.token.claim": "true", + "user.attribute": "zoneinfo", + "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "resource_access.${client_id}.roles", - "jsonType.label": "String", - "multivalued": "true" + "claim.name": "zoneinfo", + "jsonType.label": "String" } - } - ] - }, - { - "id": "1b32313e-a013-443a-baed-0cbd96581286", - "name": "email", - "description": "OpenID Connect built-in scope: email", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${emailScopeConsentText}" - }, - "protocolMappers": [ + }, { - "id": "c186583b-7296-4245-b347-5ac3785ed841", - "name": "email", + "id": "beaddf45-8040-42cd-9236-55fe2134f5df", + "name": "middle name", "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", + "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, "config": { "userinfo.token.claim": "true", - "user.attribute": "email", + "user.attribute": "middleName", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "email", + "claim.name": "middle_name", "jsonType.label": "String" } }, { - "id": "27171767-21ff-4b4c-9139-dd8011fce62f", - "name": "email verified", + "id": "043c162e-e0ba-418b-b965-157f6a52db46", + "name": "updated at", "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", + "protocolMapper": "oidc-usermodel-attribute-mapper", "consentRequired": false, "config": { "userinfo.token.claim": "true", - "user.attribute": "emailVerified", + "user.attribute": "updatedAt", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "email_verified", - "jsonType.label": "boolean" + "claim.name": "updated_at", + "jsonType.label": "String" } } ] }, { - "id": "dc767de7-a232-422b-a251-c3e5d6e30b2f", - "name": "address", - "description": "OpenID Connect built-in scope: address", - "protocol": "openid-connect", + "id": "5074f873-23f3-4d03-9b75-6c6af91fb7ed", + "name": "role_list", + "description": "SAML role list", + "protocol": "saml", "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${addressScopeConsentText}" + "consent.screen.text": "${samlRoleListScopeConsentText}", + "display.on.consent.screen": "true" }, "protocolMappers": [ { - "id": "7e466534-8441-4b9b-8ad4-e7ee015c1325", - "name": "address", - "protocol": "openid-connect", - "protocolMapper": "oidc-address-mapper", + "id": "ab3d0106-d086-4813-930b-5a27ddfe038b", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", "consentRequired": false, "config": { - "user.attribute.formatted": "formatted", - "user.attribute.country": "country", - "user.attribute.postal_code": "postal_code", - "userinfo.token.claim": "true", - "user.attribute.street": "street", - "id.token.claim": "true", - "user.attribute.region": "region", - "access.token.claim": "true", - "user.attribute.locality": "locality" + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" } } ] }, { - "id": "400354cf-19b7-4551-8bc4-a43088755fde", + "id": "65eabc09-c5a1-4a0e-830c-44a430c129f0", + "name": "offline_access", + "description": "OpenID Connect built-in scope: offline_access", + "protocol": "openid-connect", + "attributes": { + "consent.screen.text": "${offlineAccessScopeConsentText}", + "display.on.consent.screen": "true" + } + }, + { + "id": "f25b9036-55b3-4cc3-bc37-bc0be5405432", "name": "acr", "description": "OpenID Connect scope for add acr (authentication context class reference) to the token", "protocol": "openid-connect", @@ -1441,7 +1974,7 @@ data: }, "protocolMappers": [ { - "id": "fd2fdff9-9408-42fe-bbde-60252cede8bd", + "id": "e5051472-d2aa-4658-9d95-01064efcca13", "name": "acr loa level", "protocol": "openid-connect", "protocolMapper": "oidc-acr-mapper", @@ -1454,89 +1987,43 @@ data: ] }, { - "id": "faf60df2-2e91-4876-af19-aa5cbb3fc9d9", - "name": "user-attributes", - "description": "Map user attributes org-admin and org-role into token claims.", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "gui.order": "", - "consent.screen.text": "" - }, - "protocolMappers": [ - { - "id": "c16f489a-1dbc-48a3-b157-0cb19f0cf5f3", - "name": "admin-role", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "aggregate.attrs": "false", - "userinfo.token.claim": "true", - "multivalued": "false", - "user.attribute": "admin-role", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "admin-role" - } - }, - { - "id": "e3deb53c-4963-4b3b-8d31-93b6e930021d", - "name": "org-admin", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "aggregate.attrs": "false", - "userinfo.token.claim": "true", - "multivalued": "false", - "user.attribute": "org-admin", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "org-admin" - } - } - ] - }, - { - "id": "fb255db0-52eb-4c08-bd17-c7c9153e9d79", - "name": "phone", - "description": "OpenID Connect built-in scope: phone", + "id": "d6f896d6-b31b-487e-b4a8-af921d3d04eb", + "name": "microprofile-jwt", + "description": "Microprofile - JWT built-in scope", "protocol": "openid-connect", "attributes": { "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${phoneScopeConsentText}" + "display.on.consent.screen": "false" }, "protocolMappers": [ { - "id": "7d3c18c3-95d2-440a-b189-aeda66166786", - "name": "phone number verified", + "id": "c7831e59-070e-4d77-8382-d5ef4f60ddd4", + "name": "upn", "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", + "protocolMapper": "oidc-usermodel-property-mapper", "consentRequired": false, "config": { "userinfo.token.claim": "true", - "user.attribute": "phoneNumberVerified", + "user.attribute": "username", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "phone_number_verified", - "jsonType.label": "boolean" + "claim.name": "upn", + "jsonType.label": "String" } }, { - "id": "4d19b12b-a968-4a4a-a6ce-0fd55b7ee33e", - "name": "phone number", + "id": "3456b5e1-4852-48ac-8420-79568ffd9a89", + "name": "groups", "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", + "protocolMapper": "oidc-usermodel-realm-role-mapper", "consentRequired": false, "config": { + "multivalued": "true", "userinfo.token.claim": "true", - "user.attribute": "phoneNumber", + "user.attribute": "foo", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "phone_number", + "claim.name": "groups", "jsonType.label": "String" } } @@ -1547,13 +2034,13 @@ data: "role_list", "profile", "email", - "roles", "web-origins", + "roles", "acr" ], "defaultOptionalClientScopes": [ - "offline_access", "address", + "offline_access", "phone", "microprofile-jwt" ], @@ -1567,6 +2054,10 @@ data: "strictTransportSecurity": "max-age=31536000; includeSubDomains" }, "smtpServer": {}, + "loginTheme": "keycloak", + "accountTheme": "keycloak", + "adminTheme": "keycloak", + "emailTheme": "keycloak", "eventsEnabled": false, "eventsListeners": [ "jboss-logging" @@ -1579,47 +2070,42 @@ data: "components": { "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ { - "id": "85d8ee7e-ceb3-439f-9ac4-52fe137f12d1", - "name": "Consent Required", - "providerId": "consent-required", + "id": "6b7d0997-665b-4567-b955-f41029b1f7c6", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", "subType": "anonymous", "subComponents": {}, - "config": {} + "config": { + "allow-default-scopes": [ + "true" + ] + } }, { - "id": "7ae95dee-5665-4aab-b101-a025d7a2a71a", - "name": "Max Clients Limit", - "providerId": "max-clients", + "id": "b2062994-7819-4b5b-bcaf-bd565e0261f7", + "name": "Trusted Hosts", + "providerId": "trusted-hosts", "subType": "anonymous", "subComponents": {}, "config": { - "max-clients": [ - "200" + "host-sending-registration-request-must-match": [ + "true" + ], + "client-uris-must-match": [ + "true" ] } }, { - "id": "5be231cf-5657-4017-a1f4-f6d9828eb49b", - "name": "Full Scope Disabled", - "providerId": "scope", + "id": "e28102af-287e-40d3-a64d-636f9d0af6c0", + "name": "Consent Required", + "providerId": "consent-required", "subType": "anonymous", "subComponents": {}, "config": {} }, { - "id": "ccb36330-87c8-493c-b9be-882241d44eba", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - "id": "8878ae74-8a2b-4d97-ba41-b4d17592d613", + "id": "7ea991c6-db4b-4989-87c1-2cf0b2e2b371", "name": "Allowed Client Scopes", "providerId": "allowed-client-templates", "subType": "authenticated", @@ -1631,70 +2117,67 @@ data: } }, { - "id": "2c1bbdcf-dcf8-4947-b434-54ee333412b4", + "id": "c2aa0c17-6405-441a-96d8-7174001b1f6e", "name": "Allowed Protocol Mapper Types", "providerId": "allowed-protocol-mappers", "subType": "authenticated", "subComponents": {}, "config": { "allowed-protocol-mapper-types": [ - "saml-user-property-mapper", - "saml-role-list-mapper", + "oidc-usermodel-property-mapper", "oidc-address-mapper", - "saml-user-attribute-mapper", + "oidc-full-name-mapper", + "saml-user-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", - "oidc-full-name-mapper", - "oidc-usermodel-property-mapper" + "saml-user-attribute-mapper", + "saml-role-list-mapper" ] } }, { - "id": "628621e6-5498-4108-bc16-faaf52dbcceb", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", + "id": "f1d9cee9-fa10-451a-a96f-486c1abc9184", + "name": "Full Scope Disabled", + "providerId": "scope", + "subType": "anonymous", + "subComponents": {}, + "config": {} + }, + { + "id": "398d86a9-4247-4923-b3bf-a94ef18974f2", + "name": "Max Clients Limit", + "providerId": "max-clients", "subType": "anonymous", "subComponents": {}, "config": { - "allowed-protocol-mapper-types": [ - "saml-user-property-mapper", - "oidc-sha256-pairwise-sub-mapper", - "oidc-address-mapper", - "oidc-usermodel-attribute-mapper", - "oidc-full-name-mapper", - "saml-role-list-mapper", - "oidc-usermodel-property-mapper", - "saml-user-attribute-mapper" + "max-clients": [ + "200" ] } }, { - "id": "a9d8af28-fb2a-47cb-b037-a83381ed949d", - "name": "Trusted Hosts", - "providerId": "trusted-hosts", + "id": "fd8139d0-82ee-453e-a9aa-0bbd10538eff", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", "subType": "anonymous", "subComponents": {}, "config": { - "host-sending-registration-request-must-match": [ - "true" - ], - "client-uris-must-match": [ - "true" + "allowed-protocol-mapper-types": [ + "oidc-sha256-pairwise-sub-mapper", + "saml-user-attribute-mapper", + "saml-user-property-mapper", + "oidc-usermodel-property-mapper", + "oidc-full-name-mapper", + "oidc-address-mapper", + "saml-role-list-mapper", + "oidc-usermodel-attribute-mapper" ] } } ], - "org.keycloak.userprofile.UserProfileProvider": [ - { - "id": "ca57e054-f5a3-457f-81d2-9f1daeb6d944", - "providerId": "declarative-user-profile", - "subComponents": {}, - "config": {} - } - ], "org.keycloak.keys.KeyProvider": [ { - "id": "690e87fb-8893-4d6d-83c6-83b353268f04", + "id": "9ec415cf-5494-4823-a83d-cc38441b088c", "name": "aes-generated", "providerId": "aes-generated", "subComponents": {}, @@ -1705,7 +2188,7 @@ data: } }, { - "id": "797628fa-7b9a-48d3-bd8f-1de01a9589f7", + "id": "cd2dc9b1-a252-4f70-93c0-5bdb51532236", "name": "hmac-generated", "providerId": "hmac-generated", "subComponents": {}, @@ -1719,7 +2202,7 @@ data: } }, { - "id": "8216f674-5a73-414b-9e23-648b27fb7c2f", + "id": "2dc91aa5-3084-4ceb-973e-24d78e78777a", "name": "rsa-generated", "providerId": "rsa-generated", "subComponents": {}, @@ -1728,28 +2211,16 @@ data: "100" ] } - }, - { - "id": "ebdf41a2-a273-451e-a80e-71a06f73bb1e", - "name": "rsa-enc-generated", - "providerId": "rsa-enc-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "RSA-OAEP" - ] - } } ] }, "internationalizationEnabled": false, - "supportedLocales": [], + "supportedLocales": [ + "" + ], "authenticationFlows": [ { - "id": "880669c7-76c3-4851-93ef-25535e730ff7", + "id": "e5691b91-7a97-482c-9ba4-fef8933be469", "alias": "Account verification options", "description": "Method with which to verity the existing account", "providerId": "basic-flow", @@ -1775,7 +2246,7 @@ data: ] }, { - "id": "e1cae199-3fe9-4af5-95da-567e34db0d69", + "id": "c6f47ebc-143a-471b-9f93-0b7faf267717", "alias": "Authentication Options", "description": "Authentication options.", "providerId": "basic-flow", @@ -1809,7 +2280,7 @@ data: ] }, { - "id": "3eb85ff5-65b7-4792-bdac-1c6ee4144cb0", + "id": "09cbd3e3-0784-4af0-a279-4fd95216a37f", "alias": "Browser - Conditional OTP", "description": "Flow to determine if the OTP is required for the authentication", "providerId": "basic-flow", @@ -1835,7 +2306,7 @@ data: ] }, { - "id": "dc22b86b-ceae-42ca-8dec-5161447bfcbb", + "id": "016d5ed7-b797-4d0c-8a2a-da422a1c0b07", "alias": "Direct Grant - Conditional OTP", "description": "Flow to determine if the OTP is required for the authentication", "providerId": "basic-flow", @@ -1861,7 +2332,7 @@ data: ] }, { - "id": "893aedd5-060a-4d72-bbf7-b9329c389f8e", + "id": "2122d0ae-d429-43ca-82aa-b2a8ebf265f4", "alias": "First broker login - Conditional OTP", "description": "Flow to determine if the OTP is required for the authentication", "providerId": "basic-flow", @@ -1887,7 +2358,7 @@ data: ] }, { - "id": "b69d0e51-a909-4350-b0fe-8be361289f2b", + "id": "7dcbbd10-cfcb-4146-a080-d829ed4bbda8", "alias": "Handle Existing Account", "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", "providerId": "basic-flow", @@ -1913,7 +2384,7 @@ data: ] }, { - "id": "1c3df5cc-93f6-4dcc-a5f5-0922a96d277d", + "id": "f575338f-7ff4-4f6c-9230-2d5a93c01d8e", "alias": "Reset - Conditional OTP", "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", "providerId": "basic-flow", @@ -1939,7 +2410,7 @@ data: ] }, { - "id": "e8171b3d-8864-4af5-a8e8-6016b79207a5", + "id": "8b96e8ee-9bd6-44a5-9ce6-e12bcb1fca11", "alias": "User creation or linking", "description": "Flow for the existing/non-existing user alternatives", "providerId": "basic-flow", @@ -1966,7 +2437,7 @@ data: ] }, { - "id": "921c6f7b-bef9-4078-aa15-acf40f61ed18", + "id": "20339a98-7cbd-4a95-8d8f-f5b60f512524", "alias": "Verify Existing Account by Re-authentication", "description": "Reauthentication of existing account", "providerId": "basic-flow", @@ -1992,7 +2463,7 @@ data: ] }, { - "id": "af0766f4-dd33-42fb-b66d-c985348ac3a3", + "id": "43e87d99-f6c4-495b-a175-35fec32291c4", "alias": "browser", "description": "browser based authentication", "providerId": "basic-flow", @@ -2034,7 +2505,7 @@ data: ] }, { - "id": "1e39b9ea-f180-41eb-89d9-4e19c8803176", + "id": "09f61a35-e173-40a8-9bbf-4554586112f0", "alias": "clients", "description": "Base authentication for clients", "providerId": "client-flow", @@ -2076,7 +2547,7 @@ data: ] }, { - "id": "64932e94-32ce-441a-b48d-21350a135843", + "id": "30361549-be4b-4a06-ae79-b60cb3d6ac68", "alias": "direct grant", "description": "OpenID Connect Resource Owner Grant", "providerId": "basic-flow", @@ -2110,7 +2581,7 @@ data: ] }, { - "id": "62a31573-e6b8-4690-a856-3ea999f7a4a1", + "id": "ba07e315-0671-4691-af1e-beed84da42ab", "alias": "docker auth", "description": "Used by Docker clients to authenticate against the IDP", "providerId": "basic-flow", @@ -2128,7 +2599,7 @@ data: ] }, { - "id": "32ea07f1-24b3-467d-a7ff-e402f62ee55a", + "id": "3ff3f29e-260a-43df-b71b-75a945b220b1", "alias": "first broker login", "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", "providerId": "basic-flow", @@ -2155,7 +2626,7 @@ data: ] }, { - "id": "0f133fd5-0607-49ac-8c4b-9b0ea3234f53", + "id": "11efa214-3d69-470c-92e1-2ea6cd2f1133", "alias": "forms", "description": "Username, password, otp and other auth forms.", "providerId": "basic-flow", @@ -2181,7 +2652,7 @@ data: ] }, { - "id": "4ecf9ccf-d264-4ed8-945d-b5d123d34346", + "id": "b1ee124e-1648-42c2-a268-2db3251b3e44", "alias": "http challenge", "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", "providerId": "basic-flow", @@ -2207,7 +2678,7 @@ data: ] }, { - "id": "68c7570b-e7f6-4ebc-9a9f-63203815ec71", + "id": "e5c21eef-7736-42bf-83f7-219f11579be9", "alias": "registration", "description": "registration flow", "providerId": "basic-flow", @@ -2226,7 +2697,7 @@ data: ] }, { - "id": "3cc71e11-284e-479f-aefb-fd57dd61f110", + "id": "51b02897-de8e-47d9-872b-ee06ff1ffd8f", "alias": "registration form", "description": "registration form", "providerId": "form-flow", @@ -2268,7 +2739,7 @@ data: ] }, { - "id": "937c059b-79f8-469e-a4a5-c4cb4c5997c8", + "id": "f3d3919d-e759-49c4-8eb9-e85c16f314a5", "alias": "reset credentials", "description": "Reset credentials for a user if they forgot their password or something", "providerId": "basic-flow", @@ -2310,7 +2781,7 @@ data: ] }, { - "id": "d876aeed-cfe2-409e-a569-056d2bf9bc8e", + "id": "84316c99-bba7-42d5-aeeb-2f56b4ce657d", "alias": "saml ecp", "description": "SAML ECP Profile Authentication Flow", "providerId": "basic-flow", @@ -2330,14 +2801,14 @@ data: ], "authenticatorConfig": [ { - "id": "45dc9121-4b96-404c-b958-bafbfcc096de", + "id": "43cf7bce-acd0-4c1f-a08e-cac4a1f32a6c", "alias": "create unique user config", "config": { "require.password.update.after.registration": "false" } }, { - "id": "a46512d1-178a-4d17-938e-486f11dec919", + "id": "6c176502-376d-46fc-835f-0e0352158326", "alias": "review profile config", "config": { "update.profile.on.first.login": "missing" @@ -2399,24 +2870,6 @@ data: "priority": 60, "config": {} }, - { - "alias": "webauthn-register", - "name": "Webauthn Register", - "providerId": "webauthn-register", - "enabled": true, - "defaultAction": false, - "priority": 70, - "config": {} - }, - { - "alias": "webauthn-register-passwordless", - "name": "Webauthn Register Passwordless", - "providerId": "webauthn-register-passwordless", - "enabled": true, - "defaultAction": false, - "priority": 80, - "config": {} - }, { "alias": "update_user_locale", "name": "Update User Locale", @@ -2435,20 +2888,16 @@ data: "dockerAuthenticationFlow": "docker auth", "attributes": { "cibaBackchannelTokenDeliveryMode": "poll", + "cibaExpiresIn": "120", "cibaAuthRequestedUserHint": "login_hint", + "oauth2DeviceCodeLifespan": "600", "oauth2DevicePollingInterval": "5", - "clientOfflineSessionMaxLifespan": "0", "clientSessionIdleTimeout": "0", - "clientOfflineSessionIdleTimeout": "0", - "cibaInterval": "5", - "cibaExpiresIn": "120", - "oauth2DeviceCodeLifespan": "600", "parRequestUriLifespan": "60", "clientSessionMaxLifespan": "0", - "frontendUrl": "", - "acr.loa.map": "[]" + "cibaInterval": "5" }, - "keycloakVersion": "19.0.3", + "keycloakVersion": "18.0.1", "userManagedAccessAllowed": true, "clientProfiles": { "profiles": [] @@ -2456,4 +2905,79 @@ data: "clientPolicies": { "policies": [] } - } \ No newline at end of file + } +kind: ConfigMap +metadata: + namespace: "apicurio-registry-e2e" + name: keycloak-configmap +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: keycloak-deployment + name: keycloak-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: keycloak-deployment + strategy: { } + template: + metadata: + labels: + app: keycloak-deployment + spec: + containers: + - image: quay.io/keycloak/keycloak:18.0.1 + args: [ "start-dev --import-realm" ] + volumeMounts: + - name: keycloak-volume + mountPath: /opt/keycloak/data/import + name: keycloak + env: + - name: KEYCLOAK_USER + value: admin + - name: KEYCLOAK_PASSWORD + value: superSecret + - name: KC_PROXY + value: "edge" + - name: KC_HOSTNAME + value: "localhost" + - name: KC_HOSTNAME_PORT + value: "8090" + - name: KC_HOSTNAME_STRICT_BACKCHANNEL + value: "false" + - name: KC_HTTP_RELATIVE_PATH + value: "/auth" + - name: KC_HTTP_PORT + value: "8090" + ports: + - name: http + containerPort: 8090 + readinessProbe: + failureThreshold: 3 + httpGet: + path: /realms/master + port: 8090 + initialDelaySeconds: 10 + timeoutSeconds: 50 + resources: { } + volumes: + - name: keycloak-volume + configMap: + name: keycloak-configmap +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + name: keycloak-service +spec: + selector: + app: keycloak-deployment + ports: + - protocol: TCP + port: 8090 + targetPort: 8090 diff --git a/integration-tests/src/test/resources/infra/e2e-namespace.yml b/integration-tests/src/test/resources/infra/e2e-namespace.yml new file mode 100644 index 0000000000..742d6eda3c --- /dev/null +++ b/integration-tests/src/test/resources/infra/e2e-namespace.yml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: "apicurio-registry-e2e" + labels: + name: "apicurio-registry-e2e" \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/in-memory/registry-in-memory-secured.yml b/integration-tests/src/test/resources/infra/in-memory/registry-in-memory-secured.yml new file mode 100644 index 0000000000..ea494bd6b6 --- /dev/null +++ b/integration-tests/src/test/resources/infra/in-memory/registry-in-memory-secured.yml @@ -0,0 +1,96 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-memory + name: apicurio-registry-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: apicurio-registry-memory + template: + metadata: + labels: + app: apicurio-registry-memory + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: AUTH_ENABLED + value: "true" + - name: KEYCLOAK_API_CLIENT_ID + value: "registry-api" + - name: KEYCLOAK_UI_CLIENT_ID + value: apicurio-registry + - name: REGISTRY_UI_CONFIG_AUTH_KEYCLOAK_URL + value: 'http://localhost:8090' + - name: KEYCLOAK_REALM + value: 'registry' + - name: QUARKUS_OIDC_AUTH_SERVER_URL + value: "http://keycloak-service:8090/realms/registry" + - name: QUARKUS_OIDC_TLS_VERIFICATION + value: none + - name: TOKEN_ENDPOINT + value: "http://keycloak-service:8090/realms/registry/protocol/openid-connect/token" + - name: CLIENT_CREDENTIALS_BASIC_AUTH_ENABLED + value: "true" + - name: REGISTRY_AUTH_RBAC_ENABLED + value: "true" + - name: REGISTRY_AUTH_ROLE_SOURCE + value: "token" + image: registry-image + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: apicurio-registry-memory + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-memory + name: apicurio-registry-service +spec: + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + nodePort: 32586 + selector: + app: apicurio-registry-memory + type: LoadBalancer + sessionAffinity: None + externalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + allocateLoadBalancerNodePorts: true + internalTrafficPolicy: Cluster \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/in-memory/registry-in-memory.yml b/integration-tests/src/test/resources/infra/in-memory/registry-in-memory.yml new file mode 100644 index 0000000000..d84d2592ce --- /dev/null +++ b/integration-tests/src/test/resources/infra/in-memory/registry-in-memory.yml @@ -0,0 +1,74 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-memory + name: apicurio-registry-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: apicurio-registry-memory + template: + metadata: + labels: + app: apicurio-registry-memory + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: registry-image + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: apicurio-registry-memory + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-application + name: apicurio-registry-service +spec: + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + nodePort: 32586 + selector: + app: apicurio-registry-memory + type: LoadBalancer + sessionAffinity: None + externalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + allocateLoadBalancerNodePorts: true + internalTrafficPolicy: Cluster \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/in-memory/registry-multitenant-in-memory.yml b/integration-tests/src/test/resources/infra/in-memory/registry-multitenant-in-memory.yml new file mode 100644 index 0000000000..ed4ba39ac6 --- /dev/null +++ b/integration-tests/src/test/resources/infra/in-memory/registry-multitenant-in-memory.yml @@ -0,0 +1,84 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-memory + name: apicurio-registry-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: apicurio-registry-memory + template: + metadata: + labels: + app: apicurio-registry-memory + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: TENANT_MANAGER_URL + value: "http://tenant-manager-service:8585" + - name: REGISTRY_ENABLE_MULTITENANCY + value: "true" + - name: REGISTRY_DISABLE_APIS + value: "" + - name: REGISTRY_MULTITENANCY_REAPER_PERIOD_SECONDS + value: "10" + - name: REGISTRY_MULTITENANCY_REAPER_EVERY + value: "3s" + image: registry-image + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: apicurio-registry-memory + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-memory + name: apicurio-registry-service +spec: + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + nodePort: 32586 + selector: + app: apicurio-registry-memory + type: LoadBalancer + sessionAffinity: None + externalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + allocateLoadBalancerNodePorts: true + internalTrafficPolicy: Cluster \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/kafka/kafka.yml b/integration-tests/src/test/resources/infra/kafka/kafka.yml new file mode 100644 index 0000000000..2f5d6ffede --- /dev/null +++ b/integration-tests/src/test/resources/infra/kafka/kafka.yml @@ -0,0 +1,43 @@ +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: kafka-service + name: kafka-service +spec: + ports: + - protocol: TCP + port: 9092 + targetPort: 9092 + selector: + app: kafka-service +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + name: kafka-service +spec: + selector: + matchLabels: + app: kafka-service + template: + metadata: + labels: + app: kafka-service + spec: + containers: + - name: kafka-service + image: quay.io/strimzi/kafka:latest-kafka-3.5.0-amd64 + command: + - /bin/sh + - -c + - "export CLUSTER_ID=$(bin/kafka-storage.sh random-uuid) && bin/kafka-storage.sh format -t $CLUSTER_ID -c config/kraft/server.properties && bin/kafka-server-start.sh config/kraft/server.properties --override advertised.listeners=${KAFKA_ADVERTISED_LISTENERS}" + env: + - name: LOG_DIR + value: /tmp/logs + - name: KAFKA_ADVERTISED_LISTENERS + value: PLAINTEXT://kafka-service:9092 + ports: + - containerPort: 9092 \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/kafka/registry-kafka-old.yml b/integration-tests/src/test/resources/infra/kafka/registry-kafka-old.yml new file mode 100644 index 0000000000..35c91a6e36 --- /dev/null +++ b/integration-tests/src/test/resources/infra/kafka/registry-kafka-old.yml @@ -0,0 +1,76 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-kafka + name: apicurio-registry-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: apicurio-registry-kafka + template: + metadata: + labels: + app: apicurio-registry-kafka + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: KAFKA_BOOTSTRAP_SERVERS + value: kafka-service:9092 + image: quay.io/apicurio/apicurio-registry-kafkasql:2.1.2.Final + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: apicurio-registry-kafka + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-kafka + name: apicurio-registry-service +spec: + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + nodePort: 32586 + selector: + app: apicurio-registry-kafka + type: LoadBalancer + sessionAffinity: None + externalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + allocateLoadBalancerNodePorts: true + internalTrafficPolicy: Cluster \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/kafka/registry-kafka-secured.yml b/integration-tests/src/test/resources/infra/kafka/registry-kafka-secured.yml new file mode 100644 index 0000000000..9cb34b6587 --- /dev/null +++ b/integration-tests/src/test/resources/infra/kafka/registry-kafka-secured.yml @@ -0,0 +1,98 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-kafka + name: apicurio-registry-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: apicurio-registry-kafka + template: + metadata: + labels: + app: apicurio-registry-kafka + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: KAFKA_BOOTSTRAP_SERVERS + value: kafka-service:9092 + - name: AUTH_ENABLED + value: "true" + - name: KEYCLOAK_API_CLIENT_ID + value: "registry-api" + - name: KEYCLOAK_UI_CLIENT_ID + value: apicurio-registry + - name: REGISTRY_UI_CONFIG_AUTH_KEYCLOAK_URL + value: 'http://localhost:8090' + - name: KEYCLOAK_REALM + value: 'registry' + - name: QUARKUS_OIDC_AUTH_SERVER_URL + value: "http://keycloak-service:8090/realms/registry" + - name: QUARKUS_OIDC_TLS_VERIFICATION + value: none + - name: TOKEN_ENDPOINT + value: "http://keycloak-service:8090/realms/registry/protocol/openid-connect/token" + - name: CLIENT_CREDENTIALS_BASIC_AUTH_ENABLED + value: "true" + - name: REGISTRY_AUTH_RBAC_ENABLED + value: "true" + - name: REGISTRY_AUTH_ROLE_SOURCE + value: "token" + image: registry-image + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: apicurio-registry-kafka + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-kafka + name: apicurio-registry-service +spec: + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + nodePort: 32586 + selector: + app: apicurio-registry-kafka + type: LoadBalancer + sessionAffinity: None + externalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + allocateLoadBalancerNodePorts: true + internalTrafficPolicy: Cluster \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/kafka/registry-kafka.yml b/integration-tests/src/test/resources/infra/kafka/registry-kafka.yml new file mode 100644 index 0000000000..b1c1e6cd49 --- /dev/null +++ b/integration-tests/src/test/resources/infra/kafka/registry-kafka.yml @@ -0,0 +1,76 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-kafka + name: apicurio-registry-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: apicurio-registry-kafka + template: + metadata: + labels: + app: apicurio-registry-kafka + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: KAFKA_BOOTSTRAP_SERVERS + value: kafka-service:9092 + image: registry-image + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: apicurio-registry-kafka + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-kafka + name: apicurio-registry-service +spec: + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + nodePort: 32586 + selector: + app: apicurio-registry-kafka + type: LoadBalancer + sessionAffinity: None + externalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + allocateLoadBalancerNodePorts: true + internalTrafficPolicy: Cluster \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/kafka/registry-multitenant-kafka.yml b/integration-tests/src/test/resources/infra/kafka/registry-multitenant-kafka.yml new file mode 100644 index 0000000000..df92abc55c --- /dev/null +++ b/integration-tests/src/test/resources/infra/kafka/registry-multitenant-kafka.yml @@ -0,0 +1,86 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-kafka + name: apicurio-registry-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: apicurio-registry-kafka + template: + metadata: + labels: + app: apicurio-registry-kafka + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: KAFKA_BOOTSTRAP_SERVERS + value: kafka-service:9092 + - name: TENANT_MANAGER_URL + value: "http://tenant-manager-service:8585" + - name: REGISTRY_ENABLE_MULTITENANCY + value: "true" + - name: REGISTRY_DISABLE_APIS + value: "" + - name: REGISTRY_MULTITENANCY_REAPER_PERIOD_SECONDS + value: "15" + - name: REGISTRY_MULTITENANCY_REAPER_EVERY + value: "3s" + image: registry-image + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: apicurio-registry-kafka + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-kafka + name: apicurio-registry-service +spec: + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + nodePort: 32586 + selector: + app: apicurio-registry-kafka + type: LoadBalancer + sessionAffinity: None + externalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + allocateLoadBalancerNodePorts: true + internalTrafficPolicy: Cluster \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/openshift/registry-route.yml b/integration-tests/src/test/resources/infra/openshift/registry-route.yml new file mode 100644 index 0000000000..9a2ffc2700 --- /dev/null +++ b/integration-tests/src/test/resources/infra/openshift/registry-route.yml @@ -0,0 +1,15 @@ +kind: Route +apiVersion: route.openshift.io/v1 +metadata: + name: registry + namespace: apicurio-registry-e2e + labels: + app: apicurio-registry-application +spec: + to: + kind: Service + name: apicurio-registry-service + weight: 100 + port: + targetPort: 8080 + wildcardPolicy: None \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/openshift/tenant-manager-route.yml b/integration-tests/src/test/resources/infra/openshift/tenant-manager-route.yml new file mode 100644 index 0000000000..9f52549d26 --- /dev/null +++ b/integration-tests/src/test/resources/infra/openshift/tenant-manager-route.yml @@ -0,0 +1,15 @@ +kind: Route +apiVersion: route.openshift.io/v1 +metadata: + name: tenant-manager + namespace: apicurio-registry-e2e + labels: + app: tenant-manager-app +spec: + to: + kind: Service + name: tenant-manager-service + weight: 100 + port: + targetPort: 8585 + wildcardPolicy: None \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/sql/postgresql.yml b/integration-tests/src/test/resources/infra/sql/postgresql.yml new file mode 100644 index 0000000000..84f64176da --- /dev/null +++ b/integration-tests/src/test/resources/infra/sql/postgresql.yml @@ -0,0 +1,55 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: postgresql + name: postgresql +spec: + replicas: 1 + selector: + matchLabels: + app: postgresql + template: + metadata: + labels: + app: postgresql + spec: + containers: + - name: postgresql + image: quay.io/centos7/postgresql-13-centos7 + ports: + - containerPort: 5432 + env: + - name: POSTGRESQL_DB + value: registry + - name: POSTGRESQL_USER + value: apicurio + - name: POSTGRESQL_PASSWORD + value: registry + - name: POSTGRESQL_DATABASE + value: registry + volumeMounts: + - mountPath: "/var/lib/postgresql/data" + name: "registry-pgdata" + volumes: + - emptyDir: + sizeLimit: 500Mi + name: registry-pgdata +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: postgresql + name: postgresql-service +spec: + ports: + - name: http + port: 5432 + protocol: TCP + targetPort: 5432 + selector: + app: postgresql + type: ClusterIP \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/sql/registry-multitenant-sql.yml b/integration-tests/src/test/resources/infra/sql/registry-multitenant-sql.yml new file mode 100644 index 0000000000..ecb89906e0 --- /dev/null +++ b/integration-tests/src/test/resources/infra/sql/registry-multitenant-sql.yml @@ -0,0 +1,85 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-sql + name: apicurio-registry-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: apicurio-registry-sql + template: + metadata: + labels: + app: apicurio-registry-sql + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: REGISTRY_DATASOURCE_URL + value: jdbc:postgresql://postgresql-service:5432/registry + - name: REGISTRY_DATASOURCE_USERNAME + value: "apicurio" + - name: REGISTRY_DATASOURCE_PASSWORD + value: "registry" + - name: REGISTRY_ENABLE_MULTITENANCY + value: "true" + - name: REGISTRY_DISABLE_APIS + value: "" + - name: REGISTRY_MULTITENANCY_REAPER_PERIOD_SECONDS + value: "10" + - name: REGISTRY_MULTITENANCY_REAPER_EVERY + value: "3s" + - name: TENANT_MANAGER_URL + value: "http://tenant-manager-service:8585" + - name: REGISTRY_MULTITENANCY_REAPER_MAX_TENANTS_REAPED + value: "5" + image: registry-image + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: apicurio-registry-sql + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-sql + name: apicurio-registry-service +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 8080 + selector: + app: apicurio-registry-sql + type: ClusterIP \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/sql/registry-sql-old.yml b/integration-tests/src/test/resources/infra/sql/registry-sql-old.yml new file mode 100644 index 0000000000..7bf013727b --- /dev/null +++ b/integration-tests/src/test/resources/infra/sql/registry-sql-old.yml @@ -0,0 +1,92 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-sql + name: apicurio-registry-deployment +spec: + replicas: 3 + selector: + matchLabels: + app: apicurio-registry-sql + template: + metadata: + labels: + app: apicurio-registry-sql + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: REGISTRY_DATASOURCE_URL + value: jdbc:postgresql://postgresql-service:5432/registry + - name: REGISTRY_DATASOURCE_USERNAME + value: "apicurio" + - name: REGISTRY_DATASOURCE_PASSWORD + value: "registry" + - name: REGISTRY_ENABLE_MULTITENANCY + value: "true" + - name: REGISTRY_DISABLE_APIS + value: "" + - name: TENANT_MANAGER_AUTH_ENABLED + value: "false" + - name: REGISTRY_MULTITENANCY_REAPER_PERIOD_SECONDS + value: "10" + - name: REGISTRY_MULTITENANCY_REAPER_EVERY + value: "3s" + - name: TENANT_MANAGER_URL + value: "http://tenant-manager-service:8585" + image: quay.io/apicurio/apicurio-registry-sql:2.1.0.Final + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: apicurio-registry-sql + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-sql + name: apicurio-registry-service +spec: + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + nodePort: 32586 + selector: + app: apicurio-registry-sql + type: LoadBalancer + sessionAffinity: None + externalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + allocateLoadBalancerNodePorts: true + internalTrafficPolicy: Cluster \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/sql/registry-sql-secured.yml b/integration-tests/src/test/resources/infra/sql/registry-sql-secured.yml new file mode 100644 index 0000000000..11b155c581 --- /dev/null +++ b/integration-tests/src/test/resources/infra/sql/registry-sql-secured.yml @@ -0,0 +1,102 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-sql + name: apicurio-registry-deployment +spec: + replicas: 3 + selector: + matchLabels: + app: apicurio-registry-sql + template: + metadata: + labels: + app: apicurio-registry-sql + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: REGISTRY_DATASOURCE_URL + value: jdbc:postgresql://postgresql-service:5432/registry + - name: REGISTRY_DATASOURCE_USERNAME + value: "apicurio" + - name: REGISTRY_DATASOURCE_PASSWORD + value: "registry" + - name: AUTH_ENABLED + value: "true" + - name: KEYCLOAK_API_CLIENT_ID + value: "registry-api" + - name: KEYCLOAK_UI_CLIENT_ID + value: apicurio-registry + - name: REGISTRY_UI_CONFIG_AUTH_KEYCLOAK_URL + value: 'http://localhost:8090' + - name: KEYCLOAK_REALM + value: 'registry' + - name: QUARKUS_OIDC_AUTH_SERVER_URL + value: "http://keycloak-service:8090/realms/registry" + - name: QUARKUS_OIDC_TLS_VERIFICATION + value: none + - name: TOKEN_ENDPOINT + value: "http://keycloak-service:8090/realms/registry/protocol/openid-connect/token" + - name: CLIENT_CREDENTIALS_BASIC_AUTH_ENABLED + value: "true" + - name: REGISTRY_AUTH_RBAC_ENABLED + value: "true" + - name: REGISTRY_AUTH_ROLE_SOURCE + value: "token" + image: registry-image + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: apicurio-registry-sql + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-sql + name: apicurio-registry-service +spec: + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + nodePort: 32586 + selector: + app: apicurio-registry-sql + type: LoadBalancer + sessionAffinity: None + externalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + allocateLoadBalancerNodePorts: true + internalTrafficPolicy: Cluster \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/sql/registry-sql.yml b/integration-tests/src/test/resources/infra/sql/registry-sql.yml new file mode 100644 index 0000000000..066859d825 --- /dev/null +++ b/integration-tests/src/test/resources/infra/sql/registry-sql.yml @@ -0,0 +1,80 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-sql + name: apicurio-registry-deployment +spec: + replicas: 3 + selector: + matchLabels: + app: apicurio-registry-sql + template: + metadata: + labels: + app: apicurio-registry-sql + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: REGISTRY_DATASOURCE_URL + value: jdbc:postgresql://postgresql-service:5432/registry + - name: REGISTRY_DATASOURCE_USERNAME + value: "apicurio" + - name: REGISTRY_DATASOURCE_PASSWORD + value: "registry" + image: registry-image + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /health/live + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: apicurio-registry-sql + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: apicurio-registry-sql + name: apicurio-registry-service +spec: + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + nodePort: 32586 + selector: + app: apicurio-registry-sql + type: LoadBalancer + sessionAffinity: None + externalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + allocateLoadBalancerNodePorts: true + internalTrafficPolicy: Cluster \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/tenant-manager/tenant-manager-database.yml b/integration-tests/src/test/resources/infra/tenant-manager/tenant-manager-database.yml new file mode 100644 index 0000000000..45e1c2cf91 --- /dev/null +++ b/integration-tests/src/test/resources/infra/tenant-manager/tenant-manager-database.yml @@ -0,0 +1,55 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: tenant-manager-database + name: tenant-manager-database +spec: + replicas: 1 + selector: + matchLabels: + app: tenant-manager-database + template: + metadata: + labels: + app: tenant-manager-database + spec: + containers: + - name: postgresql + image: quay.io/centos7/postgresql-13-centos7 + ports: + - containerPort: 5432 + env: + - name: POSTGRESQL_DB + value: tenant-manager + - name: POSTGRESQL_USER + value: apicurio + - name: POSTGRESQL_PASSWORD + value: tenant-manager + - name: POSTGRESQL_DATABASE + value: tenant-manager + volumeMounts: + - mountPath: "/var/lib/postgresql/data" + name: "tenant-manager-pgdata" + volumes: + - emptyDir: + sizeLimit: 500Mi + name: tenant-manager-pgdata +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: tenant-manager-database + name: tenant-manager-database-service +spec: + ports: + - name: http + port: 5432 + protocol: TCP + targetPort: 5432 + selector: + app: tenant-manager-database + type: ClusterIP \ No newline at end of file diff --git a/integration-tests/src/test/resources/infra/tenant-manager/tenant-manager.yml b/integration-tests/src/test/resources/infra/tenant-manager/tenant-manager.yml new file mode 100644 index 0000000000..3d7c876362 --- /dev/null +++ b/integration-tests/src/test/resources/infra/tenant-manager/tenant-manager.yml @@ -0,0 +1,86 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: tenant-manager-app + name: tenant-manager-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: tenant-manager-app + template: + metadata: + labels: + app: tenant-manager-app + spec: + containers: + - env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: DATASOURCE_URL + value: jdbc:postgresql://tenant-manager-database-service:5432/tenant-manager + - name: DATASOURCE_USERNAME + value: "apicurio" + - name: DATASOURCE_PASSWORD + value: "tenant-manager" + - name: QUARKUS_HTTP_PORT + value: "8585" + - name: ENABLE_TEST_STATUS_TRANSITION + value: "true" + - name: REGISTRY_ROUTE_URL + value: "" + image: quay.io/apicurio/apicurio-tenant-manager-api:latest + imagePullPolicy: Always + livenessProbe: + failureThreshold: 3 + httpGet: + path: /q/health/live + port: 8585 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + name: tenant-manager-app + ports: + - containerPort: 8585 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /q/health/ready + port: 8585 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + namespace: "apicurio-registry-e2e" + labels: + app: tenant-manager-app + name: tenant-manager-service +spec: + ports: + - protocol: TCP + port: 8585 + targetPort: 8585 + nodePort: 32587 + selector: + app: tenant-manager-app + type: LoadBalancer + sessionAffinity: None + externalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + allocateLoadBalancerNodePorts: true + internalTrafficPolicy: Cluster \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/serdes/person.proto b/integration-tests/src/test/resources/serdes/person.proto similarity index 100% rename from integration-tests/testsuite/src/test/resources/serdes/person.proto rename to integration-tests/src/test/resources/serdes/person.proto diff --git a/integration-tests/testsuite/src/test/resources/serdes/testmessage.proto b/integration-tests/src/test/resources/serdes/testmessage.proto similarity index 100% rename from integration-tests/testsuite/src/test/resources/serdes/testmessage.proto rename to integration-tests/src/test/resources/serdes/testmessage.proto diff --git a/integration-tests/testsuite/pom.xml b/integration-tests/testsuite/pom.xml deleted file mode 100644 index 3bf4671774..0000000000 --- a/integration-tests/testsuite/pom.xml +++ /dev/null @@ -1,405 +0,0 @@ - - - 4.0.0 - - io.apicurio - apicurio-registry - 2.4.13-SNAPSHOT - ../../pom.xml - - apicurio-registry-integration-tests-testsuite - apicurio-registry-testsuite - - - - true - - 5.10.0 - 1.9.1 - - 2.3.0 - 2.2 - 3.1.2 - - - - - OSSRH - OSS Sonatype - https://oss.sonatype.org/content/repositories/snapshots/ - - - - - - - io.apicurio - apicurio-registry-protobuf-schema-utilities - - - - io.apicurio - apicurio-registry-integration-tests-common - - - - io.apicurio - apicurio-tenant-manager-client - - - - org.jboss.slf4j - slf4j-jboss-logmanager - - - - - - - io.apicurio - apicurio-common-rest-client-vertx - - - - - io.apicurio - apicurio-data-models - provided - - - - org.hamcrest - hamcrest - ${hamcrest.version} - provided - - - - org.jboss.slf4j - slf4j-jboss-logging - ${jboss-slf4j.version} - - - - - io.confluent - kafka-avro-serializer - provided - - - io.confluent - kafka-connect-avro-converter - test - - - - org.junit.jupiter - junit-jupiter - ${junit.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit.version} - provided - - - org.junit.platform - junit-platform-launcher - ${junit.platform-launcher.version} - compile - - - - org.apache.kafka - connect-api - ${kafka.version} - - - org.apache.kafka - connect-json - ${kafka.version} - - - - io.apicurio - apicurio-registry-client - - - - io.apicurio - apicurio-registry-utils-import-export - - - - com.squareup.wire - wire-schema - - - com.squareup.wire - wire-compiler - - - - - com.squareup.okio - okio-jvm - - - - com.squareup.okio - okio-fakefilesystem - - - - io.apicurio - apicurio-registry-serdes-avro-serde - - - io.apicurio - apicurio-registry-serdes-protobuf-serde - - - io.apicurio - apicurio-registry-serdes-jsonschema-serde - - - - - io.apicurio - apicurio-registry-utils-converter - - - - org.apache.kafka - connect-api - - - org.apache.kafka - connect-json - - - - - - - org.seleniumhq.selenium - selenium-java - 3.141.59 - test - - - org.testcontainers - selenium - ${test-containers.version} - test - - - commons-io - commons-io - test - - - - - - - - src/test/resources - true - - - - - org.apache.maven.plugins - maven-deploy-plugin - - true - - - - org.apache.maven.plugins - maven-failsafe-plugin - ${version.failsafe.plugin} - - ${groups} - ${skipTests} - - ${project.version} - ${test.storage} - ${groups} - privateKey.jwk - - - - - - integration-test - verify - - - - false - 3.0 - false - true - true - true - - - false - UTF-8 - true - - - ${exclude.integration.tests} - - - - - - - - - - - - all - - false - ( smoke | serdes | acceptance | ui ) & !multitenancy - - - - - ci - - false - ( smoke | serdes | acceptance ) & !multitenancy - - - - - smoke - - false - smoke & !multitenancy - - - - - serdes - - false - serdes & !multitenancy - - - - - ui - - false - ui & !multitenancy - - - - - acceptance - - false - acceptance & !multitenancy - - - - - multitenancy - - false - multitenancy - - - - - clustered - - false - clustered | smoke | acceptance - - - - - migration - - false - migration - - - - - auth - - false - auth - - - - - dbupgrade - - false - dbupgrade - - - - - sqlit - - false - sqlit - - - - - kafkasqlit - - false - kafkasqlit - - - - - disableSerdesTest - - **/BasicApicurioSerDesIT.java - - - - - - inmemory - - inmemory - - - - - sql - - sql - - - - - kafkasql - - kafkasql - - - - diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ApicurioV2BaseIT.java b/integration-tests/testsuite/src/test/java/io/apicurio/tests/ApicurioV2BaseIT.java deleted file mode 100644 index c0a2a9188f..0000000000 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/ApicurioV2BaseIT.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.apicurio.registry.rest.client.RegistryClient; -import io.apicurio.registry.rest.client.RegistryClientFactory; -import io.apicurio.registry.rest.client.exception.ArtifactNotFoundException; -import io.apicurio.registry.rest.client.exception.RestClientException; -import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; -import io.apicurio.registry.rest.v2.beans.ArtifactSearchResults; -import io.apicurio.registry.rest.v2.beans.IfExists; -import io.apicurio.registry.rest.v2.beans.SearchedArtifact; -import io.apicurio.registry.rest.v2.beans.SearchedVersion; -import io.apicurio.registry.rest.v2.beans.VersionMetaData; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.LoadBalanceRegistryClient.RegistryClientHolder; -import io.apicurio.tests.common.ApicurioRegistryBaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.RegistryFacade; -import io.apicurio.tests.common.utils.RegistryUtils; -import io.apicurio.tests.utils.RegistryWaitUtils; -import io.apicurio.tests.utils.RegistryWaitUtils.ConsumerExc; -import io.restassured.RestAssured; -import io.restassured.parsing.Parser; - -/** - * @author Fabian Martinez - */ -public class ApicurioV2BaseIT extends ApicurioRegistryBaseIT { - - protected final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - - protected Function errorCodeExtractor = e -> ((RestClientException) e).getError().getErrorCode(); - - protected final RegistryClient registryClient = createRegistryClient(); - - protected RegistryClient createRegistryClient() { - if (!TestUtils.isExternalRegistry() && RegistryUtils.TEST_PROFILE.contains(Constants.CLUSTERED)) { - logger.info("Using load-balancer registry client"); - return new LoadBalanceRegistryClient(RegistryFacade.getInstance().getClusteredRegistryNodes()); - } else { - return RegistryClientFactory.create(TestUtils.getRegistryBaseUrl()); - } - } - - @BeforeAll - void prepareRestAssured() { - RestAssured.baseURI = TestUtils.getRegistryV2ApiUrl(); - logger.info("RestAssured configured with {}", RestAssured.baseURI); - RestAssured.defaultParser = Parser.JSON; - RestAssured.urlEncodingEnabled = false; - } - - @AfterEach - void cleanArtifacts() throws Exception { - logger.info("Removing all artifacts"); - // Retrying to delete artifacts can solve the problem with bad order caused by artifacts references - // TODO: Solve problem with artifact references circle - maybe use of deleteAllUserData for cleaning artifacts after IT - TestUtils.retry(() -> { - ArtifactSearchResults artifacts = registryClient.searchArtifacts(null, null, null, null, null, null, null, null, null); - for (SearchedArtifact artifact : artifacts.getArtifacts()) { - try { - registryClient.deleteArtifact(artifact.getGroupId(), artifact.getId()); - registryClient.deleteArtifactsInGroup(null); - } catch (ArtifactNotFoundException e) { - //because of async storage artifact may be already deleted but listed anyway - logger.info(e.getMessage()); - } catch (Exception e) { - logger.error("", e); - } - } - ensureClusterSync(client -> assertTrue(client.searchArtifacts(null, null, null, null, null, null, null, null, null).getCount() == 0)); - }, "CleanArtifacts", 5); - } - - protected ArtifactMetaData createArtifact(String groupId, String artifactId, String artifactType, InputStream artifact) throws Exception { - ArtifactMetaData amd = registryClient.createArtifact(groupId, artifactId, null, artifactType, IfExists.FAIL, false, artifact); - - // make sure we have schema registered - ensureClusterSync(amd.getGlobalId()); - ensureClusterSync(amd.getGroupId(), amd.getId(), String.valueOf(amd.getVersion())); - - return amd; - } - - protected ArtifactMetaData createArtifact(String groupId, String artifactId, String version, IfExists ifExists, String artifactType, InputStream artifact) throws Exception { - ArtifactMetaData amd = registryClient.createArtifact(groupId, artifactId, version, artifactType, ifExists, false, artifact); - - // make sure we have schema registered - ensureClusterSync(amd.getGlobalId()); - ensureClusterSync(amd.getGroupId(), amd.getId(), String.valueOf(amd.getVersion())); - - return amd; - } - - protected VersionMetaData createArtifactVersion(String groupId, String artifactId, InputStream artifact) throws Exception { - VersionMetaData meta = registryClient.createArtifactVersion(groupId, artifactId, null, artifact); - - //wait for storage - ensureClusterSync(meta.getGlobalId()); - ensureClusterSync(meta.getGroupId(), meta.getId(), String.valueOf(meta.getVersion())); - - return meta; - } - - protected ArtifactMetaData updateArtifact(String groupId, String artifactId, InputStream artifact) throws Exception { - ArtifactMetaData meta = registryClient.updateArtifact(groupId, artifactId, artifact); - - //wait for storage - ensureClusterSync(meta.getGlobalId()); - ensureClusterSync(meta.getGroupId(), meta.getId(), String.valueOf(meta.getVersion())); - - return meta; - } - - //DO NOT USE FOR CREATE OR UPDATE OPERATIONS - protected void retryOp(ConsumerExc registryOp) throws Exception { - RegistryWaitUtils.retry(registryClient, registryOp); - } - - //DO NOT USE FOR CREATE OR UPDATE OPERATIONS - protected void retryAssertClientError(String expectedErrorName, int expectedCode, ConsumerExc registryOp, Function errorCodeExtractor) throws Exception { - RegistryWaitUtils.retry(registryClient, (rc) -> { - TestUtils.assertClientError(expectedErrorName, expectedCode, () -> registryOp.run(rc), errorCodeExtractor); - }); - } - - private void ensureClusterSync(Long globalId) throws Exception { - if (registryClient instanceof LoadBalanceRegistryClient) { - LoadBalanceRegistryClient loadBalanceRegistryClient = (LoadBalanceRegistryClient) registryClient; - - var nodes = loadBalanceRegistryClient.getRegistryNodes(); - - TestUtils.retry(() -> { - for (RegistryClientHolder target : nodes) { - target.client.getContentByGlobalId(globalId); - } - }); - } else { - TestUtils.retry(() -> registryClient.getContentByGlobalId(globalId)); - } - } - - private void ensureClusterSync(String groupId, String artifactId, String version) throws Exception { - if (registryClient instanceof LoadBalanceRegistryClient) { - LoadBalanceRegistryClient loadBalanceRegistryClient = (LoadBalanceRegistryClient) registryClient; - - var nodes = loadBalanceRegistryClient.getRegistryNodes(); - - TestUtils.retry(() -> { - for (RegistryClientHolder target : nodes) { - target.client.getArtifactVersionMetaData(groupId, artifactId, version); - } - }); - } else { - TestUtils.retry(() -> registryClient.getArtifactVersionMetaData(groupId, artifactId, version)); - } - } - - private void ensureClusterSync(Consumer function) throws Exception { - if (registryClient instanceof LoadBalanceRegistryClient) { - LoadBalanceRegistryClient loadBalanceRegistryClient = (LoadBalanceRegistryClient) registryClient; - - var nodes = loadBalanceRegistryClient.getRegistryNodes(); - - TestUtils.retry(() -> { - for (RegistryClientHolder target : nodes) { - function.accept(target.client); - } - }); - } else { - TestUtils.retry(() -> function.accept(registryClient)); - } - } - - protected List listArtifactVersions(RegistryClient rc, String groupId, String artifactId) { - return rc.listArtifactVersions(groupId, artifactId, 0, 10) - .getVersions() - .stream() - .map(SearchedVersion::getVersion) - .collect(Collectors.toList()); - } - - public static String resourceToString(String resourceName) { - try (InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName)) { - Assertions.assertNotNull(stream, "Resource not found: " + resourceName); - return new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n")); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/clustered/ClusteredRegistryIT.java b/integration-tests/testsuite/src/test/java/io/apicurio/tests/clustered/ClusteredRegistryIT.java deleted file mode 100644 index c2747a27a6..0000000000 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/clustered/ClusteredRegistryIT.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests.clustered; - -import java.io.ByteArrayInputStream; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.List; -import java.util.UUID; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import io.apicurio.registry.rest.client.RegistryClient; -import io.apicurio.registry.rest.client.RegistryClientFactory; -import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; -import io.apicurio.registry.rest.v2.beans.ArtifactSearchResults; -import io.apicurio.registry.rest.v2.beans.EditableMetaData; -import io.apicurio.registry.rest.v2.beans.Rule; -import io.apicurio.registry.rest.v2.beans.SortBy; -import io.apicurio.registry.rest.v2.beans.SortOrder; -import io.apicurio.registry.rest.v2.beans.VersionSearchResults; -import io.apicurio.registry.types.ArtifactType; -import io.apicurio.registry.types.RuleType; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; -import io.confluent.kafka.schemaregistry.ParsedSchema; -import io.confluent.kafka.schemaregistry.avro.AvroSchema; -import io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient; -import io.confluent.kafka.schemaregistry.client.SchemaRegistryClient; - -/** - * @author Fabian Martinez - */ -@Tag(Constants.CLUSTERED) -public class ClusteredRegistryIT extends ApicurioV2BaseIT { - - private final String groupId = getClass().getSimpleName(); - - @Test - public void testSmoke() throws Exception { - - RegistryClient client1 = RegistryClientFactory.create("http://localhost:" + TestUtils.getRegistryPort() + "/apis/registry/v2"); - int node2port = TestUtils.getRegistryPort() + 1; - RegistryClient client2 = RegistryClientFactory.create("http://localhost:" + node2port + "/apis/registry/v2"); - - // warm-up both nodes (its storages) - client1.listArtifactsInGroup("testSmoke"); - client2.listArtifactsInGroup("testSmoke"); - - String artifactId = UUID.randomUUID().toString(); - ByteArrayInputStream stream = new ByteArrayInputStream("{\"name\":\"redhat\"}".getBytes(StandardCharsets.UTF_8)); - client1.createArtifact(groupId, artifactId, ArtifactType.JSON, stream).getGlobalId(); - try { - TestUtils.retry(() -> { - ArtifactMetaData amd = client2.getArtifactMetaData(groupId, artifactId); - Assertions.assertEquals("1", amd.getVersion()); - }, "ClusterIT-SmokeTest-CreateArtifact", 10); - - String name = UUID.randomUUID().toString(); - String desc = UUID.randomUUID().toString(); - - EditableMetaData emd = new EditableMetaData(); - emd.setName(name); - emd.setDescription(desc); - client1.updateArtifactMetaData(groupId, artifactId, emd); - - TestUtils.retry(() -> { - ArtifactMetaData amd = client2.getArtifactMetaData(groupId, artifactId); - Assertions.assertEquals(name, amd.getName()); - Assertions.assertEquals(desc, amd.getDescription()); - }); - - Rule rule = new Rule(); - rule.setType(RuleType.VALIDITY); - rule.setConfig("myconfig"); - client1.createArtifactRule(groupId, artifactId, rule); - - TestUtils.retry(() -> { - Rule config = client2.getArtifactRuleConfig(groupId, artifactId, RuleType.VALIDITY); - Assertions.assertEquals(rule.getConfig(), config.getConfig()); - }); - - VersionSearchResults vres1 = client1.listArtifactVersions(groupId, artifactId, 0, 500); - VersionSearchResults vres2 = client2.listArtifactVersions(groupId, artifactId, 0, 500); - Assertions.assertEquals(vres1.getCount(), vres2.getCount()); - - List rt1 = client1.listArtifactRules(groupId, artifactId); - List rt2 = client2.listArtifactRules(groupId, artifactId); - Assertions.assertEquals(rt1, rt2); - - Rule globalRule = new Rule(); - globalRule.setType(RuleType.COMPATIBILITY); - globalRule.setConfig("gc"); - client1.createGlobalRule(globalRule); - try { - TestUtils.retry(() -> { - List grts = client2.listGlobalRules(); - Assertions.assertTrue(grts.contains(globalRule.getType())); - }); - } finally { - client1.deleteGlobalRule(RuleType.COMPATIBILITY); - } - } finally { - client1.deleteArtifact(groupId, artifactId); - } - } - - @Test - public void testConfluent() throws Exception { - - SchemaRegistryClient client1 = new CachedSchemaRegistryClient("http://localhost:" + TestUtils.getRegistryPort() + "/apis/ccompat/v6", 3); - int node2port = TestUtils.getRegistryPort() + 1; - SchemaRegistryClient client2 = new CachedSchemaRegistryClient("http://localhost:" + node2port + "/apis/ccompat/v6", 3); - - String subject = UUID.randomUUID().toString(); - ParsedSchema schema = new AvroSchema("{\"type\":\"record\",\"name\":\"myrecord1\",\"fields\":[{\"name\":\"f1\",\"type\":\"string\"}]}"); - int id = client1.register(subject, schema); - try { - TestUtils.retry(() -> { - Collection allSubjects = client2.getAllSubjects(); - Assertions.assertTrue(allSubjects.contains(subject)); - }, "ClusterIT-SmokeTest-RegisterSchema-1", 10); - - TestUtils.retry(() -> { - ParsedSchema s = client2.getSchemaById(id); - Assertions.assertNotNull(s); - }, "ClusterIT-SmokeTest-RegisterSchema-2", 10); - } finally { - client1.deleteSchemaVersion(subject, "1"); - } - } - - @Test - public void testSearch() throws Exception { - - RegistryClient client1 = RegistryClientFactory.create("http://localhost:" + TestUtils.getRegistryPort() + "/apis/registry/v2"); - int node2port = TestUtils.getRegistryPort() + 1; - RegistryClient client2 = RegistryClientFactory.create("http://localhost:" + node2port + "/apis/registry/v2"); - - // warm-up both nodes (its storages) - client1.listArtifactsInGroup(groupId); - client2.listArtifactsInGroup(groupId); - - String artifactId = UUID.randomUUID().toString(); - ByteArrayInputStream stream = new ByteArrayInputStream(("{\"name\":\"redhat\"}").getBytes(StandardCharsets.UTF_8)); - client1.createArtifact(groupId, artifactId, ArtifactType.JSON, stream); - try { - String name = UUID.randomUUID().toString(); - String desc = UUID.randomUUID().toString(); - - TestUtils.retry(() -> { - EditableMetaData emd = new EditableMetaData(); - emd.setName(name); - emd.setDescription(desc); - client2.updateArtifactMetaData(groupId, artifactId, emd); - }); - - TestUtils.retry(() -> { - ArtifactSearchResults results = client2.searchArtifacts(groupId, name, null, null, null, SortBy.name, SortOrder.asc, 0, 2); - Assertions.assertNotNull(results); - Assertions.assertEquals(1, results.getCount(), "Invalid results count -- name"); - Assertions.assertEquals(1, results.getArtifacts().size(), "Invalid artifacts size -- name"); - Assertions.assertEquals(name, results.getArtifacts().get(0).getName()); - Assertions.assertEquals(desc, results.getArtifacts().get(0).getDescription()); - }); - TestUtils.retry(() -> { - // client 1 ! - ArtifactSearchResults results = client1.searchArtifacts(groupId, null, desc, null, null, SortBy.name, SortOrder.asc, 0, 2); - Assertions.assertNotNull(results); - Assertions.assertEquals(1, results.getCount(), "Invalid results count -- description"); - Assertions.assertEquals(1, results.getArtifacts().size(), "Invalid artifacts size -- description"); - Assertions.assertEquals(name, results.getArtifacts().get(0).getName()); - Assertions.assertEquals(desc, results.getArtifacts().get(0).getDescription()); - }); - } finally { - client1.deleteArtifact(groupId, artifactId); - } - } - - @Test - public void testGetContentByGlobalId() throws Exception { - - RegistryClient client1 = RegistryClientFactory.create("http://localhost:" + TestUtils.getRegistryPort() + "/apis/registry/v2"); - int node2port = TestUtils.getRegistryPort() + 1; - RegistryClient client2 = RegistryClientFactory.create("http://localhost:" + node2port + "/apis/registry/v2"); - - // warm-up both nodes (its storages) - client1.listArtifactsInGroup(groupId); - client2.listArtifactsInGroup(groupId); - - String artifactId = UUID.randomUUID().toString(); - String secondId = UUID.randomUUID().toString(); - String thirdId = UUID.randomUUID().toString(); - - ByteArrayInputStream first = new ByteArrayInputStream(("{\"name\":\"redhat\"}").getBytes(StandardCharsets.UTF_8)); - ByteArrayInputStream second = new ByteArrayInputStream(("{\"name\":\"ibm\"}").getBytes(StandardCharsets.UTF_8)); - ByteArrayInputStream third = new ByteArrayInputStream(("{\"name\":\"company\"}").getBytes(StandardCharsets.UTF_8)); - final ArtifactMetaData firstArtifact = client1.createArtifact(groupId, artifactId, ArtifactType.JSON, first); - final ArtifactMetaData secondArtifact = client2.createArtifact(groupId, secondId, ArtifactType.JSON, second); - final ArtifactMetaData thirdArtifact = client1.createArtifact(groupId, thirdId, ArtifactType.JSON, third); - - try { - String name = UUID.randomUUID().toString(); - String desc = UUID.randomUUID().toString(); - - TestUtils.retry(() -> { - EditableMetaData emd = new EditableMetaData(); - emd.setName(name); - emd.setDescription(desc); - client2.updateArtifactMetaData(groupId, artifactId, emd); - }); - - TestUtils.retry(() -> { - client2.getContentByGlobalId(firstArtifact.getGlobalId()); - client1.getContentByGlobalId(secondArtifact.getGlobalId()); - client2.getContentByGlobalId(thirdArtifact.getGlobalId()); - }); - } finally { - client1.deleteArtifact(groupId, artifactId); - client1.deleteArtifact(groupId, secondId); - client1.deleteArtifact(groupId, thirdId); - } - } - -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlLogCompactionIT.java b/integration-tests/testsuite/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlLogCompactionIT.java deleted file mode 100644 index 493a307557..0000000000 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlLogCompactionIT.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests.dbupgrade; - -import static io.apicurio.tests.utils.CustomTestsUtils.createArtifact; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Map; - -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.kafka.clients.admin.NewTopic; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.api.TestInstance.Lifecycle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.apicurio.registry.rest.client.RegistryClientFactory; -import io.apicurio.registry.types.ArtifactType; -import io.apicurio.registry.utils.tests.SimpleDisplayName; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.KafkaFacade; -import io.apicurio.tests.common.RegistryFacade; -import io.apicurio.tests.common.RegistryStorageType; -import io.apicurio.tests.common.interfaces.TestSeparator; -import io.apicurio.tests.common.utils.RegistryUtils; - -/** - * @author Fabian Martinez - */ -@DisplayNameGeneration(SimpleDisplayName.class) -@TestInstance(Lifecycle.PER_CLASS) -@Tag(Constants.DB_UPGRADE) -@Tag(Constants.KAFKA_SQL) -public class KafkaSqlLogCompactionIT implements TestSeparator, Constants { - - final Logger logger = LoggerFactory.getLogger(getClass()); - - - @Test - public void testLogCompaction() throws Exception { - - RegistryStorageType previousStorageValue = RegistryUtils.REGISTRY_STORAGE; - - String testName = "testLogCompaction"; - RegistryStorageType storage = RegistryStorageType.kafkasql; - - RegistryUtils.REGISTRY_STORAGE = storage; - - Path logsPath = RegistryUtils.getLogsPath(getClass(), testName); - RegistryFacade facade = RegistryFacade.getInstance(); - - try { - - Map appEnv = facade.initRegistryAppEnv(); - - //runs all required infra except for the registry - facade.deployStorage(appEnv, storage); - - //Create the kafkasql-journal topic with aggressive log compaction - //bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic kafkasql-journal --partitions 1 --replication-factor 1 --config min.cleanable.dirty.ratio=0.000001 --config cleanup.policy=compact --config segment.ms=100 --config delete.retention.ms=100 - var kafkaAdminClient = KafkaFacade.getInstance().adminClient(); - var journal = new NewTopic("kafkasql-journal", 1, (short)1); - journal.configs(Map.of( - "min.cleanable.dirty.ratio","0.000001", - "cleanup.policy","compact", - "segment.ms", "100", - "delete.retention.ms", "100" - )); - kafkaAdminClient.createTopics(Arrays.asList(journal)); - - appEnv.put("QUARKUS_HTTP_PORT", "8081"); - - String registryNameSuffix = "first-start"; - facade.runRegistry(appEnv, registryNameSuffix, "8081"); - facade.waitForRegistryReady(); - // - - var registryClient = RegistryClientFactory.create("http://localhost:8081"); - - createArtifact(registryClient, ArtifactType.AVRO, ApicurioV2BaseIT.resourceToString("artifactTypes/" + "avro/multi-field_v1.json")); - var artifactdata = createArtifact(registryClient, ArtifactType.JSON, ApicurioV2BaseIT.resourceToString("artifactTypes/" + "jsonSchema/person_v1.json")); - createArtifact(registryClient, ArtifactType.PROTOBUF, ApicurioV2BaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v1.proto")); - - assertEquals(3, registryClient.listArtifactsInGroup(null).getCount()); - - //spend some time doing something - //this is just to give kafka some time to be 100% the topic is log compactedsddddddd - logger.info("Giving kafka some time to do log compaction"); - for (int i = 0; i<15; i++) { - registryClient.getArtifactMetaData(artifactdata.meta.getGroupId(), artifactdata.meta.getId()); - Thread.sleep(900); - } - logger.info("Finished giving kafka some time"); - - // - - facade.stopProcess(logsPath, "registry-" + registryNameSuffix); - - facade.runRegistry(appEnv, "registry-second-start", "8081"); - facade.waitForRegistryReady(); - - // - - var searchResults = registryClient.listArtifactsInGroup(null); - assertEquals(3, searchResults.getCount()); - - String test2content = ApicurioV2BaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v2.proto"); - String originalHash = DigestUtils.sha256Hex(test2content); - var artifact = createArtifact(registryClient, ArtifactType.PROTOBUF, test2content); - - assertEquals(originalHash, artifact.contentHash); - - String byglobalidHash = DigestUtils.sha256Hex(registryClient.getContentByGlobalId(artifact.meta.getGlobalId())); - String bycontentidHash = DigestUtils.sha256Hex(registryClient.getContentById(artifact.meta.getContentId())); - - assertEquals(originalHash, byglobalidHash); - assertEquals(originalHash, bycontentidHash); - - //assert total num of artifacts - assertEquals(4, registryClient.listArtifactsInGroup(null).getCount()); - - - } finally { - try { - facade.stopAndCollectLogs(logsPath); - } finally { - RegistryUtils.REGISTRY_STORAGE = previousStorageValue; - } - } - - } - -} diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlStorageUpgradeIT.java b/integration-tests/testsuite/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlStorageUpgradeIT.java deleted file mode 100644 index 61c972a445..0000000000 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/dbupgrade/KafkaSqlStorageUpgradeIT.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests.dbupgrade; - -import static io.apicurio.tests.utils.CustomTestsUtils.createArtifact; -import static io.apicurio.tests.utils.CustomTestsUtils.createArtifactWithReferences; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.nio.file.Path; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.stream.Collectors; - -import io.apicurio.registry.rest.v2.beans.ArtifactReference; -import org.apache.commons.codec.digest.DigestUtils; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.api.TestInstance.Lifecycle; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.images.RemoteDockerImage; -import org.testcontainers.utility.DockerImageName; - -import io.apicurio.registry.rest.client.RegistryClientFactory; -import io.apicurio.registry.types.ArtifactType; -import io.apicurio.registry.utils.IoUtil; -import io.apicurio.registry.utils.tests.SimpleDisplayName; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.RegistryFacade; -import io.apicurio.tests.common.RegistryStorageType; -import io.apicurio.tests.common.interfaces.TestSeparator; -import io.apicurio.tests.common.utils.RegistryUtils; -import io.apicurio.tests.utils.CustomTestsUtils.ArtifactData; - -/** - * Note this test does not extend any base class - * - */ -@DisplayNameGeneration(SimpleDisplayName.class) -@TestInstance(Lifecycle.PER_CLASS) -@Tag(Constants.DB_UPGRADE) -@Tag(Constants.KAFKA_SQL) -public class KafkaSqlStorageUpgradeIT implements TestSeparator, Constants { - - private static final String ARTIFACT_CONTENT = "{\"name\":\"redhat\"}"; - private static final String REFERENCE_CONTENT = "{\"name\":\"ibm\"}"; - - @Test - public void testStorageUpgradeProtobufUpgraderKafkaSql() throws Exception { - testStorageUpgradeProtobufUpgrader("protobufCanonicalHashKafkaSql", RegistryStorageType.kafkasql); - } - - public void testStorageUpgradeProtobufUpgrader(String testName, RegistryStorageType storage) throws Exception { - - RegistryStorageType previousStorageValue = RegistryUtils.REGISTRY_STORAGE; - RegistryUtils.REGISTRY_STORAGE = storage; - - Path logsPath = RegistryUtils.getLogsPath(getClass(), testName); - RegistryFacade facade = RegistryFacade.getInstance(); - - try { - - Map appEnv = facade.initRegistryAppEnv(); - - //runs all required infra except for the registry - facade.deployStorage(appEnv, storage); - - appEnv.put("QUARKUS_HTTP_PORT", "8081"); - - String oldRegistryName = "registry-dbv4"; - String image = "quay.io/apicurio/apicurio-registry-kafkasql:2.1.2.Final"; - - var container = new GenericContainer<>(new RemoteDockerImage(DockerImageName.parse(image))); - container.setNetworkMode("host"); - facade.runContainer(appEnv, oldRegistryName, container); - facade.waitForRegistryReady(); - - // - - var registryClient = RegistryClientFactory.create("http://localhost:8081/"); - - createArtifact(registryClient, ArtifactType.AVRO, ApicurioV2BaseIT.resourceToString("artifactTypes/" + "avro/multi-field_v1.json")); - createArtifact(registryClient, ArtifactType.JSON, ApicurioV2BaseIT.resourceToString("artifactTypes/" + "jsonSchema/person_v1.json")); - - String test1content = ApicurioV2BaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v1.proto"); - ArtifactData protoData = createArtifact(registryClient, ArtifactType.PROTOBUF, test1content); - - //verify search with canonicalize returns the expected artifact metadata - var versionMetadata = registryClient.getArtifactVersionMetaDataByContent(null, protoData.meta.getId(), true, null, IoUtil.toStream(test1content)); - assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); - - assertEquals(3, registryClient.listArtifactsInGroup(null).getCount()); - - // - - facade.stopProcess(logsPath, oldRegistryName); - - facade.runRegistry(appEnv, "registry-dblatest", "8081"); - facade.waitForRegistryReady(); - - // - - var searchResults = registryClient.listArtifactsInGroup(null); - assertEquals(3, searchResults.getCount()); - - var protobufs = searchResults.getArtifacts().stream() - .filter(ar -> ar.getType().equals(ArtifactType.PROTOBUF)) - .collect(Collectors.toList()); - - System.out.println("Protobuf artifacts are " + protobufs.size()); - assertEquals(1, protobufs.size()); - var protoMetadata = registryClient.getArtifactMetaData(protobufs.get(0).getGroupId(), protobufs.get(0).getId()); - var content = registryClient.getContentByGlobalId(protoMetadata.getGlobalId()); - - //search with canonicalize - versionMetadata = registryClient.getArtifactVersionMetaDataByContent(protobufs.get(0).getGroupId(), protobufs.get(0).getId(), true, null, content); - assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); - - //search with canonicalize - versionMetadata = registryClient.getArtifactVersionMetaDataByContent(protobufs.get(0).getGroupId(), protobufs.get(0).getId(), true, null, IoUtil.toStream(test1content)); - assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); - - //search without canonicalize - versionMetadata = registryClient.getArtifactVersionMetaDataByContent(protobufs.get(0).getGroupId(), protobufs.get(0).getId(), false, null, IoUtil.toStream(test1content)); - assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); - - //create one more protobuf artifact and verify - String test2content = ApicurioV2BaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v2.proto"); - protoData = createArtifact(registryClient, ArtifactType.PROTOBUF, test2content); - versionMetadata = registryClient.getArtifactVersionMetaDataByContent(null, protoData.meta.getId(), true, null, IoUtil.toStream(test2content)); - assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); - - //assert total num of artifacts - assertEquals(4, registryClient.listArtifactsInGroup(null).getCount()); - - - } finally { - try { - facade.stopAndCollectLogs(logsPath); - } finally { - RegistryUtils.REGISTRY_STORAGE = previousStorageValue; - } - } - - } - - @Test - public void testStorageUpgradeReferencesContentHash() throws Exception { - testStorageUpgradeReferencesContentHashUpgrader("referencesContentHash", RegistryStorageType.kafkasql); - } - - public void testStorageUpgradeReferencesContentHashUpgrader(String testName, RegistryStorageType storage) throws Exception { - - RegistryStorageType previousStorageValue = RegistryUtils.REGISTRY_STORAGE; - RegistryUtils.REGISTRY_STORAGE = storage; - - Path logsPath = RegistryUtils.getLogsPath(getClass(), testName); - RegistryFacade facade = RegistryFacade.getInstance(); - - try { - - Map appEnv = facade.initRegistryAppEnv(); - - //runs all required infra except for the registry - facade.deployStorage(appEnv, storage); - - appEnv.put("QUARKUS_HTTP_PORT", "8081"); - - String oldRegistryName = "registry-dbv4"; - String image = "quay.io/apicurio/apicurio-registry-kafkasql:2.4.1.Final"; - - var container = new GenericContainer<>(new RemoteDockerImage(DockerImageName.parse(image))); - container.setNetworkMode("host"); - facade.runContainer(appEnv, oldRegistryName, container); - facade.waitForRegistryReady(); - - // - var registryClient = RegistryClientFactory.create("http://localhost:8081/"); - - - final ArtifactData artifact = createArtifact(registryClient, ArtifactType.JSON, REFERENCE_CONTENT); - - //Create a second artifact referencing the first one, the hash will be the same using version 2.4.1.Final. - var artifactReference = new ArtifactReference(); - - artifactReference.setName("testReference"); - artifactReference.setArtifactId(artifact.meta.getId()); - artifactReference.setGroupId(artifact.meta.getGroupId()); - artifactReference.setVersion(artifact.meta.getVersion()); - - var artifactReferences = List.of(artifactReference); - - String artifactId = UUID.randomUUID().toString(); - - final ArtifactData artifactWithReferences = createArtifactWithReferences(artifactId, registryClient, ArtifactType.AVRO, ARTIFACT_CONTENT, artifactReferences); - - String calculatedHash = DigestUtils.sha256Hex(ARTIFACT_CONTENT); - - //Assertions - //The artifact hash is calculated without using references - assertEquals(calculatedHash, artifactWithReferences.contentHash); - - facade.stopProcess(logsPath, oldRegistryName); - - facade.runRegistry(appEnv, "registry-dblatest", "8081"); - facade.waitForRegistryReady(); - - //Finally, if we try to create the same artifact with the same references, no new version will be created and the same ids are used. - ArtifactData upgradedArtifact = createArtifactWithReferences(artifactId, registryClient, ArtifactType.AVRO, ARTIFACT_CONTENT, artifactReferences); - assertEquals(artifactWithReferences.meta.getGlobalId(), upgradedArtifact.meta.getGlobalId()); - assertEquals(artifactWithReferences.meta.getContentId(), upgradedArtifact.meta.getContentId()); - - - } finally { - try { - facade.stopAndCollectLogs(logsPath); - } finally { - RegistryUtils.REGISTRY_STORAGE = previousStorageValue; - } - } - - } - -} diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/dbupgrade/SqlStorageUpgradeIT.java b/integration-tests/testsuite/src/test/java/io/apicurio/tests/dbupgrade/SqlStorageUpgradeIT.java deleted file mode 100644 index 9cf8ca2428..0000000000 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/dbupgrade/SqlStorageUpgradeIT.java +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests.dbupgrade; - -import com.fasterxml.jackson.databind.ObjectMapper; -import io.apicurio.registry.rest.client.RegistryClient; -import io.apicurio.registry.rest.client.RegistryClientFactory; -import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; -import io.apicurio.registry.rest.v2.beans.ArtifactReference; -import io.apicurio.registry.rest.v2.beans.Rule; -import io.apicurio.registry.rest.v2.beans.VersionMetaData; -import io.apicurio.registry.types.ArtifactType; -import io.apicurio.registry.types.RuleType; -import io.apicurio.registry.utils.IoUtil; -import io.apicurio.registry.utils.tests.SimpleDisplayName; -import io.apicurio.tests.ApicurioV2BaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.RegistryFacade; -import io.apicurio.tests.common.RegistryStorageType; -import io.apicurio.tests.common.interfaces.TestSeparator; -import io.apicurio.tests.common.utils.RegistryUtils; -import io.apicurio.tests.multitenancy.MultitenancySupport; -import io.apicurio.tests.multitenancy.TenantUserClient; -import io.apicurio.tests.utils.CustomTestsUtils.ArtifactData; -import org.apache.commons.codec.digest.DigestUtils; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.api.TestInstance.Lifecycle; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.images.RemoteDockerImage; -import org.testcontainers.utility.DockerImageName; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.stream.Collectors; - -import static io.apicurio.tests.utils.CustomTestsUtils.createArtifact; -import static io.apicurio.tests.utils.CustomTestsUtils.createArtifactWithReferences; -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Note this test does not extend any base class - * - * @author Fabian Martinez - */ -@DisplayNameGeneration(SimpleDisplayName.class) -@TestInstance(Lifecycle.PER_CLASS) -@Tag(Constants.DB_UPGRADE) -@Tag(Constants.SQL) -public class SqlStorageUpgradeIT implements TestSeparator, Constants { - - private static final String ARTIFACT_CONTENT = "{\"name\":\"redhat\"}"; - private static final String REFERENCE_CONTENT = "{\"name\":\"ibm\"}"; - - private static final ObjectMapper mapper = new ObjectMapper(); - - @Test - public void testStorageUpgrade() throws Exception { - - Path logsPath = RegistryUtils.getLogsPath(getClass(), "testStorageUpgrade"); - RegistryFacade facade = RegistryFacade.getInstance(); - - try { - - Map appEnv = facade.initRegistryAppEnv(); - - //runs all required infra except for the registry - facade.runMultitenancyInfra(appEnv); - - appEnv.put("QUARKUS_HTTP_PORT", "8081"); - - String oldRegistryName = "registry-sql-dbv2"; - var container = new GenericContainer<>(new RemoteDockerImage(DockerImageName.parse("quay.io/apicurio/apicurio-registry-sql:2.1.0.Final"))); - container.setNetworkMode("host"); - facade.runContainer(appEnv, oldRegistryName, container); - facade.waitForRegistryReady(); - - MultitenancySupport mt = new MultitenancySupport(); - - List data = loadData(mt); - - verifyData(data); - - facade.stopProcess(logsPath, oldRegistryName); - - facade.runRegistry(appEnv, "sql-dblatest", "8081"); - facade.waitForRegistryReady(); - - verifyData(data); - - createMoreArtifacts(data); - - verifyData(data); - - } finally { - facade.stopAndCollectLogs(logsPath); - } - - } - - @Test - public void testStorageUpgradeProtobufUpgraderSql() throws Exception { - testStorageUpgradeProtobufUpgrader("protobufCanonicalHashSql", RegistryStorageType.sql); - } - - public void testStorageUpgradeProtobufUpgrader(String testName, RegistryStorageType storage) throws Exception { - - RegistryStorageType previousStorageValue = RegistryUtils.REGISTRY_STORAGE; - RegistryUtils.REGISTRY_STORAGE = storage; - - Path logsPath = RegistryUtils.getLogsPath(getClass(), testName); - RegistryFacade facade = RegistryFacade.getInstance(); - - try { - - Map appEnv = facade.initRegistryAppEnv(); - - //runs all required infra except for the registry - facade.deployStorage(appEnv, storage); - - appEnv.put("QUARKUS_HTTP_PORT", "8081"); - - String oldRegistryName = "registry-dbv4"; - String image = "quay.io/apicurio/apicurio-registry-sql:2.1.2.Final"; - if (storage == RegistryStorageType.kafkasql) { - image = "quay.io/apicurio/apicurio-registry-kafkasql:2.1.2.Final"; - } - var container = new GenericContainer<>(new RemoteDockerImage(DockerImageName.parse(image))); - container.setNetworkMode("host"); - facade.runContainer(appEnv, oldRegistryName, container); - facade.waitForRegistryReady(); - - // - - var registryClient = RegistryClientFactory.create("http://localhost:8081/"); - - createArtifact(registryClient, ArtifactType.AVRO, ApicurioV2BaseIT.resourceToString("artifactTypes/" + "avro/multi-field_v1.json")); - createArtifact(registryClient, ArtifactType.JSON, ApicurioV2BaseIT.resourceToString("artifactTypes/" + "jsonSchema/person_v1.json")); - - String test1content = ApicurioV2BaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v1.proto"); - ArtifactData protoData = createArtifact(registryClient, ArtifactType.PROTOBUF, test1content); - - //verify search with canonicalize returns the expected artifact metadata - var versionMetadata = registryClient.getArtifactVersionMetaDataByContent(null, protoData.meta.getId(), true, null, IoUtil.toStream(test1content)); - assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); - - assertEquals(3, registryClient.listArtifactsInGroup(null).getCount()); - - // - - facade.stopProcess(logsPath, oldRegistryName); - - facade.runRegistry(appEnv, "registry-dblatest", "8081"); - facade.waitForRegistryReady(); - - // - - var searchResults = registryClient.listArtifactsInGroup(null); - assertEquals(3, searchResults.getCount()); - - var protobufs = searchResults.getArtifacts().stream() - .filter(ar -> ar.getType().equals(ArtifactType.PROTOBUF)) - .collect(Collectors.toList()); - - assertEquals(1, protobufs.size()); - var protoMetadata = registryClient.getArtifactMetaData(protobufs.get(0).getGroupId(), protobufs.get(0).getId()); - var content = registryClient.getContentByGlobalId(protoMetadata.getGlobalId()); - - //search with canonicalize - versionMetadata = registryClient.getArtifactVersionMetaDataByContent(protobufs.get(0).getGroupId(), protobufs.get(0).getId(), true, null, content); - assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); - - //search with canonicalize - versionMetadata = registryClient.getArtifactVersionMetaDataByContent(protobufs.get(0).getGroupId(), protobufs.get(0).getId(), true, null, IoUtil.toStream(test1content)); - assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); - - //search without canonicalize - versionMetadata = registryClient.getArtifactVersionMetaDataByContent(protobufs.get(0).getGroupId(), protobufs.get(0).getId(), false, null, IoUtil.toStream(test1content)); - assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); - - //create one more protobuf artifact and verify - String test2content = ApicurioV2BaseIT.resourceToString("artifactTypes/" + "protobuf/tutorial_v2.proto"); - protoData = createArtifact(registryClient, ArtifactType.PROTOBUF, test2content); - versionMetadata = registryClient.getArtifactVersionMetaDataByContent(null, protoData.meta.getId(), true, null, IoUtil.toStream(test2content)); - assertEquals(protoData.meta.getContentId(), versionMetadata.getContentId()); - - //assert total num of artifacts - assertEquals(4, registryClient.listArtifactsInGroup(null).getCount()); - - - } finally { - try { - facade.stopAndCollectLogs(logsPath); - } finally { - RegistryUtils.REGISTRY_STORAGE = previousStorageValue; - } - } - - } - - @Test - public void testStorageUpgradeReferencesContentHash() throws Exception { - testStorageUpgradeReferencesContentHashUpgrader("referencesContentHash", RegistryStorageType.sql); - } - - public void testStorageUpgradeReferencesContentHashUpgrader(String testName, RegistryStorageType storage) throws Exception { - - RegistryStorageType previousStorageValue = RegistryUtils.REGISTRY_STORAGE; - RegistryUtils.REGISTRY_STORAGE = storage; - - Path logsPath = RegistryUtils.getLogsPath(getClass(), testName); - RegistryFacade facade = RegistryFacade.getInstance(); - - try { - - Map appEnv = facade.initRegistryAppEnv(); - - //runs all required infra except for the registry - facade.deployStorage(appEnv, storage); - - appEnv.put("QUARKUS_HTTP_PORT", "8081"); - - String oldRegistryName = "registry-dbv4"; - String image = "quay.io/apicurio/apicurio-registry-sql:2.4.1.Final"; - if (storage == RegistryStorageType.kafkasql) { - image = "quay.io/apicurio/apicurio-registry-kafkasql:2.4.1.Final"; - } - var container = new GenericContainer<>(new RemoteDockerImage(DockerImageName.parse(image))); - container.setNetworkMode("host"); - facade.runContainer(appEnv, oldRegistryName, container); - facade.waitForRegistryReady(); - - // - var registryClient = RegistryClientFactory.create("http://localhost:8081/"); - - - final ArtifactData artifact = createArtifact(registryClient, ArtifactType.JSON, REFERENCE_CONTENT); - - //Create a second artifact referencing the first one, the hash will be the same using version 2.4.1.Final. - var artifactReference = new ArtifactReference(); - - artifactReference.setName("testReference"); - artifactReference.setArtifactId(artifact.meta.getId()); - artifactReference.setGroupId(artifact.meta.getGroupId()); - artifactReference.setVersion(artifact.meta.getVersion()); - - var artifactReferences = List.of(artifactReference); - - String artifactId = UUID.randomUUID().toString(); - - final ArtifactData artifactWithReferences = createArtifactWithReferences(artifactId, registryClient, ArtifactType.AVRO, ARTIFACT_CONTENT, artifactReferences); - - String calculatedHash = DigestUtils.sha256Hex(ARTIFACT_CONTENT); - - //Assertions - //The artifact hash is calculated without using references - assertEquals(calculatedHash, artifactWithReferences.contentHash); - - facade.stopProcess(logsPath, oldRegistryName); - - facade.runRegistry(appEnv, "registry-dblatest", "8081"); - facade.waitForRegistryReady(); - - //Finally, if we try to create the same artifact with the same references, no new version will be created and the same ids are used. - ArtifactData upgradedArtifact = createArtifactWithReferences(artifactId, registryClient, ArtifactType.AVRO, ARTIFACT_CONTENT, artifactReferences); - assertEquals(artifactWithReferences.meta.getGlobalId(), upgradedArtifact.meta.getGlobalId()); - assertEquals(artifactWithReferences.meta.getContentId(), upgradedArtifact.meta.getContentId()); - - } finally { - try { - facade.stopAndCollectLogs(logsPath); - } finally { - RegistryUtils.REGISTRY_STORAGE = previousStorageValue; - } - } - - } - - - private List loadData(MultitenancySupport mt) throws Exception { - - List tenants = new ArrayList<>(); - - for (int i = 0; i < 50; i++) { - - TenantData tenant = new TenantData(); - TenantUserClient user = mt.createTenant(); - tenant.tenant = user; - tenants.add(tenant); - - RegistryClient client = user.client; - - Rule comp = new Rule(); - comp.setType(RuleType.COMPATIBILITY); - comp.setConfig("BACKWARD"); - client.createGlobalRule(comp); - Rule val = new Rule(); - val.setType(RuleType.VALIDITY); - val.setConfig("SYNTAX_ONLY"); - client.createGlobalRule(val); - - tenant.artifacts.add(createArtifact(client, ArtifactType.AVRO, ApicurioV2BaseIT.resourceToString("artifactTypes/" + "avro/multi-field_v1.json"))); - tenant.artifacts.add(createArtifact(client, ArtifactType.JSON, ApicurioV2BaseIT.resourceToString("artifactTypes/" + "jsonSchema/person_v1.json"))); - tenant.artifacts.add(createArtifact(client, ArtifactType.ASYNCAPI, ApicurioV2BaseIT.resourceToString("artifactTypes/" + "asyncapi/2.0-streetlights_v1.json"))); - - } - return tenants; - } - - private void createMoreArtifacts(List tenants) throws Exception { - for (TenantData tenant : tenants) { - var client = tenant.tenant.client; - - tenant.artifacts.add(createArtifact(client, ArtifactType.AVRO, ApicurioV2BaseIT.resourceToString("artifactTypes/" + "avro/multi-field_v1.json"))); - tenant.artifacts.add(createArtifact(client, ArtifactType.KCONNECT, ApicurioV2BaseIT.resourceToString("artifactTypes/" + "kafkaConnect/simple_v1.json"))); - } - } - - private void verifyData(List tenants) { - for (TenantData tenant : tenants) { - - var client = tenant.tenant.client; - - var grules = client.listGlobalRules(); - assertEquals(2, grules.size()); - - for (ArtifactData data : tenant.artifacts) { - ArtifactMetaData meta = data.meta; - - String content = IoUtil.toString(client.getArtifactVersion(meta.getGroupId(), meta.getId(), meta.getVersion())); - String contentHash = DigestUtils.sha256Hex(IoUtil.toBytes(content)); - - assertEquals(data.contentHash, contentHash); - - String contentgid = IoUtil.toString(client.getContentByGlobalId(meta.getGlobalId())); - String contentgidHash = DigestUtils.sha256Hex(IoUtil.toBytes(contentgid)); - - assertEquals(data.contentHash, contentgidHash); - - String contentcid = IoUtil.toString(client.getContentById(meta.getContentId())); - String contentcidHash = DigestUtils.sha256Hex(IoUtil.toBytes(contentcid)); - - assertEquals(data.contentHash, contentcidHash); - - VersionMetaData vmeta = client.getArtifactVersionMetaData(meta.getGroupId(), meta.getId(), meta.getVersion()); - assertEquals(meta.getContentId(), vmeta.getContentId()); - - } - } - } - - private static class TenantData { - TenantUserClient tenant; - List artifacts; - - public TenantData() { - artifacts = new ArrayList<>(); - } - } -} diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/migration/DataMigrationIT.java b/integration-tests/testsuite/src/test/java/io/apicurio/tests/migration/DataMigrationIT.java deleted file mode 100644 index 3ca52dae63..0000000000 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/migration/DataMigrationIT.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests.migration; - -import static io.apicurio.registry.utils.tests.TestUtils.retry; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.zip.ZipOutputStream; - -import io.apicurio.registry.rest.v2.beans.ArtifactReference; -import io.apicurio.registry.types.ArtifactState; -import io.apicurio.registry.types.ArtifactType; -import io.apicurio.registry.utils.IoUtil; -import io.apicurio.registry.utils.impexp.ArtifactVersionEntity; -import io.apicurio.registry.utils.impexp.ContentEntity; -import io.apicurio.registry.utils.impexp.EntityWriter; -import io.apicurio.tests.common.ApicurioRegistryBaseIT; -import org.apache.commons.codec.digest.DigestUtils; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import io.apicurio.registry.rest.client.RegistryClient; -import io.apicurio.registry.rest.client.RegistryClientFactory; -import io.apicurio.registry.rest.v2.beans.Rule; -import io.apicurio.registry.types.RuleType; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.RegistryFacade; -import io.apicurio.tests.serdes.apicurio.AvroGenericRecordSchemaFactory; -import io.apicurio.tests.serdes.apicurio.JsonSchemaMsgFactory; - -/** - * @author Fabian Martinez - */ -@Tag(Constants.MIGRATION) -public class DataMigrationIT extends ApicurioRegistryBaseIT { - - private final RegistryFacade registryFacade = RegistryFacade.getInstance(); - - @Test - public void migrate() throws Exception { - RegistryClient source = RegistryClientFactory.create(registryFacade.getSourceRegistryUrl()); - - List globalIds = new ArrayList<>(); - HashMap> referencesMap = new HashMap<>(); - - JsonSchemaMsgFactory jsonSchema = new JsonSchemaMsgFactory(); - for (int idx = 0; idx < 50; idx++) { - String artifactId = idx + "-" + UUID.randomUUID().toString(); - var amd = source.createArtifact("default", artifactId, jsonSchema.getSchemaStream()); - retry(() -> source.getContentByGlobalId(amd.getGlobalId())); - globalIds.add(amd.getGlobalId()); - } - - for (int idx = 0; idx < 15; idx++) { - AvroGenericRecordSchemaFactory avroSchema = new AvroGenericRecordSchemaFactory(List.of("a" + idx)); - String artifactId = "avro-" + idx; - List references = idx > 0 ? getSingletonRefList("avro-schemas", "avro-" + (idx - 1), "1", "myRef" + idx) : Collections.emptyList(); - var amd = source.createArtifact("avro-schemas", artifactId, avroSchema.generateSchemaStream(), references); - retry(() -> source.getContentByGlobalId(amd.getGlobalId())); - assertTrue(matchesReferences(references, source.getArtifactReferencesByGlobalId(amd.getGlobalId()))); - referencesMap.put(amd.getGlobalId(), references); - globalIds.add(amd.getGlobalId()); - - avroSchema = new AvroGenericRecordSchemaFactory(List.of("u" + idx)); - List updatedReferences = idx > 0 ? getSingletonRefList("avro-schemas", "avro-" + (idx - 1), "2", "myRef" + idx) : Collections.emptyList(); - var vmd = source.updateArtifact("avro-schemas", artifactId, null, null, null, avroSchema.generateSchemaStream(), updatedReferences); - retry(() -> source.getContentByGlobalId(vmd.getGlobalId())); - assertTrue(matchesReferences(updatedReferences, source.getArtifactReferencesByGlobalId(vmd.getGlobalId()))); - referencesMap.put(vmd.getGlobalId(), updatedReferences); - globalIds.add(vmd.getGlobalId()); - } - - Rule rule = new Rule(); - rule.setType(RuleType.VALIDITY); - rule.setConfig("SYNTAX_ONLY"); - source.createArtifactRule("avro-schemas", "avro-0", rule); - - rule = new Rule(); - rule.setType(RuleType.COMPATIBILITY); - rule.setConfig("BACKWARD"); - source.createGlobalRule(rule); - - RegistryClient dest = RegistryClientFactory.create(registryFacade.getDestRegistryUrl()); - - dest.importData(source.exportData()); - - retry(() -> { - for (long gid : globalIds) { - dest.getContentByGlobalId(gid); - if (referencesMap.containsKey(gid)) { - List srcReferences = referencesMap.get(gid); - List destReferences = dest.getArtifactReferencesByGlobalId(gid); - assertTrue(matchesReferences(srcReferences, destReferences)); - } - } - assertEquals("SYNTAX_ONLY", dest.getArtifactRuleConfig("avro-schemas", "avro-0", RuleType.VALIDITY).getConfig()); - assertEquals("BACKWARD", dest.getGlobalRuleConfig(RuleType.COMPATIBILITY).getConfig()); - }); - } - - @Test - public void testDoNotPreserveIdsImport() throws Exception { - RegistryClient source = RegistryClientFactory.create(registryFacade.getSourceRegistryUrl()); - RegistryClient dest = RegistryClientFactory.create(registryFacade.getDestRegistryUrl()); - - Map artifacts = new HashMap<>(); - - // Fill the source registry with data - JsonSchemaMsgFactory jsonSchema = new JsonSchemaMsgFactory(); - for (int idx = 0; idx < 50; idx++) { - String artifactId = idx + "-" + UUID.randomUUID().toString(); - String content = IoUtil.toString(jsonSchema.getSchemaStream()); - var amd = source.createArtifact("default", artifactId, IoUtil.toStream(content)); - retry(() -> source.getContentByGlobalId(amd.getGlobalId())); - artifacts.put("default:" + artifactId, content); - } - - for (int idx = 0; idx < 15; idx++) { - AvroGenericRecordSchemaFactory avroSchema = new AvroGenericRecordSchemaFactory(List.of("a" + idx)); - String artifactId = "avro-" + idx + "-" + UUID.randomUUID().toString(); - String content = IoUtil.toString(avroSchema.generateSchemaStream()); - var amd = source.createArtifact("avro-schemas", artifactId, IoUtil.toStream(content)); - retry(() -> source.getContentByGlobalId(amd.getGlobalId())); - artifacts.put("avro-schemas:" + artifactId, content); - - avroSchema = new AvroGenericRecordSchemaFactory(List.of("u" + idx)); - String content2 = IoUtil.toString(avroSchema.generateSchemaStream()); - var vmd = source.updateArtifact("avro-schemas", artifactId, IoUtil.toStream(content2)); - retry(() -> source.getContentByGlobalId(vmd.getGlobalId())); - artifacts.put("avro-schemas:" + artifactId, content2); - } - - // Fill the destination registry with data (Avro content is inserted first to ensure that the content IDs are different) - for (int idx = 0; idx < 15; idx++) { - AvroGenericRecordSchemaFactory avroSchema = new AvroGenericRecordSchemaFactory(List.of("a" + idx)); - String artifactId = "avro-" + idx + "-" + UUID.randomUUID().toString(); // Artifact ids need to be different we do not support identical artifact ids - String content = IoUtil.toString(avroSchema.generateSchemaStream()); - var amd = dest.createArtifact("avro-schemas", artifactId, IoUtil.toStream(content)); - retry(() -> dest.getContentByGlobalId(amd.getGlobalId())); - artifacts.put("avro-schemas:" + artifactId, content); - } - - for (int idx = 0; idx < 50; idx++) { - String artifactId = idx + "-" + UUID.randomUUID().toString(); // Artifact ids need to be different we do not support identical artifact ids - String content = IoUtil.toString(jsonSchema.getSchemaStream()); - var amd = dest.createArtifact("default", artifactId, IoUtil.toStream(content)); - retry(() -> dest.getContentByGlobalId(amd.getGlobalId())); - artifacts.put("default:" + artifactId, content); - } - - // Import the data - InputStream data = source.exportData(); - - - dest.importData(data, false, false); - - // Check that the import was successful - retry(() -> { - for (var entry : artifacts.entrySet()) { - String groupId = entry.getKey().split(":")[0]; - String artifactId = entry.getKey().split(":")[1]; - String content = entry.getValue(); - var registryContent = dest.getLatestArtifact(groupId, artifactId); - assertNotNull(registryContent); - assertEquals(content, IoUtil.toString(registryContent)); - } - }); - } - - @Test - public void testGeneratingCanonicalHashOnImport() throws Exception { - RegistryClient dest = RegistryClientFactory.create(registryFacade.getDestRegistryUrl()); - - Map artifacts = new HashMap<>(); - - JsonSchemaMsgFactory jsonSchema = new JsonSchemaMsgFactory(); - for(int i = 0; i < 20; i++) { - String artifactId = i + "-" + UUID.randomUUID(); - String content = IoUtil.toString(jsonSchema.getSchemaStream()); - artifacts.put(artifactId, content); - } - dest.importData(generateExportedZip(artifacts), false, false); - - retry(() -> { - for(var entry : artifacts.entrySet()) { - String groupId = "default"; - String artifactId = entry.getKey(); - String content = entry.getValue(); - - /* - TODO: Check if the canonical hash is generated correctly. - The only way is to generate canonical hash and then search artifact by it. But that needs apicurio-registry-app module as dependency. - */ - - var registryContent = dest.getLatestArtifact(groupId, artifactId); - assertNotNull(registryContent); - assertEquals(content, IoUtil.toString(registryContent)); - } - }); - - } - - @AfterEach - public void tearDownRegistries() throws IOException { - registryFacade.stopAndCollectLogs(null); - } - - public InputStream generateExportedZip(Map artifacts) { - try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { - ZipOutputStream zip = new ZipOutputStream(outputStream, StandardCharsets.UTF_8); - EntityWriter writer = new EntityWriter(zip); - - Map contentIndex = new HashMap<>(); - - AtomicInteger globalIdSeq = new AtomicInteger(1); - AtomicInteger contentIdSeq = new AtomicInteger(1); - - for (var entry : artifacts.entrySet()) { - String artifactId = entry.getKey(); - String content = entry.getValue(); - byte[] contentBytes = IoUtil.toBytes(content); - String contentHash = DigestUtils.sha256Hex(contentBytes); - - String artifactType = ArtifactType.JSON; - - Long contentId = contentIndex.computeIfAbsent(contentHash, k -> { - ContentEntity contentEntity = new ContentEntity(); - contentEntity.contentId = contentIdSeq.getAndIncrement(); - contentEntity.contentHash = contentHash; - contentEntity.canonicalHash = null; - contentEntity.contentBytes = contentBytes; - contentEntity.artifactType = artifactType; - - try { - writer.writeEntity(contentEntity); - } catch (IOException e) { - throw new RuntimeException(e); - } - - return contentEntity.contentId; - }); - - ArtifactVersionEntity versionEntity = new ArtifactVersionEntity(); - versionEntity.artifactId = artifactId; - versionEntity.artifactType = artifactType; - versionEntity.contentId = contentId; - versionEntity.createdBy = "integration-tests"; - versionEntity.createdOn = System.currentTimeMillis(); - versionEntity.description = null; - versionEntity.globalId = globalIdSeq.getAndIncrement(); - versionEntity.groupId = null; - versionEntity.isLatest = true; - versionEntity.labels = null; - versionEntity.name = null; - versionEntity.properties = null; - versionEntity.state = ArtifactState.ENABLED; - versionEntity.version = "1"; - versionEntity.versionId = 1; - - writer.writeEntity(versionEntity); - } - - zip.flush(); - zip.close(); - - return new ByteArrayInputStream(outputStream.toByteArray()); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - - private List getSingletonRefList(String groupId, String artifactId, String version, String name) { - ArtifactReference artifactReference = new ArtifactReference(); - artifactReference.setGroupId(groupId); - artifactReference.setArtifactId(artifactId); - artifactReference.setVersion(version); - artifactReference.setName(name); - return Collections.singletonList(artifactReference); - } - - private boolean matchesReferences(List srcReferences, List destReferences) { - return destReferences.size() == srcReferences.size() && destReferences.stream().allMatch( - srcRef -> srcReferences.stream().anyMatch(destRef -> - Objects.equals(srcRef.getGroupId(), destRef.getGroupId()) && - Objects.equals(srcRef.getArtifactId(), destRef.getArtifactId()) && - Objects.equals(srcRef.getVersion(), destRef.getVersion()) && - Objects.equals(srcRef.getName(), destRef.getName())) - ); - } - -} diff --git a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/MultitenantAuthIT.java b/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/MultitenantAuthIT.java deleted file mode 100644 index f8388b632f..0000000000 --- a/integration-tests/testsuite/src/test/java/io/apicurio/tests/multitenancy/MultitenantAuthIT.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright 2021 Red Hat - * - * Licensed 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 io.apicurio.tests.multitenancy; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.ByteArrayInputStream; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import io.apicurio.rest.client.auth.exception.ForbiddenException; -import io.apicurio.rest.client.auth.exception.NotAuthorizedException; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.apicurio.registry.rest.client.RegistryClient; -import io.apicurio.registry.rest.client.RegistryClientFactory; -import io.apicurio.registry.rest.client.exception.ArtifactNotFoundException; -import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; -import io.apicurio.registry.rest.v2.beans.RoleMapping; -import io.apicurio.registry.rest.v2.beans.Rule; -import io.apicurio.registry.rest.v2.beans.SearchedArtifact; -import io.apicurio.registry.types.ArtifactType; -import io.apicurio.registry.types.RoleType; -import io.apicurio.registry.types.RuleType; -import io.apicurio.registry.utils.tests.TestUtils; -import io.apicurio.rest.client.auth.Auth; -import io.apicurio.tests.common.ApicurioRegistryBaseIT; -import io.apicurio.tests.common.Constants; -import io.apicurio.tests.common.auth.CustomJWTAuth; -import io.smallrye.jwt.build.Jwt; - - -/** - * @author Fabian Martinez - */ -@Tag(Constants.MULTITENANCY) -public class MultitenantAuthIT extends ApicurioRegistryBaseIT { - - private static final Logger LOGGER = LoggerFactory.getLogger(MultitenantAuthIT.class); - - @Test - public void testSecuredMultitenantRegistry() throws Exception { - - MultitenancySupport mt = new MultitenancySupport(); - - RegistryClient clientTenant1 = mt.createTenant().client; - - RegistryClient clientTenant2 = mt.createTenant().client; - - try { - performTenantAdminOperations(clientTenant1); - try { - performTenantAdminOperations(clientTenant2); - } finally { - cleanTenantArtifacts(clientTenant2); - } - } finally { - cleanTenantArtifacts(clientTenant1); - } - } - - /** - * Tests two users in the same organization accessing the same tenant - */ - @Test - public void testPermissions() throws Exception { - MultitenancySupport mt = new MultitenancySupport(); - - String tenantId = UUID.randomUUID().toString(); - var user1 = new TenantUser(tenantId, "eric", "cool-org", UUID.randomUUID().toString()); - var user2 = new TenantUser(tenantId, "carles", "cool-org", UUID.randomUUID().toString()); - - //user1 is the owner of the tenant - TenantUserClient tenantOwner = mt.createTenant(user1); - - RegistryClient user2Client = mt.createUserClientCustomJWT(user2, tenantOwner.tenantAppUrl); - - try { - //user1 can access and automatically have admin permissions - performTenantAdminOperations(tenantOwner.client); - - //user2 does not have access - Assertions.assertThrows(ForbiddenException.class, () -> user2Client.listArtifactsInGroup(null)); - RoleMapping fooMapping = new RoleMapping(); - fooMapping.setPrincipalId("foo"); - fooMapping.setRole(RoleType.ADMIN); - Assertions.assertThrows(ForbiddenException.class, () -> user2Client.createRoleMapping(fooMapping)); - Assertions.assertThrows(ForbiddenException.class, () -> user2Client.updateRoleMapping(user1.principalId, RoleType.READ_ONLY)); - - //add read only permissions to user2 - RoleMapping mapping = new RoleMapping(); - mapping.setPrincipalId(user2.principalId); - mapping.setRole(RoleType.READ_ONLY); - tenantOwner.client.createRoleMapping(mapping); - - //verify read only permissions - Assertions.assertThrows(ForbiddenException.class, () -> user2Client.createRoleMapping(mapping)); - Assertions.assertThrows(ForbiddenException.class, () -> user2Client.updateRoleMapping(user2.principalId, RoleType.ADMIN)); - performTenantReadOnlyOperations(user2Client, tenantOwner.client); - - //add developer role to user2 - tenantOwner.client.updateRoleMapping(user2.principalId, RoleType.DEVELOPER); - - //verify developer role permissions - Assertions.assertThrows(ForbiddenException.class, () -> user2Client.createRoleMapping(mapping)); - Assertions.assertThrows(ForbiddenException.class, () -> user2Client.updateRoleMapping(user2.principalId, RoleType.ADMIN)); - performTenantDevRoleOperations(user2Client); - - //add admin role to user2 - tenantOwner.client.updateRoleMapping(user2.principalId, RoleType.ADMIN); - - //verify admin role permissions - user2Client.createRoleMapping(fooMapping); - user2Client.updateRoleMapping(fooMapping.getPrincipalId(), RoleType.ADMIN); - performTenantAdminOperations(user2Client); - - } finally { - cleanTenantArtifacts(tenantOwner.client); - } - } - - /** - * Tests two users, each one in it's own organization, users should be able to access only tenants in it's own organization - * @throws Exception - */ - @Test - public void testTenantAccess() throws Exception { - - MultitenancySupport mt = new MultitenancySupport(); - - var user1 = new TenantUser(UUID.randomUUID().toString(), "eric", "org1", UUID.randomUUID().toString()); - TenantUserClient tenant1User1Client = mt.createTenant(user1); - tenant1User1Client.client.listArtifactsInGroup(null); - - var user2 = new TenantUser(UUID.randomUUID().toString(), "carles", "org2", UUID.randomUUID().toString()); - TenantUserClient tenant2User2Client = mt.createTenant(user2); - tenant2User2Client.client.listArtifactsInGroup(null); - - //user2 cannot access user1 tenant, and viceversa - Assertions.assertThrows(ForbiddenException.class, () -> mt.createUserClient(user2, tenant1User1Client.tenantAppUrl).listArtifactsInGroup(null)); - Assertions.assertThrows(ForbiddenException.class, () -> mt.createUserClient(user1, tenant2User2Client.tenantAppUrl).listArtifactsInGroup(null)); - - //test invalid jwt - var invalidClient = RegistryClientFactory.create(tenant1User1Client.tenantAppUrl, Collections.emptyMap(), new Auth() { - @Override - public void apply(Map requestHeaders) { - var builder = Jwt.preferredUserName("foo") - .claim(CustomJWTAuth.RH_ORG_ID_CLAIM, "my-org"); - - String token = builder - .jws() - .keyId("247") - .sign(); - - requestHeaders.put("Authorization", "Bearer " + token); - } - }); - Assertions.assertThrows(NotAuthorizedException.class, () -> invalidClient.listArtifactsInGroup(null)); - } - - private void performTenantAdminOperations(RegistryClient client) throws Exception { - String groupId = TestUtils.generateGroupId(); - - assertTrue(client.listArtifactsInGroup(groupId).getCount().intValue() == 0); - - String artifactId = TestUtils.generateArtifactId(); - ArtifactMetaData meta = client.createArtifact(groupId, artifactId, ArtifactType.JSON, new ByteArrayInputStream("{}".getBytes())); - TestUtils.retry(() -> client.getContentByGlobalId(meta.getGlobalId())); - - assertNotNull(client.getLatestArtifact(meta.getGroupId(), meta.getId())); - - assertTrue(client.listArtifactsInGroup(groupId).getCount().intValue() == 1); - - Rule ruleConfig = new Rule(); - ruleConfig.setType(RuleType.VALIDITY); - ruleConfig.setConfig("NONE"); - client.createArtifactRule(meta.getGroupId(), meta.getId(), ruleConfig); - - client.createGlobalRule(ruleConfig); - client.deleteGlobalRule(RuleType.VALIDITY); - } - - public void performTenantReadOnlyOperations(RegistryClient readOnlyClient, RegistryClient writePermissionsClient) throws Exception { - - String groupId = TestUtils.generateGroupId(); - String artifactId = TestUtils.generateArtifactId(); - assertTrue(readOnlyClient.listArtifactsInGroup(groupId).getCount().intValue() == 0); - - Assertions.assertThrows(ArtifactNotFoundException.class, () -> readOnlyClient.getArtifactMetaData(groupId, artifactId)); - Assertions.assertThrows(ArtifactNotFoundException.class, () -> readOnlyClient.getLatestArtifact("abc", artifactId)); - Assertions.assertThrows(ForbiddenException.class, () -> { - readOnlyClient.createArtifact("ccc", artifactId, ArtifactType.JSON, new ByteArrayInputStream("{}".getBytes())); - }); - Rule ruleConfig = new Rule(); - ruleConfig.setType(RuleType.VALIDITY); - ruleConfig.setConfig("NONE"); - Assertions.assertThrows(ForbiddenException.class, () -> { - readOnlyClient.createArtifactRule(groupId, artifactId, ruleConfig); - }); - Assertions.assertThrows(ForbiddenException.class, () -> { - readOnlyClient.createGlobalRule(ruleConfig); - }); - // Users with read access are allowed to list global rules, just not edit them. - readOnlyClient.listGlobalRules(); - - ArtifactMetaData meta = writePermissionsClient.createArtifact(groupId, artifactId, ArtifactType.JSON, new ByteArrayInputStream("{}".getBytes())); - TestUtils.retry(() -> writePermissionsClient.getArtifactMetaData(groupId, meta.getId())); - - assertNotNull(readOnlyClient.getLatestArtifact(groupId, artifactId)); - } - - public void performTenantDevRoleOperations(RegistryClient client) throws Exception { - - String groupId = TestUtils.generateGroupId(); - String artifactId = TestUtils.generateArtifactId(); - try { - assertTrue(client.listArtifactsInGroup(groupId).getCount().intValue() == 0); - - client.createArtifact(groupId, artifactId, ArtifactType.JSON, new ByteArrayInputStream("{}".getBytes())); - TestUtils.retry(() -> client.getArtifactMetaData(groupId, artifactId)); - - assertNotNull(client.getLatestArtifact(groupId, artifactId)); - - Rule ruleConfig = new Rule(); - ruleConfig.setType(RuleType.VALIDITY); - ruleConfig.setConfig("NONE"); - client.createArtifactRule(groupId, artifactId, ruleConfig); - - Assertions.assertThrows(ForbiddenException.class, () -> { - client.createGlobalRule(ruleConfig); - }); - - // The client can list the global rules but not edit them. This should work. - client.listGlobalRules(); - } finally { - client.deleteArtifact(groupId, artifactId); - } - } - - private void cleanTenantArtifacts(RegistryClient client) throws Exception { - List artifacts = client.searchArtifacts(null, null, null, null, null, null, null, null, null).getArtifacts(); - for (SearchedArtifact artifact : artifacts) { - try { - client.deleteArtifact(artifact.getGroupId(), artifact.getId()); - } catch (ArtifactNotFoundException e) { - //because of async storage artifact may be already deleted but listed anyway - LOGGER.info(e.getMessage()); - } catch (Exception e) { - LOGGER.error("", e); - } - } - TestUtils.retry(() -> assertTrue(client.searchArtifacts(null, null, null, null, null, null, null, null, null).getCount().intValue() == 0)); - } - -} diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v1.json b/integration-tests/testsuite/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v1.json deleted file mode 100644 index cf694a9e3f..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v1.json +++ /dev/null @@ -1,297 +0,0 @@ -{ - "asyncapi": "2.0.0", - "info": { - "title": "Streetlights API", - "version": "1.0.0", - "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights.", - "license": { - "name": "Apache 2.0", - "url": "https://www.apache.org/licenses/LICENSE-2.0" - } - }, - "servers": { - "production": { - "url": "test.mosquitto.org:{port}", - "protocol": "mqtt", - "description": "Test broker", - "variables": { - "port": { - "description": "Secure connection (TLS) is available through port 8883.", - "default": "1883", - "enum": [ - "1883", - "8883" - ] - } - }, - "security": [ - { - "apiKey": [] - }, - { - "supportedOauthFlows": [ - "streetlights:on", - "streetlights:off", - "streetlights:dim" - ] - }, - { - "openIdConnectWellKnown": [] - } - ] - } - }, - "defaultContentType": "application/json", - "channels": { - "smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured": { - "description": "The topic on which measured values may be produced and consumed.", - "parameters": { - "streetlightId": { - "$ref": "#/components/parameters/streetlightId" - } - }, - "publish": { - "summary": "Inform about environmental lighting conditions of a particular streetlight.", - "operationId": "receiveLightMeasurement", - "traits": [ - { - "$ref": "#/components/operationTraits/kafka" - } - ], - "message": { - "$ref": "#/components/messages/lightMeasured" - } - } - }, - "smartylighting/streetlights/1/0/action/{streetlightId}/turn/on": { - "parameters": { - "streetlightId": { - "$ref": "#/components/parameters/streetlightId" - } - }, - "subscribe": { - "operationId": "turnOn", - "traits": [ - { - "$ref": "#/components/operationTraits/kafka" - } - ], - "message": { - "$ref": "#/components/messages/turnOnOff" - } - } - }, - "smartylighting/streetlights/1/0/action/{streetlightId}/turn/off": { - "parameters": { - "streetlightId": { - "$ref": "#/components/parameters/streetlightId" - } - }, - "subscribe": { - "operationId": "turnOff", - "traits": [ - { - "$ref": "#/components/operationTraits/kafka" - } - ], - "message": { - "$ref": "#/components/messages/turnOnOff" - } - } - }, - "smartylighting/streetlights/1/0/action/{streetlightId}/dim": { - "parameters": { - "streetlightId": { - "$ref": "#/components/parameters/streetlightId" - } - }, - "subscribe": { - "operationId": "dimLight", - "traits": [ - { - "$ref": "#/components/operationTraits/kafka" - } - ], - "message": { - "$ref": "#/components/messages/dimLight" - } - } - } - }, - "components": { - "messages": { - "lightMeasured": { - "name": "lightMeasured", - "title": "Light measured", - "summary": "Inform about environmental lighting conditions of a particular streetlight.", - "contentType": "application/json", - "traits": [ - { - "$ref": "#/components/messageTraits/commonHeaders" - } - ], - "payload": { - "$ref": "#/components/schemas/lightMeasuredPayload" - } - }, - "turnOnOff": { - "name": "turnOnOff", - "title": "Turn on/off", - "summary": "Command a particular streetlight to turn the lights on or off.", - "traits": [ - { - "$ref": "#/components/messageTraits/commonHeaders" - } - ], - "payload": { - "$ref": "#/components/schemas/turnOnOffPayload" - } - }, - "dimLight": { - "name": "dimLight", - "title": "Dim light", - "summary": "Command a particular streetlight to dim the lights.", - "traits": [ - { - "$ref": "#/components/messageTraits/commonHeaders" - } - ], - "payload": { - "$ref": "#/components/schemas/dimLightPayload" - } - } - }, - "schemas": { - "lightMeasuredPayload": { - "type": "object", - "properties": { - "lumens": { - "type": "integer", - "minimum": 0, - "description": "Light intensity measured in lumens." - }, - "sentAt": { - "$ref": "#/components/schemas/sentAt" - } - } - }, - "turnOnOffPayload": { - "type": "object", - "properties": { - "command": { - "type": "string", - "enum": [ - true, - false - ], - "description": "Whether to turn on or off the light." - }, - "sentAt": { - "$ref": "#/components/schemas/sentAt" - } - } - }, - "dimLightPayload": { - "type": "object", - "properties": { - "percentage": { - "type": "integer", - "description": "Percentage to which the light should be dimmed to.", - "minimum": 0, - "maximum": 100 - }, - "sentAt": { - "$ref": "#/components/schemas/sentAt" - } - } - }, - "sentAt": { - "type": "string", - "format": "date-time", - "description": "Date and time when the message was sent." - } - }, - "securitySchemes": { - "apiKey": { - "type": "apiKey", - "in": "user", - "description": "Provide your API key as the user and leave the password empty." - }, - "supportedOauthFlows": { - "type": "oauth2", - "description": "Flows to support OAuth 2.0", - "flows": { - "implicit": { - "authorizationUrl": "https://authserver.example/auth", - "scopes": { - "streetlights:on": "Ability to switch lights on", - "streetlights:off": "Ability to switch lights off", - "streetlights:dim": "Ability to dim the lights" - } - }, - "password": { - "tokenUrl": "https://authserver.example/token", - "scopes": { - "streetlights:on": "Ability to switch lights on", - "streetlights:off": "Ability to switch lights off", - "streetlights:dim": "Ability to dim the lights" - } - }, - "clientCredentials": { - "tokenUrl": "https://authserver.example/token", - "scopes": { - "streetlights:on": "Ability to switch lights on", - "streetlights:off": "Ability to switch lights off", - "streetlights:dim": "Ability to dim the lights" - } - }, - "authorizationCode": { - "authorizationUrl": "https://authserver.example/auth", - "tokenUrl": "https://authserver.example/token", - "refreshUrl": "https://authserver.example/refresh", - "scopes": { - "streetlights:on": "Ability to switch lights on", - "streetlights:off": "Ability to switch lights off", - "streetlights:dim": "Ability to dim the lights" - } - } - } - }, - "openIdConnectWellKnown": { - "type": "openIdConnect", - "openIdConnectUrl": "https://authserver.example/.well-known" - } - }, - "parameters": { - "streetlightId": { - "description": "The ID of the streetlight.", - "schema": { - "type": "string" - } - } - }, - "messageTraits": { - "commonHeaders": { - "headers": { - "type": "object", - "properties": { - "my-app-header": { - "type": "integer", - "minimum": 0, - "maximum": 100 - } - } - } - } - }, - "operationTraits": { - "kafka": { - "bindings": { - "kafka": { - "clientId": "my-app-id" - } - } - } - } - } -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v2.json b/integration-tests/testsuite/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v2.json deleted file mode 100644 index 9c033a44c0..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/asyncapi/2.0-streetlights_v2.json +++ /dev/null @@ -1,301 +0,0 @@ -{ - "asyncapi": "2.0.0", - "info": { - "title": "Streetlights API", - "version": "1.0.1", - "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights.", - "license": { - "name": "Apache 2.0", - "url": "https://www.apache.org/licenses/LICENSE-2.0" - } - }, - "servers": { - "production": { - "url": "test.mosquitto.org:{port}", - "protocol": "mqtt", - "description": "Test broker", - "variables": { - "port": { - "description": "Secure connection (TLS) is available through port 8883.", - "default": "1883", - "enum": [ - "1883", - "8883" - ] - } - }, - "security": [ - { - "apiKey": [] - }, - { - "supportedOauthFlows": [ - "streetlights:on", - "streetlights:off", - "streetlights:dim" - ] - }, - { - "openIdConnectWellKnown": [] - } - ] - } - }, - "defaultContentType": "application/json", - "channels": { - "smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured": { - "description": "The topic on which measured values may be produced and consumed.", - "parameters": { - "streetlightId": { - "$ref": "#/components/parameters/streetlightId" - } - }, - "publish": { - "summary": "Inform about environmental lighting conditions of a particular streetlight.", - "operationId": "receiveLightMeasurement", - "traits": [ - { - "$ref": "#/components/operationTraits/kafka" - } - ], - "message": { - "$ref": "#/components/messages/lightMeasured" - } - } - }, - "smartylighting/streetlights/1/0/action/{streetlightId}/turn/on": { - "parameters": { - "streetlightId": { - "$ref": "#/components/parameters/streetlightId" - } - }, - "subscribe": { - "operationId": "turnOn", - "traits": [ - { - "$ref": "#/components/operationTraits/kafka" - } - ], - "message": { - "$ref": "#/components/messages/turnOnOff" - } - } - }, - "smartylighting/streetlights/1/0/action/{streetlightId}/turn/off": { - "parameters": { - "streetlightId": { - "$ref": "#/components/parameters/streetlightId" - } - }, - "subscribe": { - "operationId": "turnOff", - "traits": [ - { - "$ref": "#/components/operationTraits/kafka" - } - ], - "message": { - "$ref": "#/components/messages/turnOnOff" - } - } - }, - "smartylighting/streetlights/1/0/action/{streetlightId}/dim": { - "parameters": { - "streetlightId": { - "$ref": "#/components/parameters/streetlightId" - } - }, - "subscribe": { - "operationId": "dimLight", - "traits": [ - { - "$ref": "#/components/operationTraits/kafka" - } - ], - "message": { - "$ref": "#/components/messages/dimLight" - } - } - } - }, - "components": { - "messages": { - "lightMeasured": { - "name": "lightMeasured", - "title": "Light measured", - "summary": "Inform about environmental lighting conditions of a particular streetlight.", - "contentType": "application/json", - "traits": [ - { - "$ref": "#/components/messageTraits/commonHeaders" - } - ], - "payload": { - "$ref": "#/components/schemas/lightMeasuredPayload" - } - }, - "turnOnOff": { - "name": "turnOnOff", - "title": "Turn on/off", - "summary": "Command a particular streetlight to turn the lights on or off.", - "traits": [ - { - "$ref": "#/components/messageTraits/commonHeaders" - } - ], - "payload": { - "$ref": "#/components/schemas/turnOnOffPayload" - } - }, - "dimLight": { - "name": "dimLight", - "title": "Dim light", - "summary": "Command a particular streetlight to dim the lights.", - "traits": [ - { - "$ref": "#/components/messageTraits/commonHeaders" - } - ], - "payload": { - "$ref": "#/components/schemas/dimLightPayload" - } - } - }, - "schemas": { - "lightMeasuredPayload": { - "type": "object", - "properties": { - "lumens": { - "type": "integer", - "minimum": 0, - "description": "Light intensity measured in lumens." - }, - "sentAt": { - "$ref": "#/components/schemas/sentAt" - }, - "addedProperty": { - "type": "string", - "description": "Another property." - } - } - }, - "turnOnOffPayload": { - "type": "object", - "properties": { - "command": { - "type": "string", - "enum": [ - true, - false - ], - "description": "Whether to turn on or off the light." - }, - "sentAt": { - "$ref": "#/components/schemas/sentAt" - } - } - }, - "dimLightPayload": { - "type": "object", - "properties": { - "percentage": { - "type": "integer", - "description": "Percentage to which the light should be dimmed to.", - "minimum": 0, - "maximum": 100 - }, - "sentAt": { - "$ref": "#/components/schemas/sentAt" - } - } - }, - "sentAt": { - "type": "string", - "format": "date-time", - "description": "Date and time when the message was sent." - } - }, - "securitySchemes": { - "apiKey": { - "type": "apiKey", - "in": "user", - "description": "Provide your API key as the user and leave the password empty." - }, - "supportedOauthFlows": { - "type": "oauth2", - "description": "Flows to support OAuth 2.0", - "flows": { - "implicit": { - "authorizationUrl": "https://authserver.example/auth", - "scopes": { - "streetlights:on": "Ability to switch lights on", - "streetlights:off": "Ability to switch lights off", - "streetlights:dim": "Ability to dim the lights" - } - }, - "password": { - "tokenUrl": "https://authserver.example/token", - "scopes": { - "streetlights:on": "Ability to switch lights on", - "streetlights:off": "Ability to switch lights off", - "streetlights:dim": "Ability to dim the lights" - } - }, - "clientCredentials": { - "tokenUrl": "https://authserver.example/token", - "scopes": { - "streetlights:on": "Ability to switch lights on", - "streetlights:off": "Ability to switch lights off", - "streetlights:dim": "Ability to dim the lights" - } - }, - "authorizationCode": { - "authorizationUrl": "https://authserver.example/auth", - "tokenUrl": "https://authserver.example/token", - "refreshUrl": "https://authserver.example/refresh", - "scopes": { - "streetlights:on": "Ability to switch lights on", - "streetlights:off": "Ability to switch lights off", - "streetlights:dim": "Ability to dim the lights" - } - } - } - }, - "openIdConnectWellKnown": { - "type": "openIdConnect", - "openIdConnectUrl": "https://authserver.example/.well-known" - } - }, - "parameters": { - "streetlightId": { - "description": "The ID of the streetlight.", - "schema": { - "type": "string" - } - } - }, - "messageTraits": { - "commonHeaders": { - "headers": { - "type": "object", - "properties": { - "my-app-header": { - "type": "integer", - "minimum": 0, - "maximum": 100 - } - } - } - } - }, - "operationTraits": { - "kafka": { - "bindings": { - "kafka": { - "clientId": "my-app-id" - } - } - } - } - } -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/avro/multi-field_v1.json b/integration-tests/testsuite/src/test/resources/artifactTypes/avro/multi-field_v1.json deleted file mode 100644 index 78b0fcb18e..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/avro/multi-field_v1.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "type": "record", - "name": "userInfo", - "namespace": "my.example", - "fields": [ - { - "name": "username", - "type": "string", - "default": "NONE" - }, - { - "name": "age", - "type": "int", - "default": -1 - }, - { - "name": "phone", - "type": "string", - "default": "NONE" - }, - { - "name": "housenum", - "type": "string", - "default": "NONE" - }, - { - "name": "street", - "type": "string", - "default": "NONE" - }, - { - "name": "city", - "type": "string", - "default": "NONE" - }, - { - "name": "state_province", - "type": "string", - "default": "NONE" - }, - { - "name": "country", - "type": "string", - "default": "NONE" - }, - { - "name": "zip", - "type": "string", - "default": "NONE" - } - ] -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/avro/multi-field_v2.json b/integration-tests/testsuite/src/test/resources/artifactTypes/avro/multi-field_v2.json deleted file mode 100644 index fa5e57df74..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/avro/multi-field_v2.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "type": "record", - "name": "userInfo", - "namespace": "my.example", - "fields": [ - { - "name": "username", - "type": "string", - "default": "NONE" - }, - { - "name": "age", - "type": "int", - "default": -1 - }, - { - "name": "phone", - "type": "string", - "default": "NONE" - }, - { - "name": "housenum", - "type": "string", - "default": "NONE" - }, - { - "name": "street", - "type": "string", - "default": "NONE" - }, - { - "name": "city", - "type": "string", - "default": "NONE" - }, - { - "name": "state_province", - "type": "string", - "default": "NONE" - }, - { - "name": "country", - "type": "string", - "default": "NONE" - }, - { - "name": "zip", - "type": "string", - "default": "NONE" - }, - { - "name": "extra", - "type": "string", - "default": "NONE" - } - ] -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/graphql/swars_v1.graphql b/integration-tests/testsuite/src/test/resources/artifactTypes/graphql/swars_v1.graphql deleted file mode 100644 index 5a30f2e404..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/graphql/swars_v1.graphql +++ /dev/null @@ -1,24 +0,0 @@ -interface Character { - id: ID! - name: String! - friends: [Character] - appearsIn: [Episode]! -} - -type Human implements Character { - id: ID! - name: String! - friends: [Character] - appearsIn: [Episode]! - starships: [Starship] - totalCredits: Int -} - -type Droid implements Character { - id: ID! - name: String! - friends: [Character] - appearsIn: [Episode]! - primaryFunction: String -} - diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/graphql/swars_v2.graphql b/integration-tests/testsuite/src/test/resources/artifactTypes/graphql/swars_v2.graphql deleted file mode 100644 index a86928898f..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/graphql/swars_v2.graphql +++ /dev/null @@ -1,25 +0,0 @@ -interface Character { - id: ID! - name: String! - friends: [Character] - appearsIn: [Episode]! -} - -type Human implements Character { - id: ID! - name: String! - friends: [Character] - appearsIn: [Episode]! - starships: [Starship] - totalCredits: Int -} - -type Droid implements Character { - id: ID! - name: String! - friends: [Character] - appearsIn: [Episode]! - primaryFunction: String - model: String -} - diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/jsonSchema/person_v1.json b/integration-tests/testsuite/src/test/resources/artifactTypes/jsonSchema/person_v1.json deleted file mode 100644 index 69ec678803..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/jsonSchema/person_v1.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$id": "https://example.com/person.schema.json", - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Person", - "type": "object", - "properties": { - "firstName": { - "type": "string", - "description": "The person's first name." - }, - "lastName": { - "type": "string", - "description": "The person's last name." - }, - "age": { - "description": "Age in years which must be equal to or greater than zero.", - "type": "integer", - "minimum": 0 - } - } -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/jsonSchema/person_v2.json b/integration-tests/testsuite/src/test/resources/artifactTypes/jsonSchema/person_v2.json deleted file mode 100644 index f7347cb664..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/jsonSchema/person_v2.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$id": "https://example.com/person.schema.json", - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Person", - "type": "object", - "properties": { - "firstName": { - "type": "string", - "description": "The person's first name." - }, - "lastName": { - "type": "string", - "description": "The person's last name." - }, - "age": { - "description": "Age in years which must be equal to or greater than zero.", - "type": "integer", - "minimum": 0 - }, - "height": { - "description": "How tall the person is in centimeters", - "type": "integer", - "minimum": 1 - } - } -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/kafkaConnect/simple_v1.json b/integration-tests/testsuite/src/test/resources/artifactTypes/kafkaConnect/simple_v1.json deleted file mode 100644 index c2e7ad8057..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/kafkaConnect/simple_v1.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "struct", - "fields": [ - { - "type": "string", - "optional": false, - "field": "bar" - } - ], - "optional": false -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/kafkaConnect/simple_v2.json b/integration-tests/testsuite/src/test/resources/artifactTypes/kafkaConnect/simple_v2.json deleted file mode 100644 index e022ced0d9..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/kafkaConnect/simple_v2.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "struct", - "fields": [ - { - "type": "string", - "optional": false, - "field": "bar" - }, - { - "type": "string", - "optional": true, - "field": "foo" - } - ], - "optional": false -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/openapi/2.0-petstore_v1.json b/integration-tests/testsuite/src/test/resources/artifactTypes/openapi/2.0-petstore_v1.json deleted file mode 100644 index 55da23a033..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/openapi/2.0-petstore_v1.json +++ /dev/null @@ -1,1043 +0,0 @@ -{ - "swagger":"2.0", - "info":{ - "description":"This is a sample server Petstore server via JSON.", - "version":"1.0.0", - "title":"Swagger Petstore (JSON)", - "termsOfService":"http://helloreverb.com/terms/", - "contact":{ - "email":"apiteam@wordnik.com" - }, - "license":{ - "name":"Apache 2.0", - "url":"http://www.apache.org/licenses/LICENSE-2.0.html" - } - }, - "host":"petstore.swagger.io", - "basePath":"/v2", - "tags":[ - { - "name":"pet", - "description":"Everything about your Pets", - "externalDocs":{ - "description":"Find out more", - "url":"http://swagger.io" - } - }, - { - "name":"store", - "description":"Operations about user" - }, - { - "name":"user", - "description":"Access to Petstore orders", - "externalDocs":{ - "description":"Find out more about our store", - "url":"http://swagger.io" - } - } - ], - "schemes":[ - "http" - ], - "paths":{ - "/pet":{ - "post":{ - "tags":[ - "pet" - ], - "summary":"Add a new pet to the store", - "description":"", - "operationId":"addPet", - "consumes":[ - "application/json", - "application/xml" - ], - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "in":"body", - "name":"body", - "description":"Pet object that needs to be added to the store", - "required":false, - "schema":{ - "$ref":"#/definitions/Pet" - } - } - ], - "responses":{ - "405":{ - "description":"Invalid input" - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - }, - "put":{ - "tags":[ - "pet" - ], - "summary":"Update an existing pet", - "description":"", - "operationId":"updatePet", - "consumes":[ - "application/json", - "application/xml" - ], - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "in":"body", - "name":"body", - "description":"Pet object that needs to be added to the store", - "required":false, - "schema":{ - "$ref":"#/definitions/Pet" - } - } - ], - "responses":{ - "400":{ - "description":"Invalid ID supplied" - }, - "404":{ - "description":"Pet not found" - }, - "405":{ - "description":"Validation exception" - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/findByStatus":{ - "get":{ - "tags":[ - "pet" - ], - "summary":"Finds Pets by status", - "description":"Multiple status values can be provided with comma seperated strings", - "operationId":"findPetsByStatus", - "consumes":[ - "application/xml", - "application/json", - "multipart/form-data", - "application/x-www-form-urlencoded" - ], - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"status", - "in":"query", - "description":"Status values that need to be considered for filter", - "required":false, - "type":"array", - "items":{ - "type":"string" - }, - "collectionFormat":"multi", - "default":"available", - "enum":[ - "available", - "pending", - "sold" - ] - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "type":"array", - "items":{ - "$ref":"#/definitions/Pet" - } - } - }, - "400":{ - "description":"Invalid status value" - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/findByTags":{ - "get":{ - "tags":[ - "pet" - ], - "summary":"Finds Pets by tags", - "description":"Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.", - "operationId":"findPetsByTags", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"tags", - "in":"query", - "description":"Tags to filter by", - "required":false, - "type":"array", - "items":{ - "type":"string" - }, - "collectionFormat":"multi" - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "type":"array", - "items":{ - "$ref":"#/definitions/Pet" - } - } - }, - "400":{ - "description":"Invalid tag value" - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/{petId}":{ - "get":{ - "tags":[ - "pet" - ], - "summary":"Find pet by ID", - "description":"Returns a single pet", - "operationId":"getPetById", - "consumes":[ - "application/x-www-form-urlencoded" - ], - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"petId", - "in":"path", - "description":"ID of pet to return", - "required":true, - "type":"integer", - "format":"int64" - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "$ref":"#/definitions/Pet" - } - }, - "400":{ - "description":"Invalid ID supplied" - }, - "404":{ - "description":"Pet not found" - } - }, - "security":[ - { - "api_key":[ - - ] - }, - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - }, - "post":{ - "tags":[ - "pet" - ], - "summary":"Updates a pet in the store with form data", - "description":"", - "operationId":"updatePetWithForm", - "consumes":[ - "application/x-www-form-urlencoded" - ], - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"petId", - "in":"path", - "description":"ID of pet that needs to be updated", - "required":true, - "type":"string" - }, - { - "name":"name", - "in":"formData", - "description":"Updated name of the pet", - "required":false, - "type":"string" - }, - { - "name":"status", - "in":"formData", - "description":"Updated status of the pet", - "required":false, - "type":"string" - } - ], - "responses":{ - "405":{ - "description":"Invalid input" - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - }, - "delete":{ - "tags":[ - "pet" - ], - "summary":"Deletes a pet", - "description":"", - "operationId":"deletePet", - "consumes":[ - "multipart/form-data", - "application/x-www-form-urlencoded" - ], - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"api_key", - "in":"header", - "description":"", - "required":false, - "type":"string" - }, - { - "name":"petId", - "in":"path", - "description":"Pet id to delete", - "required":true, - "type":"integer", - "format":"int64" - } - ], - "responses":{ - "400":{ - "description":"Invalid pet value" - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/{petId}/uploadImage":{ - "post":{ - "tags":[ - "pet" - ], - "summary":"uploads an image", - "description":"", - "operationId":"uploadFile", - "consumes":[ - "multipart/form-data" - ], - "produces":[ - "application/json" - ], - "parameters":[ - { - "name":"petId", - "in":"path", - "description":"ID of pet to update", - "required":true, - "type":"integer", - "format":"int64" - }, - { - "name":"additionalMetadata", - "in":"formData", - "description":"Additional data to pass to server", - "required":false, - "type":"string" - }, - { - "name":"file", - "in":"formData", - "description":"file to upload", - "required":false, - "type":"file" - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "$ref":"#/definitions/ApiResponse" - } - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/store/inventory":{ - "get":{ - "tags":[ - "store" - ], - "summary":"Returns pet inventories by status", - "description":"Returns a map of status codes to quantities", - "operationId":"getInventory", - "produces":[ - "application/json" - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "type":"object", - "additionalProperties":{ - "type":"integer", - "format":"int32" - } - } - } - }, - "security":[ - { - "api_key":[ - - ] - } - ] - } - }, - "/store/order":{ - "post":{ - "tags":[ - "store" - ], - "summary":"Place an order for a pet", - "description":"", - "operationId":"placeOrder", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "in":"body", - "name":"body", - "description":"order placed for purchasing the pet", - "required":false, - "schema":{ - "$ref":"#/definitions/Order" - } - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "$ref":"#/definitions/Order" - } - }, - "400":{ - "description":"Invalid Order" - } - } - } - }, - "/store/order/{orderId}":{ - "get":{ - "tags":[ - "store" - ], - "summary":"Find purchase order by ID", - "description":"For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", - "operationId":"getOrderById", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"orderId", - "in":"path", - "description":"ID of pet that needs to be fetched", - "required":true, - "type":"string" - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "$ref":"#/definitions/Order" - } - }, - "400":{ - "description":"Invalid ID supplied" - }, - "404":{ - "description":"Order not found" - } - } - }, - "delete":{ - "tags":[ - "store" - ], - "summary":"Delete purchase order by ID", - "description":"For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", - "operationId":"deleteOrder", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"orderId", - "in":"path", - "description":"ID of the order that needs to be deleted", - "required":true, - "type":"string" - } - ], - "responses":{ - "400":{ - "description":"Invalid ID supplied" - }, - "404":{ - "description":"Order not found" - } - } - } - }, - "/user":{ - "post":{ - "tags":[ - "user" - ], - "summary":"Create user", - "description":"This can only be done by the logged in user.", - "operationId":"createUser", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "in":"body", - "name":"body", - "description":"Created user object", - "required":false, - "schema":{ - "$ref":"#/definitions/User" - } - } - ], - "responses":{ - "default":{ - "description":"successful operation" - } - } - } - }, - "/user/createWithArray":{ - "post":{ - "tags":[ - "user" - ], - "summary":"Creates list of users with given input array", - "description":"", - "operationId":"createUsersWithArrayInput", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "in":"body", - "name":"body", - "description":"List of user object", - "required":false, - "schema":{ - "type":"array", - "items":{ - "$ref":"#/definitions/User" - } - } - } - ], - "responses":{ - "default":{ - "description":"successful operation" - } - } - } - }, - "/user/createWithList":{ - "post":{ - "tags":[ - "user" - ], - "summary":"Creates list of users with given input array", - "description":"", - "operationId":"createUsersWithListInput", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "in":"body", - "name":"body", - "description":"List of user object", - "required":false, - "schema":{ - "type":"array", - "items":{ - "$ref":"#/definitions/User" - } - } - } - ], - "responses":{ - "default":{ - "description":"successful operation" - } - } - } - }, - "/user/login":{ - "get":{ - "tags":[ - "user" - ], - "summary":"Logs user into the system", - "description":"", - "operationId":"loginUser", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"username", - "in":"query", - "description":"The user name for login", - "required":false, - "type":"string" - }, - { - "name":"password", - "in":"query", - "description":"The password for login in clear text", - "required":false, - "type":"string" - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "type":"string" - }, - "headers":{ - "X-Rate-Limit":{ - "type":"integer", - "format":"int32", - "description":"calls per hour allowed by the user" - }, - "X-Expires-After":{ - "type":"string", - "format":"date-time", - "description":"date in UTC when toekn expires" - } - } - }, - "400":{ - "description":"Invalid username/password supplied" - } - } - } - }, - "/user/logout":{ - "get":{ - "tags":[ - "user" - ], - "summary":"Logs out current logged in user session", - "description":"", - "operationId":"logoutUser", - "produces":[ - "application/xml", - "application/json" - ], - "responses":{ - "default":{ - "description":"successful operation" - } - } - } - }, - "/user/{username}":{ - "get":{ - "tags":[ - "user" - ], - "summary":"Get user by user name", - "description":"", - "operationId":"getUserByName", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"username", - "in":"path", - "description":"The name that needs to be fetched. Use user1 for testing. ", - "required":true, - "type":"string" - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "$ref":"#/definitions/User" - } - }, - "400":{ - "description":"Invalid username supplied" - }, - "404":{ - "description":"User not found" - } - } - }, - "put":{ - "tags":[ - "user" - ], - "summary":"Updated user", - "description":"This can only be done by the logged in user.", - "operationId":"updateUser", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"username", - "in":"path", - "description":"name that need to be deleted", - "required":true, - "type":"string" - }, - { - "in":"body", - "name":"body", - "description":"Updated user object", - "required":false, - "schema":{ - "$ref":"#/definitions/User" - } - } - ], - "responses":{ - "400":{ - "description":"Invalid user supplied" - }, - "404":{ - "description":"User not found" - } - } - }, - "delete":{ - "tags":[ - "user" - ], - "summary":"Delete user", - "description":"This can only be done by the logged in user.", - "operationId":"deleteUser", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"username", - "in":"path", - "description":"The name that needs to be deleted", - "required":true, - "type":"string" - } - ], - "responses":{ - "400":{ - "description":"Invalid username supplied" - }, - "404":{ - "description":"User not found" - } - } - } - } - }, - "securityDefinitions":{ - "petstore_auth":{ - "type":"oauth2", - "authorizationUrl":"http://petstore.swagger.io/api/oauth/dialog", - "flow":"implicit", - "scopes":{ - "write:pets":"modify pets in your account", - "read:pets":"read your pets" - } - }, - "api_key":{ - "type":"apiKey", - "name":"api_key", - "in":"header" - } - }, - "definitions":{ - "Order":{ - "properties":{ - "id":{ - "type":"integer", - "format":"int64" - }, - "petId":{ - "type":"integer", - "format":"int64" - }, - "quantity":{ - "type":"integer", - "format":"int32" - }, - "shipDate":{ - "type":"string", - "format":"date-time" - }, - "status":{ - "type":"string", - "description":"Order Status", - "enum":[ - "placed", - "approved", - "delivered" - ] - }, - "complete":{ - "type":"boolean" - } - }, - "xml":{ - "name":"Order" - } - }, - "Category":{ - "properties":{ - "id":{ - "type":"integer", - "format":"int64" - }, - "name":{ - "type":"string" - } - }, - "xml":{ - "name":"Category" - } - }, - "User":{ - "properties":{ - "id":{ - "type":"integer", - "format":"int64" - }, - "username":{ - "type":"string" - }, - "firstName":{ - "type":"string" - }, - "lastName":{ - "type":"string" - }, - "email":{ - "type":"string" - }, - "password":{ - "type":"string" - }, - "phone":{ - "type":"string" - }, - "userStatus":{ - "type":"integer", - "format":"int32", - "description":"User Status" - } - }, - "xml":{ - "name":"User" - } - }, - "Tag":{ - "properties":{ - "id":{ - "type":"integer", - "format":"int64" - }, - "name":{ - "type":"string" - } - }, - "xml":{ - "name":"Tag" - } - }, - "Pet":{ - "required":[ - "name", - "photoUrls" - ], - "properties":{ - "id":{ - "type":"integer", - "format":"int64" - }, - "category":{ - "$ref":"#/definitions/Category" - }, - "name":{ - "type":"string", - "example":"doggie" - }, - "photoUrls":{ - "type":"array", - "xml":{ - "name":"photoUrl", - "wrapped":true - }, - "items":{ - "type":"string" - } - }, - "tags":{ - "type":"array", - "xml":{ - "name":"tag", - "wrapped":true - }, - "items":{ - "$ref":"#/definitions/Tag" - } - }, - "status":{ - "type":"string", - "description":"pet status in the store", - "enum":[ - "available", - "pending", - "sold" - ] - } - }, - "xml":{ - "name":"Pet" - } - }, - "ApiResponse":{ - "properties":{ - "code":{ - "type":"integer", - "format":"int32" - }, - "type":{ - "type":"string" - }, - "message":{ - "type":"string" - } - }, - "xml":{ - "name":"##default" - } - } - }, - "externalDocs":{ - "description":"Find out more about Swagger", - "url":"http://swagger.io" - } -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/openapi/2.0-petstore_v2.json b/integration-tests/testsuite/src/test/resources/artifactTypes/openapi/2.0-petstore_v2.json deleted file mode 100644 index 98d1c1d24b..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/openapi/2.0-petstore_v2.json +++ /dev/null @@ -1,1046 +0,0 @@ -{ - "swagger":"2.0", - "info":{ - "description":"This is a sample server Petstore server via JSON.", - "version":"1.0.1", - "title":"Swagger Petstore (JSON)", - "termsOfService":"http://helloreverb.com/terms/", - "contact":{ - "email":"apiteam@wordnik.com" - }, - "license":{ - "name":"Apache 2.0", - "url":"http://www.apache.org/licenses/LICENSE-2.0.html" - } - }, - "host":"petstore.swagger.io", - "basePath":"/v2", - "tags":[ - { - "name":"pet", - "description":"Everything about your Pets", - "externalDocs":{ - "description":"Find out more", - "url":"http://swagger.io" - } - }, - { - "name":"store", - "description":"Operations about user" - }, - { - "name":"user", - "description":"Access to Petstore orders", - "externalDocs":{ - "description":"Find out more about our store", - "url":"http://swagger.io" - } - } - ], - "schemes":[ - "http" - ], - "paths":{ - "/pet":{ - "post":{ - "tags":[ - "pet" - ], - "summary":"Add a new pet to the store", - "description":"", - "operationId":"addPet", - "consumes":[ - "application/json", - "application/xml" - ], - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "in":"body", - "name":"body", - "description":"Pet object that needs to be added to the store", - "required":false, - "schema":{ - "$ref":"#/definitions/Pet" - } - } - ], - "responses":{ - "405":{ - "description":"Invalid input" - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - }, - "put":{ - "tags":[ - "pet" - ], - "summary":"Update an existing pet", - "description":"", - "operationId":"updatePet", - "consumes":[ - "application/json", - "application/xml" - ], - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "in":"body", - "name":"body", - "description":"Pet object that needs to be added to the store", - "required":false, - "schema":{ - "$ref":"#/definitions/Pet" - } - } - ], - "responses":{ - "400":{ - "description":"Invalid ID supplied" - }, - "404":{ - "description":"Pet not found" - }, - "405":{ - "description":"Validation exception" - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/findByStatus":{ - "get":{ - "tags":[ - "pet" - ], - "summary":"Finds Pets by status", - "description":"Multiple status values can be provided with comma seperated strings", - "operationId":"findPetsByStatus", - "consumes":[ - "application/xml", - "application/json", - "multipart/form-data", - "application/x-www-form-urlencoded" - ], - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"status", - "in":"query", - "description":"Status values that need to be considered for filter", - "required":false, - "type":"array", - "items":{ - "type":"string" - }, - "collectionFormat":"multi", - "default":"available", - "enum":[ - "available", - "pending", - "sold" - ] - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "type":"array", - "items":{ - "$ref":"#/definitions/Pet" - } - } - }, - "400":{ - "description":"Invalid status value" - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/findByTags":{ - "get":{ - "tags":[ - "pet" - ], - "summary":"Finds Pets by tags", - "description":"Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.", - "operationId":"findPetsByTags", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"tags", - "in":"query", - "description":"Tags to filter by", - "required":false, - "type":"array", - "items":{ - "type":"string" - }, - "collectionFormat":"multi" - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "type":"array", - "items":{ - "$ref":"#/definitions/Pet" - } - } - }, - "400":{ - "description":"Invalid tag value" - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/{petId}":{ - "get":{ - "tags":[ - "pet" - ], - "summary":"Find pet by ID", - "description":"Returns a single pet", - "operationId":"getPetById", - "consumes":[ - "application/x-www-form-urlencoded" - ], - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"petId", - "in":"path", - "description":"ID of pet to return", - "required":true, - "type":"integer", - "format":"int64" - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "$ref":"#/definitions/Pet" - } - }, - "400":{ - "description":"Invalid ID supplied" - }, - "404":{ - "description":"Pet not found" - } - }, - "security":[ - { - "api_key":[ - - ] - }, - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - }, - "post":{ - "tags":[ - "pet" - ], - "summary":"Updates a pet in the store with form data", - "description":"", - "operationId":"updatePetWithForm", - "consumes":[ - "application/x-www-form-urlencoded" - ], - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"petId", - "in":"path", - "description":"ID of pet that needs to be updated", - "required":true, - "type":"string" - }, - { - "name":"name", - "in":"formData", - "description":"Updated name of the pet", - "required":false, - "type":"string" - }, - { - "name":"status", - "in":"formData", - "description":"Updated status of the pet", - "required":false, - "type":"string" - } - ], - "responses":{ - "405":{ - "description":"Invalid input" - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - }, - "delete":{ - "tags":[ - "pet" - ], - "summary":"Deletes a pet", - "description":"", - "operationId":"deletePet", - "consumes":[ - "multipart/form-data", - "application/x-www-form-urlencoded" - ], - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"api_key", - "in":"header", - "description":"", - "required":false, - "type":"string" - }, - { - "name":"petId", - "in":"path", - "description":"Pet id to delete", - "required":true, - "type":"integer", - "format":"int64" - } - ], - "responses":{ - "400":{ - "description":"Invalid pet value" - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/pet/{petId}/uploadImage":{ - "post":{ - "tags":[ - "pet" - ], - "summary":"uploads an image", - "description":"", - "operationId":"uploadFile", - "consumes":[ - "multipart/form-data" - ], - "produces":[ - "application/json" - ], - "parameters":[ - { - "name":"petId", - "in":"path", - "description":"ID of pet to update", - "required":true, - "type":"integer", - "format":"int64" - }, - { - "name":"additionalMetadata", - "in":"formData", - "description":"Additional data to pass to server", - "required":false, - "type":"string" - }, - { - "name":"file", - "in":"formData", - "description":"file to upload", - "required":false, - "type":"file" - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "$ref":"#/definitions/ApiResponse" - } - } - }, - "security":[ - { - "petstore_auth":[ - "write:pets", - "read:pets" - ] - } - ] - } - }, - "/store/inventory":{ - "get":{ - "tags":[ - "store" - ], - "summary":"Returns pet inventories by status", - "description":"Returns a map of status codes to quantities", - "operationId":"getInventory", - "produces":[ - "application/json" - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "type":"object", - "additionalProperties":{ - "type":"integer", - "format":"int32" - } - } - } - }, - "security":[ - { - "api_key":[ - - ] - } - ] - } - }, - "/store/order":{ - "post":{ - "tags":[ - "store" - ], - "summary":"Place an order for a pet", - "description":"", - "operationId":"placeOrder", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "in":"body", - "name":"body", - "description":"order placed for purchasing the pet", - "required":false, - "schema":{ - "$ref":"#/definitions/Order" - } - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "$ref":"#/definitions/Order" - } - }, - "400":{ - "description":"Invalid Order" - } - } - } - }, - "/store/order/{orderId}":{ - "get":{ - "tags":[ - "store" - ], - "summary":"Find purchase order by ID", - "description":"For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", - "operationId":"getOrderById", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"orderId", - "in":"path", - "description":"ID of pet that needs to be fetched", - "required":true, - "type":"string" - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "$ref":"#/definitions/Order" - } - }, - "400":{ - "description":"Invalid ID supplied" - }, - "404":{ - "description":"Order not found" - } - } - }, - "delete":{ - "tags":[ - "store" - ], - "summary":"Delete purchase order by ID", - "description":"For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", - "operationId":"deleteOrder", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"orderId", - "in":"path", - "description":"ID of the order that needs to be deleted", - "required":true, - "type":"string" - } - ], - "responses":{ - "400":{ - "description":"Invalid ID supplied" - }, - "404":{ - "description":"Order not found" - } - } - } - }, - "/user":{ - "post":{ - "tags":[ - "user" - ], - "summary":"Create user", - "description":"This can only be done by the logged in user.", - "operationId":"createUser", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "in":"body", - "name":"body", - "description":"Created user object", - "required":false, - "schema":{ - "$ref":"#/definitions/User" - } - } - ], - "responses":{ - "default":{ - "description":"successful operation" - } - } - } - }, - "/user/createWithArray":{ - "post":{ - "tags":[ - "user" - ], - "summary":"Creates list of users with given input array", - "description":"", - "operationId":"createUsersWithArrayInput", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "in":"body", - "name":"body", - "description":"List of user object", - "required":false, - "schema":{ - "type":"array", - "items":{ - "$ref":"#/definitions/User" - } - } - } - ], - "responses":{ - "default":{ - "description":"successful operation" - } - } - } - }, - "/user/createWithList":{ - "post":{ - "tags":[ - "user" - ], - "summary":"Creates list of users with given input array", - "description":"", - "operationId":"createUsersWithListInput", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "in":"body", - "name":"body", - "description":"List of user object", - "required":false, - "schema":{ - "type":"array", - "items":{ - "$ref":"#/definitions/User" - } - } - } - ], - "responses":{ - "default":{ - "description":"successful operation" - } - } - } - }, - "/user/login":{ - "get":{ - "tags":[ - "user" - ], - "summary":"Logs user into the system", - "description":"", - "operationId":"loginUser", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"username", - "in":"query", - "description":"The user name for login", - "required":false, - "type":"string" - }, - { - "name":"password", - "in":"query", - "description":"The password for login in clear text", - "required":false, - "type":"string" - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "type":"string" - }, - "headers":{ - "X-Rate-Limit":{ - "type":"integer", - "format":"int32", - "description":"calls per hour allowed by the user" - }, - "X-Expires-After":{ - "type":"string", - "format":"date-time", - "description":"date in UTC when toekn expires" - } - } - }, - "400":{ - "description":"Invalid username/password supplied" - } - } - } - }, - "/user/logout":{ - "get":{ - "tags":[ - "user" - ], - "summary":"Logs out current logged in user session", - "description":"", - "operationId":"logoutUser", - "produces":[ - "application/xml", - "application/json" - ], - "responses":{ - "default":{ - "description":"successful operation" - } - } - } - }, - "/user/{username}":{ - "get":{ - "tags":[ - "user" - ], - "summary":"Get user by user name", - "description":"", - "operationId":"getUserByName", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"username", - "in":"path", - "description":"The name that needs to be fetched. Use user1 for testing. ", - "required":true, - "type":"string" - } - ], - "responses":{ - "200":{ - "description":"successful operation", - "schema":{ - "$ref":"#/definitions/User" - } - }, - "400":{ - "description":"Invalid username supplied" - }, - "404":{ - "description":"User not found" - } - } - }, - "put":{ - "tags":[ - "user" - ], - "summary":"Updated user", - "description":"This can only be done by the logged in user.", - "operationId":"updateUser", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"username", - "in":"path", - "description":"name that need to be deleted", - "required":true, - "type":"string" - }, - { - "in":"body", - "name":"body", - "description":"Updated user object", - "required":false, - "schema":{ - "$ref":"#/definitions/User" - } - } - ], - "responses":{ - "400":{ - "description":"Invalid user supplied" - }, - "404":{ - "description":"User not found" - } - } - }, - "delete":{ - "tags":[ - "user" - ], - "summary":"Delete user", - "description":"This can only be done by the logged in user.", - "operationId":"deleteUser", - "produces":[ - "application/xml", - "application/json" - ], - "parameters":[ - { - "name":"username", - "in":"path", - "description":"The name that needs to be deleted", - "required":true, - "type":"string" - } - ], - "responses":{ - "400":{ - "description":"Invalid username supplied" - }, - "404":{ - "description":"User not found" - } - } - } - } - }, - "securityDefinitions":{ - "petstore_auth":{ - "type":"oauth2", - "authorizationUrl":"http://petstore.swagger.io/api/oauth/dialog", - "flow":"implicit", - "scopes":{ - "write:pets":"modify pets in your account", - "read:pets":"read your pets" - } - }, - "api_key":{ - "type":"apiKey", - "name":"api_key", - "in":"header" - } - }, - "definitions":{ - "Order":{ - "properties":{ - "id":{ - "type":"integer", - "format":"int64" - }, - "petId":{ - "type":"integer", - "format":"int64" - }, - "quantity":{ - "type":"integer", - "format":"int32" - }, - "shipDate":{ - "type":"string", - "format":"date-time" - }, - "status":{ - "type":"string", - "description":"Order Status", - "enum":[ - "placed", - "approved", - "delivered" - ] - }, - "complete":{ - "type":"boolean" - }, - "priority":{ - "type":"string" - } - }, - "xml":{ - "name":"Order" - } - }, - "Category":{ - "properties":{ - "id":{ - "type":"integer", - "format":"int64" - }, - "name":{ - "type":"string" - } - }, - "xml":{ - "name":"Category" - } - }, - "User":{ - "properties":{ - "id":{ - "type":"integer", - "format":"int64" - }, - "username":{ - "type":"string" - }, - "firstName":{ - "type":"string" - }, - "lastName":{ - "type":"string" - }, - "email":{ - "type":"string" - }, - "password":{ - "type":"string" - }, - "phone":{ - "type":"string" - }, - "userStatus":{ - "type":"integer", - "format":"int32", - "description":"User Status" - } - }, - "xml":{ - "name":"User" - } - }, - "Tag":{ - "properties":{ - "id":{ - "type":"integer", - "format":"int64" - }, - "name":{ - "type":"string" - } - }, - "xml":{ - "name":"Tag" - } - }, - "Pet":{ - "required":[ - "name", - "photoUrls" - ], - "properties":{ - "id":{ - "type":"integer", - "format":"int64" - }, - "category":{ - "$ref":"#/definitions/Category" - }, - "name":{ - "type":"string", - "example":"doggie" - }, - "photoUrls":{ - "type":"array", - "xml":{ - "name":"photoUrl", - "wrapped":true - }, - "items":{ - "type":"string" - } - }, - "tags":{ - "type":"array", - "xml":{ - "name":"tag", - "wrapped":true - }, - "items":{ - "$ref":"#/definitions/Tag" - } - }, - "status":{ - "type":"string", - "description":"pet status in the store", - "enum":[ - "available", - "pending", - "sold" - ] - } - }, - "xml":{ - "name":"Pet" - } - }, - "ApiResponse":{ - "properties":{ - "code":{ - "type":"integer", - "format":"int32" - }, - "type":{ - "type":"string" - }, - "message":{ - "type":"string" - } - }, - "xml":{ - "name":"##default" - } - } - }, - "externalDocs":{ - "description":"Find out more about Swagger", - "url":"http://swagger.io" - } -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/openapi/3.0-petstore_v1.json b/integration-tests/testsuite/src/test/resources/artifactTypes/openapi/3.0-petstore_v1.json deleted file mode 100644 index 583b1e0990..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/openapi/3.0-petstore_v1.json +++ /dev/null @@ -1,177 +0,0 @@ -{ - "openapi": "3.0.0", - "info": { - "version": "1.0.0", - "title": "Swagger Petstore", - "license": { - "name": "MIT" - } - }, - "servers": [ - { - "url": "http://petstore.swagger.io/v1" - } - ], - "paths": { - "/pets": { - "get": { - "summary": "List all pets", - "operationId": "listPets", - "tags": [ - "pets" - ], - "parameters": [ - { - "name": "limit", - "in": "query", - "description": "How many items to return at one time (max 100)", - "required": false, - "schema": { - "type": "integer", - "format": "int32" - } - } - ], - "responses": { - "200": { - "description": "A paged array of pets", - "headers": { - "x-next": { - "description": "A link to the next page of responses", - "schema": { - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pets" - } - } - } - }, - "default": { - "description": "unexpected error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - }, - "post": { - "summary": "Create a pet", - "operationId": "createPets", - "tags": [ - "pets" - ], - "responses": { - "201": { - "description": "Null response" - }, - "default": { - "description": "unexpected error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - } - }, - "/pets/{petId}": { - "get": { - "summary": "Info for a specific pet", - "operationId": "showPetById", - "tags": [ - "pets" - ], - "parameters": [ - { - "name": "petId", - "in": "path", - "required": true, - "description": "The id of the pet to retrieve", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Expected response to a valid request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "default": { - "description": "unexpected error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "required": [ - "id", - "name" - ], - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "name": { - "type": "string" - }, - "tag": { - "type": "string" - } - } - }, - "Pets": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Pet" - } - }, - "Error": { - "type": "object", - "required": [ - "code", - "message" - ], - "properties": { - "code": { - "type": "integer", - "format": "int32" - }, - "message": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/openapi/3.0-petstore_v2.json b/integration-tests/testsuite/src/test/resources/artifactTypes/openapi/3.0-petstore_v2.json deleted file mode 100644 index 6fde02e30a..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/openapi/3.0-petstore_v2.json +++ /dev/null @@ -1,180 +0,0 @@ -{ - "openapi": "3.0.0", - "info": { - "version": "1.0.0", - "title": "Swagger Petstore", - "license": { - "name": "MIT" - } - }, - "servers": [ - { - "url": "http://petstore.swagger.io/v1" - } - ], - "paths": { - "/pets": { - "get": { - "summary": "List all pets", - "operationId": "listPets", - "tags": [ - "pets" - ], - "parameters": [ - { - "name": "limit", - "in": "query", - "description": "How many items to return at one time (max 100)", - "required": false, - "schema": { - "type": "integer", - "format": "int32" - } - } - ], - "responses": { - "200": { - "description": "A paged array of pets", - "headers": { - "x-next": { - "description": "A link to the next page of responses", - "schema": { - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pets" - } - } - } - }, - "default": { - "description": "unexpected error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - }, - "post": { - "summary": "Create a pet", - "operationId": "createPets", - "tags": [ - "pets" - ], - "responses": { - "201": { - "description": "Null response" - }, - "default": { - "description": "unexpected error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - } - }, - "/pets/{petId}": { - "get": { - "summary": "Info for a specific pet", - "operationId": "showPetById", - "tags": [ - "pets" - ], - "parameters": [ - { - "name": "petId", - "in": "path", - "required": true, - "description": "The id of the pet to retrieve", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Expected response to a valid request", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - } - }, - "default": { - "description": "unexpected error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "type": "object", - "required": [ - "id", - "name" - ], - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "name": { - "type": "string" - }, - "tag": { - "type": "string" - }, - "species": { - "type": "string" - } - } - }, - "Pets": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Pet" - } - }, - "Error": { - "type": "object", - "required": [ - "code", - "message" - ], - "properties": { - "code": { - "type": "integer", - "format": "int32" - }, - "message": { - "type": "string" - } - } - } - } - } -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/protobuf/tutorial_v1.proto b/integration-tests/testsuite/src/test/resources/artifactTypes/protobuf/tutorial_v1.proto deleted file mode 100644 index 3153ad5481..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/protobuf/tutorial_v1.proto +++ /dev/null @@ -1,29 +0,0 @@ -syntax = "proto2"; - -package tutorial; - -option java_package = "com.example.tutorial"; -option java_outer_classname = "AddressBookProtos"; - -message Person { - required string name = 1; - required int32 id = 2; - optional string email = 3; - - enum PhoneType { - MOBILE = 0; - HOME = 1; - WORK = 2; - } - - message PhoneNumber { - required string number = 1; - optional PhoneType type = 2 [default = HOME]; - } - - repeated PhoneNumber phones = 4; -} - -message AddressBook { - repeated Person people = 1; -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/artifactTypes/protobuf/tutorial_v2.proto b/integration-tests/testsuite/src/test/resources/artifactTypes/protobuf/tutorial_v2.proto deleted file mode 100644 index ed366e0fe5..0000000000 --- a/integration-tests/testsuite/src/test/resources/artifactTypes/protobuf/tutorial_v2.proto +++ /dev/null @@ -1,29 +0,0 @@ -syntax = "proto2"; - -package tutorial; - -option java_package = "com.example.tutorials"; -option java_outer_classname = "AddressBookProtos"; - -message Person { - required string name = 1; - required int32 id = 2; - optional string email = 3; - - enum PhoneType { - MOBILE = 0; - HOME = 1; - WORK = 2; - } - - message PhoneNumber { - required string number = 1; - optional PhoneType type = 2 [default = HOME]; - } - - repeated PhoneNumber phones = 4; -} - -message AddressBook { - repeated Person people = 1; -} \ No newline at end of file diff --git a/integration-tests/testsuite/src/test/resources/privateKey.jwk b/integration-tests/testsuite/src/test/resources/privateKey.jwk deleted file mode 100644 index fd33492b39..0000000000 --- a/integration-tests/testsuite/src/test/resources/privateKey.jwk +++ /dev/null @@ -1,11 +0,0 @@ -{ - "kty":"RSA", - "n":"iJw33l1eVAsGoRlSyo-FCimeOc-AaZbzQ2iESA3Nkuo3TFb1zIkmt0kzlnWVGt48dkaIl13Vdefh9hqw_r9yNF8xZqX1fp0PnCWc5M_TX_ht5fm9y0TpbiVmsjeRMWZn4jr3DsFouxQ9aBXUJiu26V0vd2vrECeeAreFT4mtoHY13D2WVeJvboc5mEJcp50JNhxRCJ5UkY8jR_wfUk2Tzz4-fAj5xQaBccXnqJMu_1C6MjoCEiB7G1d13bVPReIeAGRKVJIF6ogoCN8JbrOhc_48lT4uyjbgnd24beatuKWodmWYhactFobRGYo5551cgMe8BoxpVQ4to30cGA0qjQ", - "e":"AQAB", - "d":"AvIDTlsK_priQLTwEQf5IVf2Xl638Q7dHdXyDC-oAAPmv1GcqRVH7Wm5oAPW_CZQfWhV55WRVaJzP8AhksyD5NcslH79hQZT4NT6xgApGYecrvmseuZ4dfR-e1cxXTRNBxaoXvwSiv4LuOPHmC8XGX712AhOoCGKiZp1WFqqkKwTpkgJEApJFVb-XRIKQa0YaRKpJsJ534pLMwTh7LoPLM4BCaBVbRfHzH2H5L3TSJP718kyCuxg3z2p9Y7zIOLTmgFdeR0_kd_xKUFZ2ByN3SKlC0IWlLUSiMPsGYExRpZTMZHKyD939gv-2_Z-bOYfKlYNIvAmQH_8CcX2I039LQ", - "p":"104AjPaxZoi_BiMBODlChnZOvRJT071PdkeZ283uyrdW8qqKD9q8FTMgUXzKoboHtUiHbJbLOobPmPDh93839rq7dTdCNzNVOuLmE-V3_bmaShdzvxEIazwPf6AvjbEZAc-zu2RS4SNkp1LbzgSl9nINSlF7t6Lkl6T28PYULys", - "q":"om5ooyzxa4ZJ-dU0ODsEb-Bmz6xwb27xF9aEhBYJprHeoNs2QM1D64_A39weD9MYwBux4-ivshCJ0dVKEbDujJRLnzf-ssrasA6CFyaaCT4DKtq1oWb9rcG-2LQd5Bm9PttrUrSUNqitr085IYikaLEz7UU6gtXPoC8UOcJ4cSc", - "dp":"DeWE95Q8oweUfMrpmz1m49LjBiUWsAX6CQJaFevWy9LFk-gZ_Sf7F8sy_M93LLUbJkJGK2YYO_DTmWWC0Dyv2gb3bntglLuFdsWKYCJhekjugnW9DMoGpxU7Utt99kFGAe3sBd5V0x47sukQMt3t8FgwL2nO-G1VH8yP-8GGT_0", - "dq":"TGBeE1wuqMCcSD1YMJiPnYuGzF_o_nzMIMldxj4Wi6tXY4uwFwhtx3Xw21JFUGuSV8KuAtyGwNPF-kSwb2Eiyjdw140c1jVMXzxzLy-XfoEKPDxa62niHrHba0pGQ9tWgRfrfxgqGQl3odc-peX6aL_qCsdim-KtnkSE3iPzPkE", - "qi":"Jzp5KnT24y0wOoPUn_11S3ZcYl0i03dkaH4c5zR02G1MJG9K017juurx2aXVTctOzrj7O226EUiL1Qbq3QtnWFDDGY6vNZuqzJM7AMXsvp1djq_6fEVhxCIOgfJbmhb3mkG82rxn4et9o_TNr6mvEmHzG15sHbvZbAnn4GeqToY" -} \ No newline at end of file diff --git a/new-system-tests/README.md b/new-system-tests/README.md deleted file mode 100644 index 45cecead96..0000000000 --- a/new-system-tests/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Apicurio Registry system tests - -System tests for Apicurio Registry and Apicurio Registry operators. diff --git a/new-system-tests/pom.xml b/new-system-tests/pom.xml deleted file mode 100644 index 7e994415a2..0000000000 --- a/new-system-tests/pom.xml +++ /dev/null @@ -1,167 +0,0 @@ - - - - apicurio-registry - io.apicurio - 2.4.13-SNAPSHOT - ../pom.xml - - 4.0.0 - - apicurio-registry-new-system-tests - apicurio-registry-new-system-tests - - - 17 - 17 - 3.1.2 - 3.1.2 - 5.9.0 - 6.9.0 - - 0.101.0 - 2.2 - 2.0.9 - 1.0.0-v2.0.0.final - 1.18.30 - 0.38.0 - 4.2.0 - 1.6.8 - - - - - - - - io.fabric8 - kubernetes-client-bom - ${fabric8.version} - pom - import - - - - - - - - io.fabric8 - openshift-client - ${fabric8.version} - test - - - io.fabric8 - generator-annotations - ${fabric8.version} - - - io.fabric8 - kubernetes-junit-jupiter - - - - - org.junit.jupiter - junit-jupiter - test - - - org.junit.jupiter - junit-jupiter-api - test - - - - org.hamcrest - hamcrest - ${version.hamcrest} - test - - - org.slf4j - slf4j-api - ${version.slf4.simple} - - - org.slf4j - slf4j-simple - ${version.slf4.simple} - - - org.projectlombok - lombok - ${lombok.version} - provided - - - io.sundr - builder-annotations - ${sundrio.version} - provided - - - io.strimzi - api - ${strimzi.version} - - - org.awaitility - awaitility - ${awaitility.version} - - - - - - - maven-surefire-plugin - ${maven.surefire.version} - - - org.apache.maven.plugins - maven-failsafe-plugin - ${maven.failsafe.version} - - - - integration-test - verify - - - - **/IT*.java - **/*IT.java - **/ST*.java - **/*ST.java - - true - - - - - - io.fabric8 - java-generator-maven-plugin - ${fabric8.version} - - - generate-sources - - generate - - - - - https://raw.githubusercontent.com/Apicurio/apicurio-registry-operator/${operator.version}/packagemanifests/${operator.version}/registry.apicur.io_apicurioregistries.yaml - ${project.build.directory}/meta - true - - - - - - diff --git a/new-system-tests/scripts/kind_config.yaml b/new-system-tests/scripts/kind_config.yaml deleted file mode 100644 index 29f49f8b85..0000000000 --- a/new-system-tests/scripts/kind_config.yaml +++ /dev/null @@ -1,18 +0,0 @@ -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -nodes: - - role: control-plane - image: kindest/node:v1.24.7 - kubeadmConfigPatches: - - | - kind: InitConfiguration - nodeRegistration: - kubeletExtraArgs: - node-labels: "ingress-ready=true" - extraPortMappings: - - containerPort: 80 - hostPort: 80 - protocol: TCP - - containerPort: 443 - hostPort: 443 - protocol: TCP diff --git a/new-system-tests/scripts/run.sh b/new-system-tests/scripts/run.sh deleted file mode 100755 index 93fab2efa5..0000000000 --- a/new-system-tests/scripts/run.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -./scripts/setup_cluster.sh - -mvn clean -Dtest=SqlNoIAM test diff --git a/new-system-tests/scripts/setup_cluster.sh b/new-system-tests/scripts/setup_cluster.sh deleted file mode 100755 index 408342e89d..0000000000 --- a/new-system-tests/scripts/setup_cluster.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/bin/bash - -### INITIALIZATION OF VARIABLES ################################################ - -# Define name of cluster for tests -CLUSTER_NAME="apicurio-cluster" -# If CLUSTER_TYPE environment variable is not set, use "kind" as default value -: "${CLUSTER_TYPE:=kind}" - -### SCRIPT FUNCTIONS ########################################################### - -# Logs info message to stdout -function log_info() { - # Print all arguments to stdout - echo "INFO: $*" -} - -# Logs error message to stderr -function log_error() { - # Print all arguments to stderr - echo "ERROR: $*" >&2 -} - -# Checks if kind cluster for tests exists -function kind_cluster_exists() { - # Log information about checking kind cluster existence - log_info "Checking existence of kind cluster '${CLUSTER_NAME}'..." - # Check that there is exactly one kind cluster with name CLUSTER_NAME - [[ $(kind get clusters 2>&1 | grep "^${CLUSTER_NAME}$" -c) -eq 1 ]] -} - -# Creates kind cluster for tests -function kind_cluster_create() { - # Log information about creating kind cluster - log_info "Creating kind cluster '${CLUSTER_NAME}'..." - # Create kind cluster with name CLUSTER_NAME - kind create cluster -n "${CLUSTER_NAME}" --config scripts/kind_config.yaml -} - -# Deploys ingress-nginx-controller to cluster -function ingress_nginx_controller_deploy() { - # Log information about deploying ingress-nginx-controller - log_info "Deploying ingress-nginx-controller..." - # Apply ingress-nginx deploy file - kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml -} - -# Patches ingress-nginx-controller deployment to enable SSL passthrough -function ingress_nginx_controller_patch() { - # Log information about patching ingress-nginx-controller - log_info "Patching ingress-nginx-controller..." - # Patch ingress-nginx-controller deployment - kubectl patch deployment ingress-nginx-controller -n ingress-nginx --type=json -p '[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--enable-ssl-passthrough"}]' -} - -# Deploys OLM to cluster -function olm_deploy() { - # Log information about deploying OLM - log_info "Deploying OLM..." - # Deploy CRDs of OLM - kubectl apply -f https://raw.githubusercontent.com/operator-framework/operator-lifecycle-manager/master/deploy/upstream/quickstart/crds.yaml || return 1 - # Deploy OLM - kubectl apply -f https://raw.githubusercontent.com/operator-framework/operator-lifecycle-manager/master/deploy/upstream/quickstart/olm.yaml || return 1 -} - -# TODO: cleanup function (delete everything) - -### SETUP OF CLUSTER ########################################################### - -# If CLUSTER_TYPE is "openshift" -if [ "$CLUSTER_TYPE" == "openshift" ] -then - # Do pre-run setup of OpenShift cluster - log_info "Nothing to do for OpenShift cluster." -# If CLUSTER_TYPE is "kind" (default) -elif [ "$CLUSTER_TYPE" == "kind" ] -then - # Do pre-run setup of kind cluster - log_info "Preparing kind cluster '${CLUSTER_NAME}'..." - - # If kind cluster already exists - if kind_cluster_exists - then - # Do nothing - log_info "kind cluster '${CLUSTER_NAME}' already exists." - # If kind cluster does not exist - else - # Create kind cluster - - # If kind cluster was successfully created - if kind_cluster_create - then - # Print info about successful creation of kind cluster - log_info "kind cluster '${CLUSTER_NAME}' created." - - # Deploy ingress-nginx-controller - # If deploy was successful - if ingress_nginx_controller_deploy - then - # Log information about success - log_info "ingress-nginx-controller successfully deployed." - # If deploy failed - else - # Log error message - log_error "Deploy of ingress-nginx-controller failed. Exiting..." - # Exit with error code - exit 1 - fi - - # Patch ingress-nginx-controller - # If patch was successful - if ingress_nginx_controller_patch - then - # Log information about success - log_info "Patch of ingress-nginx-controller deployment successful." - # If patch failed - else - # Log error message - log_error "Patch of ingress-nginx-controller deployment failed. Exiting..." - # Exit with error code - exit 1 - fi - - # Deploy OLM - # If deploy was successful - if olm_deploy - then - # Log information about success - log_info "OLM successfully deployed." - # If deploy failed - else - # Log error message - log_error "Deploy of OLM failed. Exiting..." - # Exit with error code - exit 1 - fi - - # TODO: Install cluster-wide Kafka operator - # TODO: Install cluster-wide/namespaced Registry operator here? - # If kind cluster creation failed - else - # Print error message - log_error "Creation of kind cluster '${CLUSTER_NAME}' failed. Exiting..." - # Exit with error code - exit 1 - fi - fi -# If CLUSTER_TYPE is "minikube" -elif [ "$CLUSTER_TYPE" == "minikube" ] -then - # Do pre-run setup of minikube cluster - log_error "minikube cluster is not supported yet." - # Exit with error code - exit 1 -# If CLUSTER_TYPE is not known -else - # Print error message - log_error "Unknown CLUSTER_TYPE '${CLUSTER_TYPE}'. Exiting..." - # Exit with error code - exit 1 -fi diff --git a/new-system-tests/src/main/java/io/apicurio/registry/systemtests/Constants.java b/new-system-tests/src/main/java/io/apicurio/registry/systemtests/Constants.java deleted file mode 100644 index 208ea7b68d..0000000000 --- a/new-system-tests/src/main/java/io/apicurio/registry/systemtests/Constants.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.apicurio.registry.systemtests; - -/** - * Constants used in test suite and tests. - */ -public class Constants { - /** Name of ApicurioRegistry instance for tests. */ - public static final String REGISTRY_NAME = "registry"; - /** Name and namespace of PostgreSQL database instance for tests. */ - public static final String POSTGRESQL_NAME = "postgresql"; - /** Name/prefix of Apicurio Registry operator deployment for tests. */ - public static final String REGISTRY_OPERATOR_NAME = "apicurio-registry-operator"; - /** Name of Keycloak deployment for tests. */ - public static final String KEYCLOAK_NAME = "keycloak"; - /** Name of Kafka instance for tests. */ - public static final String KAFKA_NAME = "kafka"; - /** Name/prefix of Strimzi Kafka operator deployment for tests. */ - public static final String KAFKA_OPERATOR_NAME = "strimzi-cluster-operator"; -} diff --git a/new-system-tests/src/test/java/io/apicurio/registry/systemtests/KafkasqlNoAuthKeycloak.java b/new-system-tests/src/test/java/io/apicurio/registry/systemtests/KafkasqlNoAuthKeycloak.java deleted file mode 100644 index bc3e5d7701..0000000000 --- a/new-system-tests/src/test/java/io/apicurio/registry/systemtests/KafkasqlNoAuthKeycloak.java +++ /dev/null @@ -1,88 +0,0 @@ -package io.apicurio.registry.systemtests; - -import io.apicur.registry.v1.ApicurioRegistry; -import io.fabric8.junit.jupiter.api.KubernetesTest; -import io.fabric8.junit.jupiter.api.LoadKubernetesManifests; -import io.fabric8.openshift.client.OpenShiftClient; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static io.apicurio.registry.systemtests.Utils.findOperatorDeployment; -import static io.apicurio.registry.systemtests.Utils.isDeploymentReady; -import static io.apicurio.registry.systemtests.Utils.waitDeploymentExists; -import static io.apicurio.registry.systemtests.Utils.waitDeploymentReady; -import static io.apicurio.registry.systemtests.Utils.waitKafkaReady; -import static org.junit.jupiter.api.Assertions.assertTrue; - -@KubernetesTest -@LoadKubernetesManifests({ - // Shared resources - "/common/00_operator_group.yaml", // Operator group for installed operators in namespace - // Keycloak IAM - "/keycloak/00_service.yaml", // Service - "/keycloak/01_realm.yaml", // Keycloak realm as realm.json in ConfigMap - "/keycloak/02_deployment.yaml", // Deployment of Keycloak itself - // Strimzi Kafka operator - "/kafkasql/01_subscription.yaml", // Strimzi Kafka operator subscription - // Kafka instance - "/kafkasql/02_no_auth.yaml", // Kafka instance without authentication - // Apicurio Registry operator - "/apicurio/01_subscription.yaml", // Apicurio Registry operator subscription - // Apicurio Registry instance - "/apicurio/02_registry_kafkasql_no_auth_keycloak.yaml" // Apicurio Registry instance with KafkaSQL storage and Keycloak IAM -}) -public class KafkasqlNoAuthKeycloak extends TestBase { - /** {@link OpenShiftClient} instance for tests. */ - private OpenShiftClient client; - - /** - * Performs actions that should be done before each test. - */ - @BeforeEach - public void beforeEach() { - // Log information about current action - logger.info("Running BeforeEach actions."); - - // Wait for readiness of Keycloak deployment - assertTrue(waitDeploymentReady(client, Constants.KEYCLOAK_NAME)); - - // Wait for existence of Strimzi Kafka operator deployment - assertTrue(waitDeploymentExists(client, Constants.KAFKA_OPERATOR_NAME)); - - // Wait for readiness of Strimzi Kafka operator deployment - assertTrue(waitDeploymentReady( - client, - findOperatorDeployment(client, Constants.KAFKA_OPERATOR_NAME).getMetadata().getName()) - ); - - // Wait for readiness of Kafka instance - assertTrue(waitKafkaReady(client, Constants.KAFKA_NAME)); - - // Wait for readiness of Apicurio Registry operator deployment - assertTrue(waitDeploymentReady( - client, - findOperatorDeployment(client, Constants.REGISTRY_OPERATOR_NAME).getMetadata().getName()) - ); - - // Log information about current action - logger.info("BeforeEach finished."); - } - - /** - * Tests that {@link ApicurioRegistry} with KafkaSQL storage and Keycloak IAM becomes ready. - */ - @Test - public void testDeploy() { - // Log information about current action - logger.info("Running testDeploy test."); - - // Wait for readiness of Apicurio Registry instance with KafkaSQL storage deployment and Keycloak IAM - assertTrue(waitDeploymentReady(client, Constants.REGISTRY_NAME + "-deployment")); - - // Check readiness of Apicurio Registry instance with KafkaSQL storage deployment and Keycloak IAM - assertTrue(isDeploymentReady(client, Constants.REGISTRY_NAME + "-deployment")); - - // Log information about current action - logger.info("testDeploy test finished."); - } -} diff --git a/new-system-tests/src/test/java/io/apicurio/registry/systemtests/KafkasqlNoAuthNoIAM.java b/new-system-tests/src/test/java/io/apicurio/registry/systemtests/KafkasqlNoAuthNoIAM.java deleted file mode 100644 index a3c0f7d575..0000000000 --- a/new-system-tests/src/test/java/io/apicurio/registry/systemtests/KafkasqlNoAuthNoIAM.java +++ /dev/null @@ -1,81 +0,0 @@ -package io.apicurio.registry.systemtests; - -import io.apicur.registry.v1.ApicurioRegistry; -import io.fabric8.junit.jupiter.api.KubernetesTest; -import io.fabric8.junit.jupiter.api.LoadKubernetesManifests; -import io.fabric8.openshift.client.OpenShiftClient; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static io.apicurio.registry.systemtests.Utils.findOperatorDeployment; -import static io.apicurio.registry.systemtests.Utils.isDeploymentReady; -import static io.apicurio.registry.systemtests.Utils.waitDeploymentExists; -import static io.apicurio.registry.systemtests.Utils.waitDeploymentReady; -import static io.apicurio.registry.systemtests.Utils.waitKafkaReady; -import static org.junit.jupiter.api.Assertions.assertTrue; - -@KubernetesTest -@LoadKubernetesManifests({ - // Shared resources - "/common/00_operator_group.yaml", // Operator group for installed operators in namespace - // Strimzi Kafka operator - "/kafkasql/01_subscription.yaml", // Strimzi Kafka operator subscription - // Kafka instance - "/kafkasql/02_no_auth.yaml", // Kafka instance without authentication - // Apicurio Registry operator - "/apicurio/01_subscription.yaml", // Apicurio Registry operator subscription - // Apicurio Registry instance - "/apicurio/02_registry_kafkasql_no_auth_no_iam.yaml" // Apicurio Registry instance with KafkaSQL storage and without IAM -}) -public class KafkasqlNoAuthNoIAM extends TestBase { - /** {@link OpenShiftClient} instance for tests. */ - private OpenShiftClient client; - - /** - * Performs actions that should be done before each test. - */ - @BeforeEach - public void beforeEach() { - // Log information about current action - logger.info("Running BeforeEach actions."); - - // Wait for existence of Strimzi Kafka operator deployment - assertTrue(waitDeploymentExists(client, Constants.KAFKA_OPERATOR_NAME)); - - // Wait for readiness of Strimzi Kafka operator deployment - assertTrue(waitDeploymentReady( - client, - findOperatorDeployment(client, Constants.KAFKA_OPERATOR_NAME).getMetadata().getName()) - ); - - // Wait for readiness of Kafka instance - assertTrue(waitKafkaReady(client, Constants.KAFKA_NAME)); - - // Wait for readiness of Apicurio Registry operator deployment - assertTrue(waitDeploymentReady( - client, - findOperatorDeployment(client, Constants.REGISTRY_OPERATOR_NAME).getMetadata().getName()) - ); - - // Log information about current action - logger.info("BeforeEach finished."); - } - - /** - * Tests that {@link ApicurioRegistry} with KafkaSQL storage becomes ready. - */ - @Test - public void testDeploy() { - // Log information about current action - logger.info("Running testDeploy test."); - - // Wait for readiness of Apicurio Registry instance with KafkaSQL storage deployment - assertTrue(waitDeploymentReady(client, Constants.REGISTRY_NAME + "-deployment")); - - // Check readiness of Apicurio Registry instance with KafkaSQL storage deployment - assertTrue(isDeploymentReady(client, Constants.REGISTRY_NAME + "-deployment")); - - // Log information about current action - logger.info("testDeploy test finished."); - } -} diff --git a/new-system-tests/src/test/java/io/apicurio/registry/systemtests/SqlKeycloak.java b/new-system-tests/src/test/java/io/apicurio/registry/systemtests/SqlKeycloak.java deleted file mode 100644 index a7aebf5c80..0000000000 --- a/new-system-tests/src/test/java/io/apicurio/registry/systemtests/SqlKeycloak.java +++ /dev/null @@ -1,76 +0,0 @@ -package io.apicurio.registry.systemtests; - -import io.apicur.registry.v1.ApicurioRegistry; -import io.fabric8.junit.jupiter.api.KubernetesTest; -import io.fabric8.junit.jupiter.api.LoadKubernetesManifests; -import io.fabric8.openshift.client.OpenShiftClient; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static io.apicurio.registry.systemtests.Utils.findOperatorDeployment; -import static io.apicurio.registry.systemtests.Utils.isDeploymentReady; -import static io.apicurio.registry.systemtests.Utils.waitDeploymentReady; -import static org.junit.jupiter.api.Assertions.assertTrue; - -@KubernetesTest -@LoadKubernetesManifests({ - // Shared resources - "/common/00_operator_group.yaml", // Operator group for installed operators in namespace - // Keycloak IAM - "/keycloak/00_service.yaml", // Service - "/keycloak/01_realm.yaml", // Keycloak realm as realm.json in ConfigMap - "/keycloak/02_deployment.yaml", // Deployment of Keycloak itself - // PostgreSQL database resources - "/sql/00_service.yaml", // Service - "/sql/01_deployment.yaml", // Deployment - // Apicurio Registry operator - "/apicurio/01_subscription.yaml", // Apicurio Registry operator subscription - // Apicurio Registry instance - "/apicurio/02_registry_sql_keycloak.yaml" // Apicurio Registry instance with PostgreSQL storage and Keycloak IAM -}) -public class SqlKeycloak extends TestBase { - /** {@link OpenShiftClient} instance for tests. */ - private OpenShiftClient client; - - /** - * Performs actions that should be done before each test. - */ - @BeforeEach - public void beforeEach() { - // Log information about current action - logger.info("Running BeforeEach actions."); - - // Wait for readiness of Keycloak deployment - assertTrue(waitDeploymentReady(client, Constants.KEYCLOAK_NAME)); - - // Wait for readiness of PostgreSQL database deployment - assertTrue(waitDeploymentReady(client, Constants.POSTGRESQL_NAME)); - - // Wait for readiness of Apicurio Registry operator deployment - assertTrue(waitDeploymentReady( - client, - findOperatorDeployment(client, Constants.REGISTRY_OPERATOR_NAME).getMetadata().getName()) - ); - - // Log information about current action - logger.info("BeforeEach finished."); - } - - /** - * Tests that {@link ApicurioRegistry} with PostgreSQL database storage and Keycloak IAM becomes ready. - */ - @Test - public void testDeploy() { - // Log information about current action - logger.info("Running testDeploy test."); - - // Wait for deployment readiness of Apicurio Registry instance with PostgreSQL database storage and Keycloak IAM - assertTrue(waitDeploymentReady(client, Constants.REGISTRY_NAME + "-deployment")); - - // Check deployment readiness of Apicurio Registry instance with PostgreSQL database storage and Keycloak IAM - assertTrue(isDeploymentReady(client, Constants.REGISTRY_NAME + "-deployment")); - - // Log information about current action - logger.info("testDeploy test finished."); - } -} diff --git a/new-system-tests/src/test/java/io/apicurio/registry/systemtests/SqlNoIAM.java b/new-system-tests/src/test/java/io/apicurio/registry/systemtests/SqlNoIAM.java deleted file mode 100644 index dca0217034..0000000000 --- a/new-system-tests/src/test/java/io/apicurio/registry/systemtests/SqlNoIAM.java +++ /dev/null @@ -1,69 +0,0 @@ -package io.apicurio.registry.systemtests; - -import io.apicur.registry.v1.ApicurioRegistry; -import io.fabric8.junit.jupiter.api.KubernetesTest; -import io.fabric8.junit.jupiter.api.LoadKubernetesManifests; -import io.fabric8.openshift.client.OpenShiftClient; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static io.apicurio.registry.systemtests.Utils.findOperatorDeployment; -import static io.apicurio.registry.systemtests.Utils.isDeploymentReady; -import static io.apicurio.registry.systemtests.Utils.waitDeploymentReady; -import static org.junit.jupiter.api.Assertions.assertTrue; - -@KubernetesTest -@LoadKubernetesManifests({ - // Shared resources - "/common/00_operator_group.yaml", // Operator group for installed operators in namespace - // PostgreSQL database resources - "/sql/00_service.yaml", // Service - "/sql/01_deployment.yaml", // Deployment - // Apicurio Registry operator - "/apicurio/01_subscription.yaml", // Apicurio Registry operator subscription - // Apicurio Registry instance - "/apicurio/02_registry_sql_no_iam.yaml" // Apicurio Registry instance with PostgreSQL storage and without IAM -}) -public class SqlNoIAM extends TestBase { - /** {@link OpenShiftClient} instance for tests. */ - private OpenShiftClient client; - - /** - * Performs actions that should be done before each test. - */ - @BeforeEach - public void beforeEach() { - // Log information about current action - logger.info("Running BeforeEach actions."); - - // Wait for readiness of PostgreSQL database deployment - assertTrue(waitDeploymentReady(client, Constants.POSTGRESQL_NAME)); - - // Wait for readiness of Apicurio Registry operator deployment - assertTrue(waitDeploymentReady( - client, - findOperatorDeployment(client, Constants.REGISTRY_OPERATOR_NAME).getMetadata().getName()) - ); - - // Log information about current action - logger.info("BeforeEach finished."); - } - - /** - * Tests that {@link ApicurioRegistry} with PostgreSQL database storage becomes ready. - */ - @Test - public void testDeploy() { - // Log information about current action - logger.info("Running testDeploy test."); - - // Wait for deployment readiness of Apicurio Registry instance with PostgreSQL database storage and without IAM - assertTrue(waitDeploymentReady(client, Constants.REGISTRY_NAME + "-deployment")); - - // Check deployment readiness of Apicurio Registry instance with PostgreSQL database storage and without IAM - assertTrue(isDeploymentReady(client, Constants.REGISTRY_NAME + "-deployment")); - - // Log information about current action - logger.info("testDeploy test finished."); - } -} diff --git a/new-system-tests/src/test/java/io/apicurio/registry/systemtests/TestBase.java b/new-system-tests/src/test/java/io/apicurio/registry/systemtests/TestBase.java deleted file mode 100644 index f2d48b0db4..0000000000 --- a/new-system-tests/src/test/java/io/apicurio/registry/systemtests/TestBase.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.apicurio.registry.systemtests; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Parent class for future subclasses that will share tests. - */ -public abstract class TestBase { - /** {@link Logger} instance for logging in tests. */ - protected Logger logger = LoggerFactory.getLogger(getClass().getName()); - - /** - * We can add test(s) that will be shared between multiple subclasses in the future here. - */ -} diff --git a/new-system-tests/src/test/java/io/apicurio/registry/systemtests/Utils.java b/new-system-tests/src/test/java/io/apicurio/registry/systemtests/Utils.java deleted file mode 100644 index 48d039c12c..0000000000 --- a/new-system-tests/src/test/java/io/apicurio/registry/systemtests/Utils.java +++ /dev/null @@ -1,200 +0,0 @@ -package io.apicurio.registry.systemtests; - -import io.fabric8.kubernetes.api.model.apps.Deployment; -import io.fabric8.kubernetes.client.KubernetesClientTimeoutException; -import io.fabric8.openshift.client.OpenShiftClient; -import io.strimzi.api.kafka.model.Kafka; -import org.awaitility.core.ConditionTimeoutException; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.TimeUnit; - -import static org.awaitility.Awaitility.await; - -/** - * Utilities used in test suite and tests. - */ -public class Utils { - /** - * Finds {@link Deployment} of operator in provided namespace. - * - * @param client {@link OpenShiftClient} instance to use for interaction with cluster. - * @param namespace Name of namespace to search for operator {@link Deployment}. - * @return {@link Deployment} of operator if {@link Deployment} was found; {@code null} otherwise. - */ - public static Deployment findOperatorDeployment(OpenShiftClient client, String namespace, String name) { - return client - .apps() - .deployments() - .inNamespace(namespace) - .list() - .getItems() - .stream() - .filter(d -> d.getMetadata().getName().startsWith(name)) - .findFirst() - .orElse(null); - } - - /** - * Finds {@link Deployment} of operator in client's namespace. - * - * @param client {@link OpenShiftClient} instance to use for interaction with cluster. - * @return {@link Deployment} of operator if {@link Deployment} was found; {@code null} otherwise. - */ - public static Deployment findOperatorDeployment(OpenShiftClient client, String name) { - return findOperatorDeployment(client, client.getNamespace(), name); - } - - /** - * Waits for existence of {@link Deployment} in provided namespace for provided timeout. - * - * @param client {@link OpenShiftClient} instance to use for interaction with cluster. - * @param namespace Name of namespace of {@link Deployment}. - * @param name Name of {@link Deployment} to wait for. - * @param timeUnit {@link TimeUnit} for waiting. - * @param amount Amount of {@link TimeUnit}s to wait. - * @return {@code true} if {@link Deployment} exists within provided timeout; {@code false} otherwise. - */ - public static boolean waitDeploymentExists(OpenShiftClient client, String namespace, String name, TimeUnit timeUnit, long amount) { - try { - await().atMost(amount, timeUnit).until(() -> findOperatorDeployment(client, namespace, name) != null); - } catch (KubernetesClientTimeoutException e) { - LoggerFactory.getLogger(Utils.class).error( - "Deployment '" + name + "' in namespace '" + namespace + "' failed existence check within " + amount + " " + timeUnit.name() + "." - ); - - return false; - } - - return true; - } - - /** - * Waits for existence of {@link Deployment} in client's namespace for pre-defined timeout 5 minutes. - * - * @param client {@link OpenShiftClient} instance to use for interaction with cluster. - * @param name Name of {@link Deployment} to wait for. - * @return {@code true} if {@link Deployment} exists within pre-defined timeout 5 minutes; - * {@code false} otherwise. - */ - public static boolean waitDeploymentExists(OpenShiftClient client, String name) { - return waitDeploymentExists(client, client.getNamespace(), name, TimeUnit.MINUTES, 5); - } - - /** - * Waits for readiness of {@link Deployment} in provided namespace for provided timeout. - * - * @param client {@link OpenShiftClient} instance to use for interaction with cluster. - * @param namespace Name of namespace of {@link Deployment}. - * @param name Name of {@link Deployment} to wait for. - * @param timeUnit {@link TimeUnit} for waiting. - * @param amount Amount of {@link TimeUnit}s to wait. - * @return {@code true} if {@link Deployment} becomes ready within provided timeout; {@code false} otherwise. - */ - public static boolean waitDeploymentReady(OpenShiftClient client, String namespace, String name, TimeUnit timeUnit, long amount) { - try { - client - .apps() - .deployments() - .inNamespace(namespace) - .withName(name) - .waitUntilReady(amount, timeUnit); - } catch (KubernetesClientTimeoutException e) { - LoggerFactory.getLogger(Utils.class).error( - "Deployment '" + name + "' in namespace '" + namespace + "' failed readiness check within " + amount + " " + timeUnit.name() + "." - ); - - return false; - } - - return true; - } - - /** - * Waits for readiness of {@link Deployment} in client's namespace for pre-defined timeout 5 minutes. - * - * @param client {@link OpenShiftClient} instance to use for interaction with cluster. - * @param name Name of {@link Deployment} to wait for. - * @return {@code true} if {@link Deployment} becomes ready within pre-defined timeout 5 minutes; - * {@code false} otherwise. - */ - public static boolean waitDeploymentReady(OpenShiftClient client, String name) { - return waitDeploymentReady(client, client.getNamespace(), name, TimeUnit.MINUTES, 5); - } - - /** - * Checks {@link Deployment} readiness in provided namespace. - * - * @param client {@link OpenShiftClient} instance to use for interaction with cluster. - * @param namespace Name of namespace of {@link Deployment} to check. - * @param name Name of {@link Deployment} to check. - * @return {@code true} if {@link Deployment} is ready; {@code false} otherwise. - */ - public static boolean isDeploymentReady(OpenShiftClient client, String namespace, String name) { - return client - .apps() - .deployments() - .inNamespace(namespace) - .withName(name) - .isReady(); - } - - /** - * Checks {@link Deployment} readiness in client's namespace. - * - * @param client {@link OpenShiftClient} instance to use for interaction with cluster. - * @param name Name of {@link Deployment} to check. - * @return {@code true} if {@link Deployment} is ready; {@code false} otherwise. - */ - public static boolean isDeploymentReady(OpenShiftClient client, String name) { - return isDeploymentReady(client, client.getNamespace(), name); - } - - /** - * Waits for readiness of {@link Kafka} in provided namespace for provided timeout. - * - * @param client {@link OpenShiftClient} instance to use for interaction with cluster. - * @param namespace Name of namespace of {@link Kafka}. - * @param name Name of {@link Kafka} to wait for. - * @param timeUnit {@link TimeUnit} for waiting. - * @param amount Amount of {@link TimeUnit}s to wait. - * @return {@code true} if {@link Kafka} becomes ready within provided timeout; {@code false} otherwise. - */ - public static boolean waitKafkaReady(OpenShiftClient client, String namespace, String name, TimeUnit timeUnit, long amount) { - try { - await().atMost(amount, timeUnit).until(() -> isKafkaReady(client, namespace, name)); - } catch (ConditionTimeoutException e) { - LoggerFactory.getLogger(Utils.class).error( - "Kafka '" + name + "' in namespace '" + namespace + "' failed readiness check within " + amount + " " + timeUnit.name() + "." - ); - - return false; - } - - return true; - } - - /** - * Waits for readiness of {@link Kafka} in client's namespace for pre-defined timeout 5 minutes. - * - * @param client {@link OpenShiftClient} instance to use for interaction with cluster. - * @param name Name of {@link Kafka} to wait for. - * @return {@code true} if {@link Kafka} becomes ready within pre-defined timeout 5 minutes; - * {@code false} otherwise. - */ - public static boolean waitKafkaReady(OpenShiftClient client, String name) { - return waitKafkaReady(client, client.getNamespace(), name, TimeUnit.MINUTES, 5); - } - - /** - * Checks {@link Kafka} readiness in provided namespace. - * - * @param client {@link OpenShiftClient} instance to use for interaction with cluster. - * @param namespace Name of namespace of {@link Kafka} to check. - * @param name Name of {@link Kafka} to check. - * @return {@code true} if {@link Kafka} is ready; {@code false} otherwise. - */ - public static boolean isKafkaReady(OpenShiftClient client, String namespace, String name) { - return client.resources(Kafka.class).inNamespace(namespace).withName(name).isReady(); - } -} diff --git a/new-system-tests/src/test/resources/apicurio/01_subscription.yaml b/new-system-tests/src/test/resources/apicurio/01_subscription.yaml deleted file mode 100644 index 1dd78902df..0000000000 --- a/new-system-tests/src/test/resources/apicurio/01_subscription.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: operators.coreos.com/v1alpha1 -kind: Subscription -metadata: - name: apicurio-registry-operator-subscription -spec: - channel: 2.x - name: apicurio-registry - source: operatorhubio-catalog - sourceNamespace: olm \ No newline at end of file diff --git a/new-system-tests/src/test/resources/apicurio/02_registry_kafkasql_no_auth_keycloak.yaml b/new-system-tests/src/test/resources/apicurio/02_registry_kafkasql_no_auth_keycloak.yaml deleted file mode 100644 index 3f4458b443..0000000000 --- a/new-system-tests/src/test/resources/apicurio/02_registry_kafkasql_no_auth_keycloak.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: registry.apicur.io/v1 -kind: ApicurioRegistry -metadata: - name: registry -spec: - configuration: - kafkasql: - bootstrapServers: 'kafka-kafka-bootstrap:9092' - persistence: kafkasql - security: - keycloak: - apiClientId: registry-client-api - realm: registry - uiClientId: registry-client-ui - url: >- - http://keycloak:8080/auth \ No newline at end of file diff --git a/new-system-tests/src/test/resources/apicurio/02_registry_kafkasql_no_auth_no_iam.yaml b/new-system-tests/src/test/resources/apicurio/02_registry_kafkasql_no_auth_no_iam.yaml deleted file mode 100644 index 956081d897..0000000000 --- a/new-system-tests/src/test/resources/apicurio/02_registry_kafkasql_no_auth_no_iam.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: registry.apicur.io/v1 -kind: ApicurioRegistry -metadata: - name: registry -spec: - configuration: - kafkasql: - bootstrapServers: 'kafka-kafka-bootstrap:9092' - persistence: kafkasql \ No newline at end of file diff --git a/new-system-tests/src/test/resources/apicurio/02_registry_sql_keycloak.yaml b/new-system-tests/src/test/resources/apicurio/02_registry_sql_keycloak.yaml deleted file mode 100644 index 26ccbb3501..0000000000 --- a/new-system-tests/src/test/resources/apicurio/02_registry_sql_keycloak.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: registry.apicur.io/v1 -kind: ApicurioRegistry -metadata: - name: registry -spec: - configuration: - persistence: sql - security: - keycloak: - apiClientId: registry-client-api - realm: registry - uiClientId: registry-client-ui - url: >- - http://keycloak:8080/auth - sql: - dataSource: - password: postgrespassword - url: >- - jdbc:postgresql://postgresql:5432/postgresdb - userName: postgresuser \ No newline at end of file diff --git a/new-system-tests/src/test/resources/apicurio/02_registry_sql_no_iam.yaml b/new-system-tests/src/test/resources/apicurio/02_registry_sql_no_iam.yaml deleted file mode 100644 index f1b20ca18b..0000000000 --- a/new-system-tests/src/test/resources/apicurio/02_registry_sql_no_iam.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: registry.apicur.io/v1 -kind: ApicurioRegistry -metadata: - name: registry -spec: - configuration: - persistence: sql - sql: - dataSource: - password: postgrespassword - url: >- - jdbc:postgresql://postgresql:5432/postgresdb - userName: postgresuser \ No newline at end of file diff --git a/new-system-tests/src/test/resources/common/00_operator_group.yaml b/new-system-tests/src/test/resources/common/00_operator_group.yaml deleted file mode 100644 index f8ef40680d..0000000000 --- a/new-system-tests/src/test/resources/common/00_operator_group.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: operators.coreos.com/v1 -kind: OperatorGroup -metadata: - name: system-tests-operator-group \ No newline at end of file diff --git a/new-system-tests/src/test/resources/kafkasql/01_subscription.yaml b/new-system-tests/src/test/resources/kafkasql/01_subscription.yaml deleted file mode 100644 index bcedde7ae0..0000000000 --- a/new-system-tests/src/test/resources/kafkasql/01_subscription.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: operators.coreos.com/v1alpha1 -kind: Subscription -metadata: - name: strimzi-kafka-operator-subscription -spec: - channel: stable - name: strimzi-kafka-operator - source: operatorhubio-catalog - sourceNamespace: olm \ No newline at end of file diff --git a/new-system-tests/src/test/resources/kafkasql/02_no_auth.yaml b/new-system-tests/src/test/resources/kafkasql/02_no_auth.yaml deleted file mode 100644 index 619bbd38fc..0000000000 --- a/new-system-tests/src/test/resources/kafkasql/02_no_auth.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: kafka.strimzi.io/v1beta2 -kind: Kafka -metadata: - name: kafka -spec: - entityOperator: - topicOperator: {} - userOperator: {} - kafka: - config: - offsets.topic.replication.factor: 1 - transaction.state.log.min.isr: 1 - transaction.state.log.replication.factor: 1 - listeners: - - name: plain - port: 9092 - tls: false - type: internal - replicas: 1 - storage: - type: ephemeral - zookeeper: - replicas: 1 - storage: - type: ephemeral \ No newline at end of file diff --git a/new-system-tests/src/test/resources/keycloak/00_service.yaml b/new-system-tests/src/test/resources/keycloak/00_service.yaml deleted file mode 100644 index 4aaf12fabb..0000000000 --- a/new-system-tests/src/test/resources/keycloak/00_service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: keycloak - labels: - app: keycloak -spec: - ports: - - name: http - port: 8080 - targetPort: 8080 - selector: - app: keycloak - type: ClusterIP \ No newline at end of file diff --git a/new-system-tests/src/test/resources/keycloak/02_deployment.yaml b/new-system-tests/src/test/resources/keycloak/02_deployment.yaml deleted file mode 100644 index 7229810f4f..0000000000 --- a/new-system-tests/src/test/resources/keycloak/02_deployment.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: keycloak - labels: - app: keycloak -spec: - replicas: 1 - selector: - matchLabels: - app: keycloak - template: - metadata: - labels: - app: keycloak - spec: - containers: - - name: keycloak - image: quay.io/keycloak/keycloak:20.0.1 - imagePullPolicy: IfNotPresent - args: ["start-dev", "--import-realm"] - env: - - name: KEYCLOAK_ADMIN - value: "admin" - - name: KEYCLOAK_ADMIN_PASSWORD - value: "admin" - - name: KC_HTTP_RELATIVE_PATH - value: /auth - ports: - - name: http - containerPort: 8080 - volumeMounts: - - name: keycloak-realm-vol - mountPath: /opt/keycloak/data/import/realm.json - subPath: realm.json - volumes: - - name: keycloak-realm-vol - configMap: - name: keycloak-realm \ No newline at end of file diff --git a/new-system-tests/src/test/resources/sql/00_service.yaml b/new-system-tests/src/test/resources/sql/00_service.yaml deleted file mode 100644 index b6623016ef..0000000000 --- a/new-system-tests/src/test/resources/sql/00_service.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: postgresql - labels: - app: postgresql -spec: - ports: - - name: postgresql - port: 5432 - protocol: TCP - targetPort: 5432 - selector: - app: postgresql - type: ClusterIP \ No newline at end of file diff --git a/new-system-tests/src/test/resources/sql/01_deployment.yaml b/new-system-tests/src/test/resources/sql/01_deployment.yaml deleted file mode 100644 index 2ab99ec9c7..0000000000 --- a/new-system-tests/src/test/resources/sql/01_deployment.yaml +++ /dev/null @@ -1,48 +0,0 @@ -kind: Deployment -apiVersion: apps/v1 -metadata: - name: postgresql - labels: - app: postgresql -spec: - replicas: 1 - selector: - matchLabels: - app: postgresql - template: - metadata: - labels: - app: postgresql - spec: - containers: - - readinessProbe: - tcpSocket: - port: 5432 - name: postgresql - livenessProbe: - tcpSocket: - port: 5432 - env: - - name: POSTGRES_ADMIN_PASSWORD - value: adminpassword - - name: POSTGRES_DB - value: postgresdb - - name: POSTGRES_USER - value: postgresuser - - name: POSTGRES_PASSWORD - value: postgrespassword - - name: PGDATA - value: /postgresql/data - ports: - - name: postgresql - containerPort: 5432 - protocol: TCP - imagePullPolicy: IfNotPresent - image: postgres:15 - volumeMounts: - - mountPath: /postgresql - name: postgresql - restartPolicy: Always - volumes: - - name: postgresql - emptyDir: {} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 95a23c5419..5ef20a40ca 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT pom apicurio-registry @@ -151,16 +151,16 @@ 16.17.0 - 3.0.4.Final + 3.2.6.Final - 1.2.3 + 1.2.1 1.11.3 1.0.87 4.9.1 - 4.3.0 + 4.8.0 3.6.0 3.6.0 3.4.0 @@ -175,7 +175,7 @@ 4.6.3 - 7.3.0 + 7.5.1 dev @@ -213,13 +213,13 @@ 0.2.2.Final 1.7.30 0.14.0 - 2.8.1 - 2.2 - 32.1.3-jre + 3.5.1 + 2.1 + 32.1.2-jre 6.5.1 - 2.8.1 + 3.5.1 1.3.5 @@ -253,9 +253,9 @@ 1.7.1 - 1.19.1 + 1.18.3 1.9.0 - 22.0.4 + 21.1.2 2.0.4 0.105.0 2.35.1 @@ -321,12 +321,25 @@ io.apicurio - apicurio-registry-utils-tests + apicurio-registry-storage-sql ${project.version} + test-jar io.apicurio - apicurio-registry-integration-tests-common + apicurio-registry-storage-kafkasql + ${project.version} + test-jar + + + io.apicurio + apicurio-registry-storage-mssql + ${project.version} + test-jar + + + io.apicurio + apicurio-registry-utils-tests ${project.version} @@ -349,6 +362,11 @@ apicurio-registry-storage-kafkasql ${project.version} + + io.apicurio + apicurio-registry-integration-tests + ${project.version} + io.apicurio apicurio-registry-serde-common @@ -564,6 +582,11 @@ + + kotlinx-serialization-core + org.jetbrains.kotlinx + 1.5.1 + com.ibm.icu icu4j @@ -671,6 +694,7 @@ ${woodstox-core.version} + io.confluent @@ -726,32 +750,27 @@ - - io.strimzi - strimzi-test-container - ${strimzi.version} - test - org.testcontainers redpanda ${test-containers.version} test + + io.zonky.test + embedded-postgres + ${embedded-postgres.version} + test + io.quarkus quarkus-test-common ${quarkus.version} test - - com.github.dasniko - testcontainers-keycloak - ${keycloak.testcontainers.version} - org.keycloak - keycloak-admin-client + keycloak-admin-client-jakarta ${keycloak-admin-client.version} @@ -821,14 +840,6 @@ org.jboss.jandex jandex-maven-plugin ${jandex.version} - - - make-index - - jandex - - - io.quarkus @@ -899,6 +910,18 @@ + + org.jboss.jandex + jandex-maven-plugin + + + make-index + + jandex + + + + org.codehaus.mojo properties-maven-plugin @@ -1047,14 +1070,6 @@ - - system-tests - - - system-tests - new-system-tests - - ui @@ -1102,8 +1117,7 @@ integration-tests - integration-tests/integration-tests-common - integration-tests/testsuite + integration-tests diff --git a/schema-resolver/pom.xml b/schema-resolver/pom.xml index 4100589c90..305c1a08b5 100644 --- a/schema-resolver/pom.xml +++ b/schema-resolver/pom.xml @@ -7,7 +7,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml diff --git a/schema-util/asyncapi/pom.xml b/schema-util/asyncapi/pom.xml index 0393693c68..e155191b3a 100644 --- a/schema-util/asyncapi/pom.xml +++ b/schema-util/asyncapi/pom.xml @@ -6,7 +6,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/schema-util/asyncapi/src/main/java/io/apicurio/registry/content/dereference/AsyncApiDereferencer.java b/schema-util/asyncapi/src/main/java/io/apicurio/registry/content/dereference/AsyncApiDereferencer.java new file mode 100644 index 0000000000..80d620ea0c --- /dev/null +++ b/schema-util/asyncapi/src/main/java/io/apicurio/registry/content/dereference/AsyncApiDereferencer.java @@ -0,0 +1,23 @@ +/* + * Copyright 2021 Red Hat + * + * Licensed 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 io.apicurio.registry.content.dereference; + +/** + * @author eric.wittmann@gmail.com + */ +public class AsyncApiDereferencer extends ApicurioDataModelsContentDereferencer { +} diff --git a/schema-util/asyncapi/src/main/java/io/apicurio/registry/content/extract/AsyncApiContentExtractor.java b/schema-util/asyncapi/src/main/java/io/apicurio/registry/content/extract/AsyncApiContentExtractor.java new file mode 100644 index 0000000000..2e396beb6c --- /dev/null +++ b/schema-util/asyncapi/src/main/java/io/apicurio/registry/content/extract/AsyncApiContentExtractor.java @@ -0,0 +1,24 @@ +/* + * Copyright 2020 Red Hat + * + * Licensed 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 io.apicurio.registry.content.extract; + +/** + * Performs meta-data extraction for OpenAPI content. + * @author eric.wittmann@gmail.com + */ +public class AsyncApiContentExtractor extends ApicurioDataModelsContentExtractor { +} diff --git a/schema-util/asyncapi/src/main/java/io/apicurio/registry/content/refs/AsyncApiReferenceFinder.java b/schema-util/asyncapi/src/main/java/io/apicurio/registry/content/refs/AsyncApiReferenceFinder.java new file mode 100644 index 0000000000..dd5b1ae4a7 --- /dev/null +++ b/schema-util/asyncapi/src/main/java/io/apicurio/registry/content/refs/AsyncApiReferenceFinder.java @@ -0,0 +1,26 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +/** + * OpenAPI implementation of a reference finder. Parses the OpenAPI document, finds all $refs, converts them + * to external references, and returns them. + * @author eric.wittmann@gmail.com + */ +public class AsyncApiReferenceFinder extends AbstractDataModelsReferenceFinder { + +} diff --git a/schema-util/avro/pom.xml b/schema-util/avro/pom.xml index b440e284eb..e12851ea93 100644 --- a/schema-util/avro/pom.xml +++ b/schema-util/avro/pom.xml @@ -6,7 +6,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/schema-util/avro/src/main/java/io/apicurio/registry/content/dereference/AvroDereferencer.java b/schema-util/avro/src/main/java/io/apicurio/registry/content/dereference/AvroDereferencer.java index 74278fc6cf..9e922d72f4 100644 --- a/schema-util/avro/src/main/java/io/apicurio/registry/content/dereference/AvroDereferencer.java +++ b/schema-util/avro/src/main/java/io/apicurio/registry/content/dereference/AvroDereferencer.java @@ -36,4 +36,16 @@ public ContentHandle dereference(ContentHandle content, Map resolvedReferenceUrls) { + // Avro does not support rewriting references. A reference in Avro is a QName of a type + // defined in another .avsc file. The location of that other file is not included in the Avro + // specification (in other words there is no "import" statement). So rewriting is meaningless + // in Avro. + return content; + } } diff --git a/schema-util/avro/src/main/java/io/apicurio/registry/content/refs/AvroReferenceFinder.java b/schema-util/avro/src/main/java/io/apicurio/registry/content/refs/AvroReferenceFinder.java new file mode 100644 index 0000000000..bed52750f1 --- /dev/null +++ b/schema-util/avro/src/main/java/io/apicurio/registry/content/refs/AvroReferenceFinder.java @@ -0,0 +1,105 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; + +import io.apicurio.registry.content.ContentHandle; + +/** + * An Apache Avro implementation of a reference finder. + * @author eric.wittmann@gmail.com + */ +public class AvroReferenceFinder implements ReferenceFinder { + + private static final ObjectMapper mapper = new ObjectMapper(); + private static final Logger log = LoggerFactory.getLogger(AvroReferenceFinder.class); + + private static final Set PRIMITIVE_TYPES = Set.of("null", "boolean", "int", "long", "float", "double", "bytes", "string"); + + /** + * @see io.apicurio.registry.content.refs.ReferenceFinder#findExternalReferences(io.apicurio.registry.content.ContentHandle) + */ + @Override + public Set findExternalReferences(ContentHandle content) { + try { + JsonNode tree = mapper.readTree(content.content()); + Set externalTypes = new HashSet<>(); + findExternalTypesIn(tree, externalTypes); + return externalTypes.stream().map(type -> new ExternalReference(type)).collect(Collectors.toSet()); + } catch (Exception e) { + log.error("Error finding external references in an Avro file.", e); + return Collections.emptySet(); + } + } + + private static void findExternalTypesIn(JsonNode schema, Set externalTypes) { + // Null check + if (schema == null || schema.isNull()) { + return; + } + + // Handle primitive/external types + if (schema.isTextual()) { + String type = schema.asText(); + if (!PRIMITIVE_TYPES.contains(type)) { + externalTypes.add(type); + } + } + + // Handle unions + if (schema.isArray()) { + ArrayNode schemas = (ArrayNode) schema; + schemas.forEach(s -> findExternalTypesIn(s, externalTypes)); + } + + // Handle records + if (schema.isObject() && schema.has("type") && !schema.get("type").isNull() && schema.get("type").asText().equals("record")) { + JsonNode fieldsNode = schema.get("fields"); + if (fieldsNode != null && fieldsNode.isArray()) { + ArrayNode fields = (ArrayNode) fieldsNode; + fields.forEach(fieldNode -> { + if (fieldNode.isObject()) { + JsonNode typeNode = fieldNode.get("type"); + findExternalTypesIn(typeNode, externalTypes); + } + }); + } + } + // Handle arrays + if (schema.has("type") && !schema.get("type").isNull() && schema.get("type").asText().equals("array")) { + JsonNode items = schema.get("items"); + findExternalTypesIn(items, externalTypes); + } + // Handle maps + if (schema.has("type") && !schema.get("type").isNull() && schema.get("type").asText().equals("map")) { + JsonNode values = schema.get("values"); + findExternalTypesIn(values, externalTypes); + } + } + +} diff --git a/schema-util/common/pom.xml b/schema-util/common/pom.xml index a019ab24b6..c13864ad7a 100644 --- a/schema-util/common/pom.xml +++ b/schema-util/common/pom.xml @@ -6,7 +6,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/schema-util/common/src/main/java/io/apicurio/registry/content/dereference/ContentDereferencer.java b/schema-util/common/src/main/java/io/apicurio/registry/content/dereference/ContentDereferencer.java index ba8c08683f..c751996c07 100644 --- a/schema-util/common/src/main/java/io/apicurio/registry/content/dereference/ContentDereferencer.java +++ b/schema-util/common/src/main/java/io/apicurio/registry/content/dereference/ContentDereferencer.java @@ -32,4 +32,14 @@ public interface ContentDereferencer { * @param content */ ContentHandle dereference(ContentHandle content, Map resolvedReferences); + + /** + * Called to rewrite any references in the content so that they point to valid Registry API URLs rather than + * "logical" values. For example, if an OpenAPI document has a $ref property with + * a value of ./common-types.json#/defs/FooType this method will rewrite that property + * to something like https://registry.example.com/apis/registry/v2/groups/Example/artifacts/CommonTypes/versions/1.0. + * @param content + * @param resolvedReferences + */ + ContentHandle rewriteReferences(ContentHandle content, Map resolvedReferenceUrls); } diff --git a/schema-util/common/src/main/java/io/apicurio/registry/content/refs/ExternalReference.java b/schema-util/common/src/main/java/io/apicurio/registry/content/refs/ExternalReference.java new file mode 100644 index 0000000000..4483b210d5 --- /dev/null +++ b/schema-util/common/src/main/java/io/apicurio/registry/content/refs/ExternalReference.java @@ -0,0 +1,158 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +import java.util.Objects; + +/** + * Models a reference from one artifact to another. This represents the information found in the content + * of an artifact, and is very type-specific. For example, a JSON schema reference might look like this: + * + *

+ * {
+ *   "$ref" : "types/data-types.json#/$defs/FooType"
+ * }
+ * 
+ * + * In this case, the fields of this type will be: + * + *
    + *
  • fullReference: types/data-types.json#/$defs/FooType
  • + *
  • resource: types/data-types.json
  • + *
  • component: #/$defs/FooType
  • + *
+ * + * For an Avro artifact a reference might look like this: + * + *
+ * {
+ *   "name": "exchange",
+ *   "type": "com.kubetrade.schema.common.Exchange"
+ * }
+ * 
+ * + * In this case, the fields of this type will be: + * + *
    + *
  • fullReference: com.kubetrade.schema.common.Exchange
  • + *
  • resource: com.kubetrade.schema.common.Exchange
  • + *
  • component: null
  • + *
+ * + * @author eric.wittmann@gmail.com + */ +public class ExternalReference { + + private String fullReference; + private String resource; + private String component; + + /** + * Constructor. + * @param fullReference + * @param resource + * @param component + */ + public ExternalReference(String fullReference, String resource, String component) { + this.fullReference = fullReference; + this.resource = resource; + this.component = component; + } + + /** + * Constructor. This variant is useful if there is no component part of an external reference. In this + * case the full reference is also the resource (and the component is null). + * @param reference + */ + public ExternalReference(String reference) { + this(reference, reference, null); + } + + /** + * @return the fullReference + */ + public String getFullReference() { + return fullReference; + } + + /** + * @param fullReference the fullReference to set + */ + public void setFullReference(String fullReference) { + this.fullReference = fullReference; + } + + /** + * @return the resource + */ + public String getResource() { + return resource; + } + + /** + * @param resource the resource to set + */ + public void setResource(String resource) { + this.resource = resource; + } + + /** + * @return the component + */ + public String getComponent() { + return component; + } + + /** + * @param component the component to set + */ + public void setComponent(String component) { + this.component = component; + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return Objects.hash(fullReference); + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ExternalReference other = (ExternalReference) obj; + return Objects.equals(fullReference, other.fullReference); + } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return this.fullReference; + } + +} diff --git a/schema-util/common/src/main/java/io/apicurio/registry/content/refs/JsonPointerExternalReference.java b/schema-util/common/src/main/java/io/apicurio/registry/content/refs/JsonPointerExternalReference.java new file mode 100644 index 0000000000..a1afd0d3d7 --- /dev/null +++ b/schema-util/common/src/main/java/io/apicurio/registry/content/refs/JsonPointerExternalReference.java @@ -0,0 +1,54 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +/** + * @author eric.wittmann@gmail.com + */ +public class JsonPointerExternalReference extends ExternalReference { + + /** + * Constructor. + * @param jsonPointer + */ + public JsonPointerExternalReference(String jsonPointer) { + super(jsonPointer, resourceFrom(jsonPointer), componentFrom(jsonPointer)); + } + + private static String componentFrom(String jsonPointer) { + int idx = jsonPointer.indexOf('#'); + if (idx == 0) { + return jsonPointer; + } else if (idx > 0) { + return jsonPointer.substring(idx); + } else { + return null; + } + } + + private static String resourceFrom(String jsonPointer) { + int idx = jsonPointer.indexOf('#'); + if (idx == 0) { + return null; + } else if (idx > 0) { + return jsonPointer.substring(0, idx); + } else { + return jsonPointer; + } + } + +} diff --git a/schema-util/common/src/main/java/io/apicurio/registry/content/refs/NoOpReferenceFinder.java b/schema-util/common/src/main/java/io/apicurio/registry/content/refs/NoOpReferenceFinder.java new file mode 100644 index 0000000000..9a42418300 --- /dev/null +++ b/schema-util/common/src/main/java/io/apicurio/registry/content/refs/NoOpReferenceFinder.java @@ -0,0 +1,39 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +import java.util.Collections; +import java.util.Set; + +import io.apicurio.registry.content.ContentHandle; + +/** + * @author eric.wittmann@gmail.com + */ +public class NoOpReferenceFinder implements ReferenceFinder { + + public static final ReferenceFinder INSTANCE = new NoOpReferenceFinder(); + + /** + * @see io.apicurio.registry.content.refs.ReferenceFinder#findExternalReferences(io.apicurio.registry.content.ContentHandle) + */ + @Override + public Set findExternalReferences(ContentHandle content) { + return Collections.emptySet(); + } + +} diff --git a/schema-util/common/src/main/java/io/apicurio/registry/content/refs/ReferenceFinder.java b/schema-util/common/src/main/java/io/apicurio/registry/content/refs/ReferenceFinder.java new file mode 100644 index 0000000000..b662ea280b --- /dev/null +++ b/schema-util/common/src/main/java/io/apicurio/registry/content/refs/ReferenceFinder.java @@ -0,0 +1,34 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +import java.util.Set; + +import io.apicurio.registry.content.ContentHandle; + +/** + * @author eric.wittmann@gmail.com + */ +public interface ReferenceFinder { + + /** + * Finds the set of external references in a piece of content. + * @param content + */ + public Set findExternalReferences(ContentHandle content); + +} diff --git a/schema-util/graphql/pom.xml b/schema-util/graphql/pom.xml index da2f890580..8071a3f165 100644 --- a/schema-util/graphql/pom.xml +++ b/schema-util/graphql/pom.xml @@ -6,7 +6,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/schema-util/graphql/src/main/java/io/apicurio/registry/rules/validity/GraphQLContentValidator.java b/schema-util/graphql/src/main/java/io/apicurio/registry/rules/validity/GraphQLContentValidator.java index 54a0aeb693..6f01de4c7e 100644 --- a/schema-util/graphql/src/main/java/io/apicurio/registry/rules/validity/GraphQLContentValidator.java +++ b/schema-util/graphql/src/main/java/io/apicurio/registry/rules/validity/GraphQLContentValidator.java @@ -46,6 +46,7 @@ public void validate(ValidityLevel level, ContentHandle content, Map io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/schema-util/json/src/main/java/io/apicurio/registry/content/dereference/JsonSchemaDereferencer.java b/schema-util/json/src/main/java/io/apicurio/registry/content/dereference/JsonSchemaDereferencer.java index cc1deb8d40..fdd09f4541 100644 --- a/schema-util/json/src/main/java/io/apicurio/registry/content/dereference/JsonSchemaDereferencer.java +++ b/schema-util/json/src/main/java/io/apicurio/registry/content/dereference/JsonSchemaDereferencer.java @@ -16,21 +16,25 @@ package io.apicurio.registry.content.dereference; +import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; + +import java.io.IOException; +import java.util.Iterator; +import java.util.Map; + import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; + import io.apicurio.registry.content.ContentHandle; import io.apicurio.registry.rules.compatibility.jsonschema.JsonUtil; -import java.io.IOException; -import java.util.Map; - -import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; - /** * @author carnalca@redhat.com */ @@ -58,4 +62,42 @@ public ContentHandle dereference(ContentHandle content, Map resolvedReferenceUrls) { + try { + JsonNode tree = objectMapper.readTree(content.content()); + rewriteIn(tree, resolvedReferenceUrls); + String converted = objectMapper.writeValueAsString(objectMapper.treeToValue(tree, Object.class)); + return ContentHandle.create(converted); + } catch (Exception e) { + return content; + } + } + + private void rewriteIn(JsonNode node, Map resolvedReferenceUrls) { + if (node.isObject()) { + rewriteInObject((ObjectNode) node, resolvedReferenceUrls); + } + } + + private void rewriteInObject(ObjectNode node, Map resolvedReferenceUrls) { + if (node.hasNonNull("$ref")) { + String $ref = node.get("$ref").asText(); + if (resolvedReferenceUrls.containsKey($ref)) { + node.put("$ref", resolvedReferenceUrls.get($ref)); + } + } + Iterator fieldNames = node.fieldNames(); + while (fieldNames.hasNext()) { + String fieldName = fieldNames.next(); + JsonNode fieldValue = node.get(fieldName); + if (fieldValue.isObject()) { + rewriteInObject((ObjectNode) fieldValue, resolvedReferenceUrls); + } + } + } } diff --git a/schema-util/json/src/main/java/io/apicurio/registry/content/refs/JsonSchemaReferenceFinder.java b/schema-util/json/src/main/java/io/apicurio/registry/content/refs/JsonSchemaReferenceFinder.java new file mode 100644 index 0000000000..356e645cab --- /dev/null +++ b/schema-util/json/src/main/java/io/apicurio/registry/content/refs/JsonSchemaReferenceFinder.java @@ -0,0 +1,80 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.Set; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.apicurio.registry.content.ContentHandle; + +/** + * A JSON Schema implementation of a reference finder. + * @author eric.wittmann@gmail.com + */ +public class JsonSchemaReferenceFinder implements ReferenceFinder { + + private static final ObjectMapper mapper = new ObjectMapper(); + private static final Logger log = LoggerFactory.getLogger(JsonSchemaReferenceFinder.class); + + /** + * @see io.apicurio.registry.content.refs.ReferenceFinder#findExternalReferences(io.apicurio.registry.content.ContentHandle) + */ + @Override + public Set findExternalReferences(ContentHandle content) { + try { + JsonNode tree = mapper.readTree(content.content()); + Set externalTypes = new HashSet<>(); + findExternalTypesIn(tree, externalTypes); + + return externalTypes.stream() + .map(type -> new JsonPointerExternalReference(type)) + .filter(ref -> ref.getResource() != null) + .collect(Collectors.toSet()); + } catch (Exception e) { + log.error("Error finding external references in an Avro file.", e); + return Collections.emptySet(); + } + } + + private static void findExternalTypesIn(JsonNode schema, Set externalTypes) { + if (schema.isObject()) { + if (schema.has("$ref")) { + String ref = schema.get("$ref").asText(null); + if (ref != null) { + // TODO: the value of the ref should be resolved against the $id in this schema if it has one + externalTypes.add(ref); + } + } + Iterator> fields = schema.fields(); + while (fields.hasNext()) { + Entry field = fields.next(); + findExternalTypesIn(field.getValue(), externalTypes); + } + } + } + +} diff --git a/schema-util/kconnect/pom.xml b/schema-util/kconnect/pom.xml index 31fcb03a1f..6b627ce3c0 100644 --- a/schema-util/kconnect/pom.xml +++ b/schema-util/kconnect/pom.xml @@ -6,7 +6,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/schema-util/openapi/pom.xml b/schema-util/openapi/pom.xml index b005ea7c32..50abb6d14c 100644 --- a/schema-util/openapi/pom.xml +++ b/schema-util/openapi/pom.xml @@ -6,7 +6,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/schema-util/openapi/src/main/java/io/apicurio/registry/content/dereference/ApicurioDataModelsContentDereferencer.java b/schema-util/openapi/src/main/java/io/apicurio/registry/content/dereference/ApicurioDataModelsContentDereferencer.java new file mode 100644 index 0000000000..38c9843064 --- /dev/null +++ b/schema-util/openapi/src/main/java/io/apicurio/registry/content/dereference/ApicurioDataModelsContentDereferencer.java @@ -0,0 +1,49 @@ +/* + * Copyright 2021 Red Hat + * + * Licensed 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 io.apicurio.registry.content.dereference; + +import java.util.Map; + +import io.apicurio.datamodels.Library; +import io.apicurio.datamodels.TraverserDirection; +import io.apicurio.datamodels.models.Document; +import io.apicurio.registry.content.ContentHandle; + +/** + * @author eric.wittmann@gmail.com + */ +public class ApicurioDataModelsContentDereferencer implements ContentDereferencer { + + @Override + public ContentHandle dereference(ContentHandle content, Map resolvedReferences) { + // TODO not yet implemented +// Document document = Library.readDocumentFromJSONString(content.content()); +// Library.dereference(document); + return content; + } + + /** + * @see io.apicurio.registry.content.dereference.ContentDereferencer#rewriteReferences(io.apicurio.registry.content.ContentHandle, java.util.Map) + */ + @Override + public ContentHandle rewriteReferences(ContentHandle content, Map resolvedReferenceUrls) { + Document doc = Library.readDocumentFromJSONString(content.content()); + ReferenceRewriter visitor = new ReferenceRewriter(resolvedReferenceUrls); + Library.visitTree(doc, visitor, TraverserDirection.down); + return ContentHandle.create(Library.writeDocumentToJSONString(doc)); + } +} diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryStorageType.java b/schema-util/openapi/src/main/java/io/apicurio/registry/content/dereference/OpenApiDereferencer.java similarity index 73% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryStorageType.java rename to schema-util/openapi/src/main/java/io/apicurio/registry/content/dereference/OpenApiDereferencer.java index 2e02ed62f6..6ea2f32c23 100644 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryStorageType.java +++ b/schema-util/openapi/src/main/java/io/apicurio/registry/content/dereference/OpenApiDereferencer.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Red Hat + * Copyright 2021 Red Hat * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apicurio.tests.common; -public enum RegistryStorageType { - inmemory, - sql, - kafkasql; +package io.apicurio.registry.content.dereference; + +/** + * @author eric.wittmann@gmail.com + */ +public class OpenApiDereferencer extends ApicurioDataModelsContentDereferencer { } diff --git a/schema-util/openapi/src/main/java/io/apicurio/registry/content/dereference/ReferenceRewriter.java b/schema-util/openapi/src/main/java/io/apicurio/registry/content/dereference/ReferenceRewriter.java new file mode 100644 index 0000000000..3a18aaa35d --- /dev/null +++ b/schema-util/openapi/src/main/java/io/apicurio/registry/content/dereference/ReferenceRewriter.java @@ -0,0 +1,76 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.dereference; + +import java.util.Map; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import io.apicurio.datamodels.models.Node; +import io.apicurio.datamodels.models.Referenceable; +import io.apicurio.datamodels.models.asyncapi.AsyncApiMessage; +import io.apicurio.datamodels.models.visitors.AllNodeVisitor; + +/** + * Rewrites all references in a data model using a map of replacements provided. + * @author eric.wittmann@gmail.com + */ +public class ReferenceRewriter extends AllNodeVisitor { + + private final Map referenceUrls; + + /** + * Constructor. + * @param resolvedReferenceUrls + */ + public ReferenceRewriter(Map referenceUrls) { + this.referenceUrls = referenceUrls; + } + + /** + * @see io.apicurio.datamodels.models.visitors.AllNodeVisitor#visitNode(io.apicurio.datamodels.models.Node) + */ + @Override + protected void visitNode(Node node) { + if (node instanceof Referenceable) { + String $ref = ((Referenceable) node).get$ref(); + if ($ref != null && referenceUrls.containsKey($ref)) { + ((Referenceable) node).set$ref(referenceUrls.get($ref)); + } + } + } + + /** + * @see io.apicurio.datamodels.models.visitors.AllNodeVisitor#visitMessage(io.apicurio.datamodels.models.asyncapi.AsyncApiMessage) + */ + @Override + public void visitMessage(AsyncApiMessage node) { + super.visitMessage(node); + + // Note: for now we have special handling of the payload because it's not yet fully modeled in the + // apicurio-data-models library. + JsonNode payload = node.getPayload(); + if (payload != null && payload.hasNonNull("$ref")) { + String $ref = payload.get("$ref").asText(); + if (referenceUrls.containsKey($ref)) { + ((ObjectNode) payload).put("$ref", referenceUrls.get($ref)); + } + } + } + +} diff --git a/schema-util/openapi/src/main/java/io/apicurio/registry/content/extract/OpenApiOrAsyncApiContentExtractor.java b/schema-util/openapi/src/main/java/io/apicurio/registry/content/extract/ApicurioDataModelsContentExtractor.java similarity index 96% rename from schema-util/openapi/src/main/java/io/apicurio/registry/content/extract/OpenApiOrAsyncApiContentExtractor.java rename to schema-util/openapi/src/main/java/io/apicurio/registry/content/extract/ApicurioDataModelsContentExtractor.java index d8818902ce..e4f0667658 100644 --- a/schema-util/openapi/src/main/java/io/apicurio/registry/content/extract/OpenApiOrAsyncApiContentExtractor.java +++ b/schema-util/openapi/src/main/java/io/apicurio/registry/content/extract/ApicurioDataModelsContentExtractor.java @@ -30,7 +30,7 @@ * Performs meta-data extraction for OpenAPI content. * @author eric.wittmann@gmail.com */ -public class OpenApiOrAsyncApiContentExtractor implements ContentExtractor { +public class ApicurioDataModelsContentExtractor implements ContentExtractor { Logger log = LoggerFactory.getLogger(getClass()); diff --git a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryTestProcess.java b/schema-util/openapi/src/main/java/io/apicurio/registry/content/extract/OpenApiContentExtractor.java similarity index 72% rename from integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryTestProcess.java rename to schema-util/openapi/src/main/java/io/apicurio/registry/content/extract/OpenApiContentExtractor.java index 7bfac3a5ae..a50997d207 100644 --- a/integration-tests/integration-tests-common/src/main/java/io/apicurio/tests/common/RegistryTestProcess.java +++ b/schema-util/openapi/src/main/java/io/apicurio/registry/content/extract/OpenApiContentExtractor.java @@ -13,16 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apicurio.tests.common; -public interface RegistryTestProcess extends AutoCloseable { +package io.apicurio.registry.content.extract; - public boolean isContainer(); - - public String getName(); - - public String getStdOut(); - - public String getStdErr(); - -} \ No newline at end of file +/** + * Performs meta-data extraction for OpenAPI content. + * @author eric.wittmann@gmail.com + */ +public class OpenApiContentExtractor extends ApicurioDataModelsContentExtractor { +} diff --git a/schema-util/openapi/src/main/java/io/apicurio/registry/content/refs/AbstractDataModelsReferenceFinder.java b/schema-util/openapi/src/main/java/io/apicurio/registry/content/refs/AbstractDataModelsReferenceFinder.java new file mode 100644 index 0000000000..0baf5e71db --- /dev/null +++ b/schema-util/openapi/src/main/java/io/apicurio/registry/content/refs/AbstractDataModelsReferenceFinder.java @@ -0,0 +1,98 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.databind.JsonNode; + +import io.apicurio.datamodels.Library; +import io.apicurio.datamodels.TraverserDirection; +import io.apicurio.datamodels.models.Document; +import io.apicurio.datamodels.models.Node; +import io.apicurio.datamodels.models.Referenceable; +import io.apicurio.datamodels.models.asyncapi.AsyncApiMessage; +import io.apicurio.datamodels.models.visitors.AllNodeVisitor; +import io.apicurio.registry.content.ContentHandle; + +/** + * Implementation of a reference finder that uses Apicurio Data Models and so supports any specification + * contained therein. Parses the document, finds all $refs, converts them to external references, and + * returns them. + * + * @author eric.wittmann@gmail.com + */ +public abstract class AbstractDataModelsReferenceFinder implements ReferenceFinder { + + /** + * @see io.apicurio.registry.content.refs.ReferenceFinder#findExternalReferences(io.apicurio.registry.content.ContentHandle) + */ + @Override + public Set findExternalReferences(ContentHandle content) { + Document doc = Library.readDocumentFromJSONString(content.content()); + + // Find all the $refs + RefFinderVisitor visitor = new RefFinderVisitor(); + Library.visitTree(doc, visitor, TraverserDirection.down); + + // Convert to ExternalReference and filter. + return visitor.allReferences.stream() + .map(ref -> new JsonPointerExternalReference(ref)) + .filter(ref -> ref.getResource() != null) + .collect(Collectors.toSet()); + } + + /** + * Visitor that will visit every node looking for "$ref" properties. + * @author eric.wittmann@gmail.com + */ + private static class RefFinderVisitor extends AllNodeVisitor { + + public Set allReferences = new HashSet<>(); + + /** + * @see io.apicurio.datamodels.models.visitors.AllNodeVisitor#visitNode(io.apicurio.datamodels.models.Node) + */ + @Override + protected void visitNode(Node node) { + if (node instanceof Referenceable) { + String ref = ((Referenceable) node).get$ref(); + if (ref != null && !ref.trim().isEmpty()) { + allReferences.add(ref); + } + } + } + + /** + * @see io.apicurio.datamodels.models.visitors.AllNodeVisitor#visitMessage(io.apicurio.datamodels.models.asyncapi.AsyncApiMessage) + */ + @Override + public void visitMessage(AsyncApiMessage node) { + // Note: special handling of message payloads because data-models doesn't fully model the payload yet. + JsonNode payload = node.getPayload(); + if (payload != null && payload.has("$ref") && !payload.get("$ref").isNull()) { + String ref = payload.get("$ref").asText(); + allReferences.add(ref); + } + super.visitMessage(node); + } + + } + +} diff --git a/schema-util/openapi/src/main/java/io/apicurio/registry/content/refs/OpenApiReferenceFinder.java b/schema-util/openapi/src/main/java/io/apicurio/registry/content/refs/OpenApiReferenceFinder.java new file mode 100644 index 0000000000..d56eabbf84 --- /dev/null +++ b/schema-util/openapi/src/main/java/io/apicurio/registry/content/refs/OpenApiReferenceFinder.java @@ -0,0 +1,26 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +/** + * OpenAPI implementation of a reference finder. Parses the OpenAPI document, finds all $refs, converts them + * to external references, and returns them. + * @author eric.wittmann@gmail.com + */ +public class OpenApiReferenceFinder extends AbstractDataModelsReferenceFinder { + +} diff --git a/schema-util/protobuf/pom.xml b/schema-util/protobuf/pom.xml index 00499577e4..e8bc50c20c 100644 --- a/schema-util/protobuf/pom.xml +++ b/schema-util/protobuf/pom.xml @@ -6,7 +6,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/schema-util/protobuf/src/main/java/io/apicurio/registry/content/dereference/ProtobufDereferencer.java b/schema-util/protobuf/src/main/java/io/apicurio/registry/content/dereference/ProtobufDereferencer.java index 0157b24142..e42bd87a51 100644 --- a/schema-util/protobuf/src/main/java/io/apicurio/registry/content/dereference/ProtobufDereferencer.java +++ b/schema-util/protobuf/src/main/java/io/apicurio/registry/content/dereference/ProtobufDereferencer.java @@ -34,6 +34,7 @@ public class ProtobufDereferencer implements ContentDereferencer { @Override public ContentHandle dereference(ContentHandle content, Map resolvedReferences) { //FIXME this code is not dereferencing references, only validating that all that references are resolvable + //FIXME CAN this even be done in Proto? Can multiple types in different namespaces be defined in the same .proto file? Does it matter? Needs investigation. final ProtoFileElement protoFileElement = ProtobufFile.toProtoFileElement(content.content()); final Map dependencies = Collections.unmodifiableMap(resolvedReferences.entrySet() .stream() @@ -47,4 +48,13 @@ public ContentHandle dereference(ContentHandle content, Map resolvedReferenceUrls) { + // TODO not yet implemented (perhaps cannot be implemented?) + return content; + } } \ No newline at end of file diff --git a/schema-util/protobuf/src/main/java/io/apicurio/registry/content/refs/ProtobufReferenceFinder.java b/schema-util/protobuf/src/main/java/io/apicurio/registry/content/refs/ProtobufReferenceFinder.java new file mode 100644 index 0000000000..c01ab830d2 --- /dev/null +++ b/schema-util/protobuf/src/main/java/io/apicurio/registry/content/refs/ProtobufReferenceFinder.java @@ -0,0 +1,57 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.squareup.wire.schema.internal.parser.ProtoFileElement; + +import io.apicurio.registry.content.ContentHandle; +import io.apicurio.registry.utils.protobuf.schema.ProtobufFile; + +/** + * A Google Protocol Buffer implementation of a reference finder. + * @author eric.wittmann@gmail.com + */ +public class ProtobufReferenceFinder implements ReferenceFinder { + + private static final Logger log = LoggerFactory.getLogger(ProtobufReferenceFinder.class); + + /** + * @see io.apicurio.registry.content.refs.ReferenceFinder#findExternalReferences(io.apicurio.registry.content.ContentHandle) + */ + @Override + public Set findExternalReferences(ContentHandle content) { + try { + ProtoFileElement protoFileElement = ProtobufFile.toProtoFileElement(content.content()); + Set allImports = new HashSet<>(); + allImports.addAll(protoFileElement.getImports()); + allImports.addAll(protoFileElement.getPublicImports()); + return allImports.stream().map(imprt -> new ExternalReference(imprt)).collect(Collectors.toSet()); + } catch (Exception e) { + log.error("Error finding external references in a Protobuf file.", e); + return Collections.emptySet(); + } + } + +} diff --git a/schema-util/util-provider/pom.xml b/schema-util/util-provider/pom.xml index 682fcffd9a..a1a1cf700f 100644 --- a/schema-util/util-provider/pom.xml +++ b/schema-util/util-provider/pom.xml @@ -6,7 +6,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/ArtifactTypeUtilProvider.java b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/ArtifactTypeUtilProvider.java index 8fed5b31c1..1bcb1d2115 100644 --- a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/ArtifactTypeUtilProvider.java +++ b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/ArtifactTypeUtilProvider.java @@ -19,6 +19,7 @@ import io.apicurio.registry.content.canon.ContentCanonicalizer; import io.apicurio.registry.content.dereference.ContentDereferencer; import io.apicurio.registry.content.extract.ContentExtractor; +import io.apicurio.registry.content.refs.ReferenceFinder; import io.apicurio.registry.rules.compatibility.CompatibilityChecker; import io.apicurio.registry.rules.validity.ContentValidator; @@ -44,4 +45,6 @@ public interface ArtifactTypeUtilProvider { ContentExtractor getContentExtractor(); ContentDereferencer getContentDereferencer(); + + ReferenceFinder getReferenceFinder(); } diff --git a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/AsyncApiArtifactTypeUtilProvider.java b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/AsyncApiArtifactTypeUtilProvider.java index bd5bcaed1e..b63a5a238d 100644 --- a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/AsyncApiArtifactTypeUtilProvider.java +++ b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/AsyncApiArtifactTypeUtilProvider.java @@ -18,10 +18,12 @@ import io.apicurio.registry.content.canon.ContentCanonicalizer; import io.apicurio.registry.content.canon.JsonContentCanonicalizer; +import io.apicurio.registry.content.dereference.AsyncApiDereferencer; import io.apicurio.registry.content.dereference.ContentDereferencer; -import io.apicurio.registry.content.dereference.JsonSchemaDereferencer; +import io.apicurio.registry.content.extract.AsyncApiContentExtractor; import io.apicurio.registry.content.extract.ContentExtractor; -import io.apicurio.registry.content.extract.OpenApiOrAsyncApiContentExtractor; +import io.apicurio.registry.content.refs.AsyncApiReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; import io.apicurio.registry.rules.compatibility.CompatibilityChecker; import io.apicurio.registry.rules.compatibility.NoopCompatibilityChecker; import io.apicurio.registry.rules.validity.AsyncApiContentValidator; @@ -55,11 +57,16 @@ protected ContentValidator createContentValidator() { @Override protected ContentExtractor createContentExtractor() { - return new OpenApiOrAsyncApiContentExtractor(); + return new AsyncApiContentExtractor(); } @Override public ContentDereferencer getContentDereferencer() { - return new JsonSchemaDereferencer(); + return new AsyncApiDereferencer(); + } + + @Override + public ReferenceFinder getReferenceFinder() { + return new AsyncApiReferenceFinder(); } } diff --git a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/AvroArtifactTypeUtilProvider.java b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/AvroArtifactTypeUtilProvider.java index 98aa80237a..ac1ff3ce3a 100644 --- a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/AvroArtifactTypeUtilProvider.java +++ b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/AvroArtifactTypeUtilProvider.java @@ -22,6 +22,8 @@ import io.apicurio.registry.content.dereference.ContentDereferencer; import io.apicurio.registry.content.extract.AvroContentExtractor; import io.apicurio.registry.content.extract.ContentExtractor; +import io.apicurio.registry.content.refs.JsonSchemaReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; import io.apicurio.registry.rules.compatibility.AvroCompatibilityChecker; import io.apicurio.registry.rules.compatibility.CompatibilityChecker; import io.apicurio.registry.rules.validity.AvroContentValidator; @@ -62,4 +64,9 @@ protected ContentExtractor createContentExtractor() { public ContentDereferencer getContentDereferencer() { return new AvroDereferencer(); } + + @Override + public ReferenceFinder getReferenceFinder() { + return new JsonSchemaReferenceFinder(); + } } diff --git a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/GraphQLArtifactTypeUtilProvider.java b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/GraphQLArtifactTypeUtilProvider.java index 4ed15b300a..e3c8dc210e 100644 --- a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/GraphQLArtifactTypeUtilProvider.java +++ b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/GraphQLArtifactTypeUtilProvider.java @@ -21,6 +21,8 @@ import io.apicurio.registry.content.dereference.ContentDereferencer; import io.apicurio.registry.content.extract.ContentExtractor; import io.apicurio.registry.content.extract.NoopContentExtractor; +import io.apicurio.registry.content.refs.NoOpReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; import io.apicurio.registry.rules.compatibility.CompatibilityChecker; import io.apicurio.registry.rules.compatibility.NoopCompatibilityChecker; import io.apicurio.registry.rules.validity.ContentValidator; @@ -60,4 +62,12 @@ protected ContentExtractor createContentExtractor() { public ContentDereferencer getContentDereferencer() { return null; } + + /** + * @see io.apicurio.registry.types.provider.ArtifactTypeUtilProvider#getReferenceFinder() + */ + @Override + public ReferenceFinder getReferenceFinder() { + return NoOpReferenceFinder.INSTANCE; + } } diff --git a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/JsonArtifactTypeUtilProvider.java b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/JsonArtifactTypeUtilProvider.java index 2815819d3e..82c6446da5 100644 --- a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/JsonArtifactTypeUtilProvider.java +++ b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/JsonArtifactTypeUtilProvider.java @@ -19,9 +19,11 @@ import io.apicurio.registry.content.canon.ContentCanonicalizer; import io.apicurio.registry.content.canon.JsonContentCanonicalizer; import io.apicurio.registry.content.dereference.ContentDereferencer; -import io.apicurio.registry.content.dereference.JsonSchemaDereferencer; +import io.apicurio.registry.content.dereference.AsyncApiDereferencer; import io.apicurio.registry.content.extract.ContentExtractor; import io.apicurio.registry.content.extract.JsonContentExtractor; +import io.apicurio.registry.content.refs.JsonSchemaReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; import io.apicurio.registry.rules.compatibility.CompatibilityChecker; import io.apicurio.registry.rules.compatibility.JsonSchemaCompatibilityChecker; import io.apicurio.registry.rules.validity.ContentValidator; @@ -60,6 +62,11 @@ protected ContentExtractor createContentExtractor() { @Override public ContentDereferencer getContentDereferencer() { - return new JsonSchemaDereferencer(); + return new AsyncApiDereferencer(); + } + + @Override + public ReferenceFinder getReferenceFinder() { + return new JsonSchemaReferenceFinder(); } } diff --git a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/KConnectArtifactTypeUtilProvider.java b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/KConnectArtifactTypeUtilProvider.java index de3edbe23e..1803c5ee14 100644 --- a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/KConnectArtifactTypeUtilProvider.java +++ b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/KConnectArtifactTypeUtilProvider.java @@ -21,6 +21,8 @@ import io.apicurio.registry.content.dereference.ContentDereferencer; import io.apicurio.registry.content.extract.ContentExtractor; import io.apicurio.registry.content.extract.NoopContentExtractor; +import io.apicurio.registry.content.refs.NoOpReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; import io.apicurio.registry.rules.compatibility.CompatibilityChecker; import io.apicurio.registry.rules.compatibility.NoopCompatibilityChecker; import io.apicurio.registry.rules.validity.ContentValidator; @@ -60,4 +62,12 @@ protected ContentExtractor createContentExtractor() { public ContentDereferencer getContentDereferencer() { return null; } + + /** + * @see io.apicurio.registry.types.provider.ArtifactTypeUtilProvider#getReferenceFinder() + */ + @Override + public ReferenceFinder getReferenceFinder() { + return NoOpReferenceFinder.INSTANCE; + } } diff --git a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/OpenApiArtifactTypeUtilProvider.java b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/OpenApiArtifactTypeUtilProvider.java index a479b5be2b..b26413d45a 100644 --- a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/OpenApiArtifactTypeUtilProvider.java +++ b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/OpenApiArtifactTypeUtilProvider.java @@ -19,9 +19,11 @@ import io.apicurio.registry.content.canon.ContentCanonicalizer; import io.apicurio.registry.content.canon.JsonContentCanonicalizer; import io.apicurio.registry.content.dereference.ContentDereferencer; -import io.apicurio.registry.content.dereference.JsonSchemaDereferencer; +import io.apicurio.registry.content.dereference.AsyncApiDereferencer; import io.apicurio.registry.content.extract.ContentExtractor; -import io.apicurio.registry.content.extract.OpenApiOrAsyncApiContentExtractor; +import io.apicurio.registry.content.extract.OpenApiContentExtractor; +import io.apicurio.registry.content.refs.OpenApiReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; import io.apicurio.registry.rules.compatibility.CompatibilityChecker; import io.apicurio.registry.rules.compatibility.NoopCompatibilityChecker; import io.apicurio.registry.rules.validity.ContentValidator; @@ -55,11 +57,16 @@ protected ContentValidator createContentValidator() { @Override protected ContentExtractor createContentExtractor() { - return new OpenApiOrAsyncApiContentExtractor(); + return new OpenApiContentExtractor(); } @Override public ContentDereferencer getContentDereferencer() { - return new JsonSchemaDereferencer(); + return new AsyncApiDereferencer(); + } + + @Override + public ReferenceFinder getReferenceFinder() { + return new OpenApiReferenceFinder(); } } diff --git a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/ProtobufArtifactTypeUtilProvider.java b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/ProtobufArtifactTypeUtilProvider.java index 856db9a130..d0f0f62456 100644 --- a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/ProtobufArtifactTypeUtilProvider.java +++ b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/ProtobufArtifactTypeUtilProvider.java @@ -22,6 +22,8 @@ import io.apicurio.registry.content.dereference.ProtobufDereferencer; import io.apicurio.registry.content.extract.ContentExtractor; import io.apicurio.registry.content.extract.NoopContentExtractor; +import io.apicurio.registry.content.refs.ProtobufReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; import io.apicurio.registry.rules.compatibility.CompatibilityChecker; import io.apicurio.registry.rules.compatibility.ProtobufCompatibilityChecker; import io.apicurio.registry.rules.validity.ContentValidator; @@ -61,4 +63,9 @@ protected ContentExtractor createContentExtractor() { public ContentDereferencer getContentDereferencer() { return new ProtobufDereferencer(); } + + @Override + public ReferenceFinder getReferenceFinder() { + return new ProtobufReferenceFinder(); + } } diff --git a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/WsdlArtifactTypeUtilProvider.java b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/WsdlArtifactTypeUtilProvider.java index 07c3cbc47f..86f56a6289 100644 --- a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/WsdlArtifactTypeUtilProvider.java +++ b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/WsdlArtifactTypeUtilProvider.java @@ -21,6 +21,8 @@ import io.apicurio.registry.content.dereference.ContentDereferencer; import io.apicurio.registry.content.extract.ContentExtractor; import io.apicurio.registry.content.extract.WsdlOrXsdContentExtractor; +import io.apicurio.registry.content.refs.NoOpReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; import io.apicurio.registry.rules.compatibility.CompatibilityChecker; import io.apicurio.registry.rules.compatibility.NoopCompatibilityChecker; import io.apicurio.registry.rules.validity.ContentValidator; @@ -76,4 +78,12 @@ protected ContentExtractor createContentExtractor() { public ContentDereferencer getContentDereferencer() { return null; } + + /** + * @see io.apicurio.registry.types.provider.ArtifactTypeUtilProvider#getReferenceFinder() + */ + @Override + public ReferenceFinder getReferenceFinder() { + return NoOpReferenceFinder.INSTANCE; + } } diff --git a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/XmlArtifactTypeUtilProvider.java b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/XmlArtifactTypeUtilProvider.java index 56b6fb11ff..701e10ecbb 100644 --- a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/XmlArtifactTypeUtilProvider.java +++ b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/XmlArtifactTypeUtilProvider.java @@ -21,6 +21,8 @@ import io.apicurio.registry.content.dereference.ContentDereferencer; import io.apicurio.registry.content.extract.ContentExtractor; import io.apicurio.registry.content.extract.NoopContentExtractor; +import io.apicurio.registry.content.refs.NoOpReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; import io.apicurio.registry.rules.compatibility.CompatibilityChecker; import io.apicurio.registry.rules.compatibility.NoopCompatibilityChecker; import io.apicurio.registry.rules.validity.ContentValidator; @@ -76,4 +78,12 @@ protected ContentExtractor createContentExtractor() { public ContentDereferencer getContentDereferencer() { return null; } + + /** + * @see io.apicurio.registry.types.provider.ArtifactTypeUtilProvider#getReferenceFinder() + */ + @Override + public ReferenceFinder getReferenceFinder() { + return NoOpReferenceFinder.INSTANCE; + } } diff --git a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/XsdArtifactTypeUtilProvider.java b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/XsdArtifactTypeUtilProvider.java index c887875c08..120609112c 100644 --- a/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/XsdArtifactTypeUtilProvider.java +++ b/schema-util/util-provider/src/main/java/io/apicurio/registry/types/provider/XsdArtifactTypeUtilProvider.java @@ -21,6 +21,8 @@ import io.apicurio.registry.content.dereference.ContentDereferencer; import io.apicurio.registry.content.extract.ContentExtractor; import io.apicurio.registry.content.extract.WsdlOrXsdContentExtractor; +import io.apicurio.registry.content.refs.NoOpReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; import io.apicurio.registry.rules.compatibility.CompatibilityChecker; import io.apicurio.registry.rules.compatibility.NoopCompatibilityChecker; import io.apicurio.registry.rules.validity.ContentValidator; @@ -76,4 +78,12 @@ protected ContentExtractor createContentExtractor() { public ContentDereferencer getContentDereferencer() { return null; } + + /** + * @see io.apicurio.registry.types.provider.ArtifactTypeUtilProvider#getReferenceFinder() + */ + @Override + public ReferenceFinder getReferenceFinder() { + return NoOpReferenceFinder.INSTANCE; + } } diff --git a/schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/AsyncApiContentDereferencerTest.java b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/AsyncApiContentDereferencerTest.java new file mode 100644 index 0000000000..61b37970e2 --- /dev/null +++ b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/AsyncApiContentDereferencerTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.dereference; + +import java.util.Map; +import java.util.Set; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.apicurio.registry.content.ContentHandle; +import io.apicurio.registry.content.refs.ExternalReference; +import io.apicurio.registry.content.refs.JsonPointerExternalReference; +import io.apicurio.registry.content.refs.AsyncApiReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; +import io.apicurio.registry.rules.validity.ArtifactUtilProviderTestBase; + +/** + * @author eric.wittmann@gmail.com + */ +public class AsyncApiContentDereferencerTest extends ArtifactUtilProviderTestBase { + + @Test + public void testRewriteReferences() { + ContentHandle content = resourceToContentHandle("asyncapi-to-rewrite.json"); + AsyncApiDereferencer dereferencer = new AsyncApiDereferencer(); + ContentHandle modifiedContent = dereferencer.rewriteReferences(content, Map.of( + "./TradeKey.avsc", "https://www.example.org/schemas/TradeKey.avsc", + "./common-types.json#/components/schemas/User", "https://www.example.org/schemas/common-types.json#/components/schemas/User")); + + ReferenceFinder finder = new AsyncApiReferenceFinder(); + Set externalReferences = finder.findExternalReferences(modifiedContent); + Assertions.assertTrue(externalReferences.contains(new JsonPointerExternalReference("https://www.example.org/schemas/common-types.json#/components/schemas/User"))); + Assertions.assertTrue(externalReferences.contains(new JsonPointerExternalReference("https://www.example.org/schemas/TradeKey.avsc"))); + } + +} diff --git a/schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/JsonSchemaContentDereferencerTest.java b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/JsonSchemaContentDereferencerTest.java new file mode 100644 index 0000000000..9ff854c8bf --- /dev/null +++ b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/JsonSchemaContentDereferencerTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.dereference; + +import java.util.Map; +import java.util.Set; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.apicurio.registry.content.ContentHandle; +import io.apicurio.registry.content.refs.ExternalReference; +import io.apicurio.registry.content.refs.JsonPointerExternalReference; +import io.apicurio.registry.content.refs.JsonSchemaReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; +import io.apicurio.registry.rules.validity.ArtifactUtilProviderTestBase; + +/** + * @author eric.wittmann@gmail.com + */ +public class JsonSchemaContentDereferencerTest extends ArtifactUtilProviderTestBase { + + @Test + public void testRewriteReferences() { + ContentHandle content = resourceToContentHandle("json-schema-to-rewrite.json"); + JsonSchemaDereferencer dereferencer = new JsonSchemaDereferencer(); + ContentHandle modifiedContent = dereferencer.rewriteReferences(content, Map.of( + "./address.json", "https://www.example.org/schemas/address.json", + "./ssn.json", "https://www.example.org/schemas/ssn.json")); + + ReferenceFinder finder = new JsonSchemaReferenceFinder(); + Set externalReferences = finder.findExternalReferences(modifiedContent); + Assertions.assertTrue(externalReferences.contains(new JsonPointerExternalReference("https://www.example.org/schemas/address.json"))); + Assertions.assertTrue(externalReferences.contains(new JsonPointerExternalReference("https://www.example.org/schemas/ssn.json"))); + } + +} diff --git a/schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/OpenApiContentDereferencerTest.java b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/OpenApiContentDereferencerTest.java new file mode 100644 index 0000000000..376842b380 --- /dev/null +++ b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/OpenApiContentDereferencerTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.dereference; + +import java.util.Map; +import java.util.Set; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.apicurio.registry.content.ContentHandle; +import io.apicurio.registry.content.refs.ExternalReference; +import io.apicurio.registry.content.refs.JsonPointerExternalReference; +import io.apicurio.registry.content.refs.OpenApiReferenceFinder; +import io.apicurio.registry.content.refs.ReferenceFinder; +import io.apicurio.registry.rules.validity.ArtifactUtilProviderTestBase; + +/** + * @author eric.wittmann@gmail.com + */ +public class OpenApiContentDereferencerTest extends ArtifactUtilProviderTestBase { + + @Test + public void testRewriteReferences() { + ContentHandle content = resourceToContentHandle("openapi-to-rewrite.json"); + OpenApiDereferencer dereferencer = new OpenApiDereferencer(); + ContentHandle modifiedContent = dereferencer.rewriteReferences(content, Map.of( + "./types/bar-types.json#/components/schemas/Bar", "https://www.example.org/schemas/bar-types.json#/components/schemas/Bar", + "./types/foo-types.json#/components/schemas/Foo", "https://www.example.org/schemas/foo-types.json#/components/schemas/Foo")); + + ReferenceFinder finder = new OpenApiReferenceFinder(); + Set externalReferences = finder.findExternalReferences(modifiedContent); + Assertions.assertTrue(externalReferences.contains(new JsonPointerExternalReference("https://www.example.org/schemas/bar-types.json#/components/schemas/Bar"))); + Assertions.assertTrue(externalReferences.contains(new JsonPointerExternalReference("https://www.example.org/schemas/foo-types.json#/components/schemas/Foo"))); + } + +} diff --git a/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/AsyncApiReferenceFinderTest.java b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/AsyncApiReferenceFinderTest.java new file mode 100644 index 0000000000..013caa9c93 --- /dev/null +++ b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/AsyncApiReferenceFinderTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +import java.util.Set; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.apicurio.registry.content.ContentHandle; +import io.apicurio.registry.rules.validity.ArtifactUtilProviderTestBase; + +/** + * @author eric.wittmann@gmail.com + */ +public class AsyncApiReferenceFinderTest extends ArtifactUtilProviderTestBase { + + /** + * Test method for {@link io.apicurio.registry.content.refs.AsyncApiReferenceFinder#findExternalReferences(io.apicurio.registry.content.ContentHandle)}. + */ + @Test + public void testFindExternalReferences() { + ContentHandle content = resourceToContentHandle("asyncapi-with-refs.json"); + AsyncApiReferenceFinder finder = new AsyncApiReferenceFinder(); + Set foundReferences = finder.findExternalReferences(content); + Assertions.assertNotNull(foundReferences); + Assertions.assertEquals(2, foundReferences.size()); + Assertions.assertEquals(Set.of( + new JsonPointerExternalReference("./TradeKey.avsc"), + new JsonPointerExternalReference("./common-types.json#/components/schemas/User")), foundReferences); + } + +} diff --git a/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/AvroReferenceFinderTest.java b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/AvroReferenceFinderTest.java new file mode 100644 index 0000000000..ac125bb3e0 --- /dev/null +++ b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/AvroReferenceFinderTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +import java.util.Set; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.apicurio.registry.content.ContentHandle; +import io.apicurio.registry.rules.validity.ArtifactUtilProviderTestBase; + +/** + * @author eric.wittmann@gmail.com + */ +public class AvroReferenceFinderTest extends ArtifactUtilProviderTestBase { + + /** + * Test method for {@link io.apicurio.registry.content.refs.AsyncApiReferenceFinder#findExternalReferences(io.apicurio.registry.content.ContentHandle)}. + */ + @Test + public void testFindExternalReferences() { + ContentHandle content = resourceToContentHandle("avro-with-refs.avsc"); + AvroReferenceFinder finder = new AvroReferenceFinder(); + Set foundReferences = finder.findExternalReferences(content); + Assertions.assertNotNull(foundReferences); + Assertions.assertEquals(2, foundReferences.size()); + Assertions.assertEquals(Set.of( + new ExternalReference("com.kubetrade.schema.trade.TradeKey"), + new ExternalReference("com.kubetrade.schema.trade.TradeValue")), foundReferences); + } + +} diff --git a/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/JsonSchemaReferenceFinderTest.java b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/JsonSchemaReferenceFinderTest.java new file mode 100644 index 0000000000..65202d7495 --- /dev/null +++ b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/JsonSchemaReferenceFinderTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +import java.util.Set; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.apicurio.registry.content.ContentHandle; +import io.apicurio.registry.rules.validity.ArtifactUtilProviderTestBase; + +/** + * @author eric.wittmann@gmail.com + */ +public class JsonSchemaReferenceFinderTest extends ArtifactUtilProviderTestBase { + + /** + * Test method for {@link io.apicurio.registry.content.refs.AsyncApiReferenceFinder#findExternalReferences(io.apicurio.registry.content.ContentHandle)}. + */ + @Test + public void testFindExternalReferences() { + ContentHandle content = resourceToContentHandle("json-schema-with-refs.json"); + JsonSchemaReferenceFinder finder = new JsonSchemaReferenceFinder(); + Set foundReferences = finder.findExternalReferences(content); + Assertions.assertNotNull(foundReferences); + Assertions.assertEquals(2, foundReferences.size()); + Assertions.assertEquals(Set.of(new JsonPointerExternalReference("./address.json"), new JsonPointerExternalReference("./ssn.json")), foundReferences); + } + +} diff --git a/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/OpenApiReferenceFinderTest.java b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/OpenApiReferenceFinderTest.java new file mode 100644 index 0000000000..276f4be35e --- /dev/null +++ b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/OpenApiReferenceFinderTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +import java.util.Set; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.apicurio.registry.content.ContentHandle; +import io.apicurio.registry.rules.validity.ArtifactUtilProviderTestBase; + +/** + * @author eric.wittmann@gmail.com + */ +public class OpenApiReferenceFinderTest extends ArtifactUtilProviderTestBase { + + /** + * Test method for {@link io.apicurio.registry.content.refs.AsyncApiReferenceFinder#findExternalReferences(io.apicurio.registry.content.ContentHandle)}. + */ + @Test + public void testFindExternalReferences() { + ContentHandle content = resourceToContentHandle("openapi-with-refs.json"); + OpenApiReferenceFinder finder = new OpenApiReferenceFinder(); + Set foundReferences = finder.findExternalReferences(content); + Assertions.assertNotNull(foundReferences); + Assertions.assertEquals(2, foundReferences.size()); + Assertions.assertEquals(Set.of( + new JsonPointerExternalReference("./types/bar-types.json#/components/schemas/Bar"), + new JsonPointerExternalReference("./types/foo-types.json#/components/schemas/Foo")), foundReferences); + } + +} diff --git a/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/ProtobufReferenceFinderTest.java b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/ProtobufReferenceFinderTest.java new file mode 100644 index 0000000000..4729e58ae7 --- /dev/null +++ b/schema-util/util-provider/src/test/java/io/apicurio/registry/content/refs/ProtobufReferenceFinderTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.content.refs; + +import java.util.Set; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.apicurio.registry.content.ContentHandle; +import io.apicurio.registry.rules.validity.ArtifactUtilProviderTestBase; + +/** + * @author eric.wittmann@gmail.com + */ +public class ProtobufReferenceFinderTest extends ArtifactUtilProviderTestBase { + + /** + * Test method for {@link io.apicurio.registry.content.refs.AsyncApiReferenceFinder#findExternalReferences(io.apicurio.registry.content.ContentHandle)}. + */ + @Test + public void testFindExternalReferences() { + ContentHandle content = resourceToContentHandle("protobuf-with-refs.proto"); + ProtobufReferenceFinder finder = new ProtobufReferenceFinder(); + Set foundReferences = finder.findExternalReferences(content); + Assertions.assertNotNull(foundReferences); + Assertions.assertEquals(3, foundReferences.size()); + Assertions.assertEquals(Set.of( + new ExternalReference("google/protobuf/timestamp.proto"), + new ExternalReference("sample/table_info.proto"), + new ExternalReference("sample/table_notification_type.proto")), foundReferences); + } + +} diff --git a/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/dereference/asyncapi-to-rewrite.json b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/dereference/asyncapi-to-rewrite.json new file mode 100644 index 0000000000..5d3d4c2658 --- /dev/null +++ b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/dereference/asyncapi-to-rewrite.json @@ -0,0 +1,33 @@ +{ + "asyncapi": "2.6.0", + "info": { + "title": "Account Service", + "version": "1.0.0", + "description": "This service is in charge of processing user signups" + }, + "channels": { + "user/signedup": { + "subscribe": { + "message": { + "$ref": "#/components/messages/UserSignedUp" + } + } + }, + "user/externalAvro": { + "subscribe": { + "message": { + "$ref": "./TradeKey.avsc" + } + } + } + }, + "components": { + "messages": { + "UserSignedUp": { + "payload": { + "$ref": "./common-types.json#/components/schemas/User" + } + } + } + } +} diff --git a/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/dereference/json-schema-to-rewrite.json b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/dereference/json-schema-to-rewrite.json new file mode 100644 index 0000000000..30969bfc3d --- /dev/null +++ b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/dereference/json-schema-to-rewrite.json @@ -0,0 +1,10 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "name": { "type": "string" }, + "age": { "type": "integer" }, + "address": { "$ref": "./address.json" }, + "ssn": { "$ref": "./ssn.json" } + } +} diff --git a/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/dereference/openapi-to-rewrite.json b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/dereference/openapi-to-rewrite.json new file mode 100644 index 0000000000..4ba2c9ba54 --- /dev/null +++ b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/dereference/openapi-to-rewrite.json @@ -0,0 +1,159 @@ +{ + "openapi": "3.0.2", + "info": { + "title": "Widget API (with refs)", + "version": "1.0.0" + }, + "paths": { + "/widgets": { + "summary": "Path used to manage the list of widgets.", + "description": "The REST endpoint/path used to list and create zero or more `Widget` entities. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively.", + "get": { + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Widget" + } + } + } + }, + "description": "Successful response - returns an array of `Widget` entities." + } + }, + "operationId": "getWidgets", + "summary": "List All Widgets", + "description": "Gets a list of all `Widget` entities." + }, + "post": { + "requestBody": { + "description": "A new `Widget` to be created.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Widget" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful response." + } + }, + "operationId": "createWidget", + "summary": "Create a Widget", + "description": "Creates a new instance of a `Widget`." + } + }, + "/widgets/{widgetId}": { + "summary": "Path used to manage a single Widget.", + "description": "The REST endpoint/path used to get, update, and delete single instances of an `Widget`. This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and delete tasks, respectively.", + "get": { + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Widget" + } + } + }, + "description": "Successful response - returns a single `Widget`." + } + }, + "operationId": "getWidget", + "summary": "Get a Widget", + "description": "Gets the details of a single instance of a `Widget`." + }, + "put": { + "requestBody": { + "description": "Updated `Widget` information.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Widget" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Successful response." + } + }, + "operationId": "updateWidget", + "summary": "Update a Widget", + "description": "Updates an existing `Widget`." + }, + "delete": { + "responses": { + "204": { + "description": "Successful response." + } + }, + "operationId": "deleteWidget", + "summary": "Delete a Widget", + "description": "Deletes an existing `Widget`." + }, + "parameters": [ + { + "name": "widgetId", + "description": "A unique identifier for a `Widget`.", + "schema": { + "type": "string" + }, + "in": "path", + "required": true + } + ] + } + }, + "components": { + "schemas": { + "Widget": { + "title": "Root Type for Widget", + "description": "", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "foo": { + "$ref": "#/components/schemas/Foo", + "properties": { + "prop-1": { + "type": "string" + }, + "prop-2": { + "type": "string" + } + } + } + }, + "example": { + "name": "...", + "description": "...", + "foo": { + "prop-1": "", + "prop-2": "" + } + } + }, + "Bar": { + "$ref": "./types/bar-types.json#/components/schemas/Bar" + }, + "Foo": { + "$ref": "./types/foo-types.json#/components/schemas/Foo" + } + } + } +} \ No newline at end of file diff --git a/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/asyncapi-with-refs.json b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/asyncapi-with-refs.json new file mode 100644 index 0000000000..5d3d4c2658 --- /dev/null +++ b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/asyncapi-with-refs.json @@ -0,0 +1,33 @@ +{ + "asyncapi": "2.6.0", + "info": { + "title": "Account Service", + "version": "1.0.0", + "description": "This service is in charge of processing user signups" + }, + "channels": { + "user/signedup": { + "subscribe": { + "message": { + "$ref": "#/components/messages/UserSignedUp" + } + } + }, + "user/externalAvro": { + "subscribe": { + "message": { + "$ref": "./TradeKey.avsc" + } + } + } + }, + "components": { + "messages": { + "UserSignedUp": { + "payload": { + "$ref": "./common-types.json#/components/schemas/User" + } + } + } + } +} diff --git a/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/avro-with-refs.avsc b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/avro-with-refs.avsc new file mode 100644 index 0000000000..20ab732e91 --- /dev/null +++ b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/avro-with-refs.avsc @@ -0,0 +1,23 @@ +{ + "namespace": "com.kubetrade.schema.trade", + "type": "record", + "name": "TradeRaw", + "fields": [ + { + "name": "tradeKey", + "type": "com.kubetrade.schema.trade.TradeKey" + }, + { + "name": "value", + "type": ["string", "com.kubetrade.schema.trade.TradeValue"] + }, + { + "name": "symbol", + "type": "string" + }, + { + "name": "payload", + "type": "string" + } + ] +} \ No newline at end of file diff --git a/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/json-schema-with-refs.json b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/json-schema-with-refs.json new file mode 100644 index 0000000000..30969bfc3d --- /dev/null +++ b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/json-schema-with-refs.json @@ -0,0 +1,10 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "name": { "type": "string" }, + "age": { "type": "integer" }, + "address": { "$ref": "./address.json" }, + "ssn": { "$ref": "./ssn.json" } + } +} diff --git a/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/openapi-with-refs.json b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/openapi-with-refs.json new file mode 100644 index 0000000000..4ba2c9ba54 --- /dev/null +++ b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/openapi-with-refs.json @@ -0,0 +1,159 @@ +{ + "openapi": "3.0.2", + "info": { + "title": "Widget API (with refs)", + "version": "1.0.0" + }, + "paths": { + "/widgets": { + "summary": "Path used to manage the list of widgets.", + "description": "The REST endpoint/path used to list and create zero or more `Widget` entities. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively.", + "get": { + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Widget" + } + } + } + }, + "description": "Successful response - returns an array of `Widget` entities." + } + }, + "operationId": "getWidgets", + "summary": "List All Widgets", + "description": "Gets a list of all `Widget` entities." + }, + "post": { + "requestBody": { + "description": "A new `Widget` to be created.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Widget" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful response." + } + }, + "operationId": "createWidget", + "summary": "Create a Widget", + "description": "Creates a new instance of a `Widget`." + } + }, + "/widgets/{widgetId}": { + "summary": "Path used to manage a single Widget.", + "description": "The REST endpoint/path used to get, update, and delete single instances of an `Widget`. This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and delete tasks, respectively.", + "get": { + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Widget" + } + } + }, + "description": "Successful response - returns a single `Widget`." + } + }, + "operationId": "getWidget", + "summary": "Get a Widget", + "description": "Gets the details of a single instance of a `Widget`." + }, + "put": { + "requestBody": { + "description": "Updated `Widget` information.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Widget" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Successful response." + } + }, + "operationId": "updateWidget", + "summary": "Update a Widget", + "description": "Updates an existing `Widget`." + }, + "delete": { + "responses": { + "204": { + "description": "Successful response." + } + }, + "operationId": "deleteWidget", + "summary": "Delete a Widget", + "description": "Deletes an existing `Widget`." + }, + "parameters": [ + { + "name": "widgetId", + "description": "A unique identifier for a `Widget`.", + "schema": { + "type": "string" + }, + "in": "path", + "required": true + } + ] + } + }, + "components": { + "schemas": { + "Widget": { + "title": "Root Type for Widget", + "description": "", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "foo": { + "$ref": "#/components/schemas/Foo", + "properties": { + "prop-1": { + "type": "string" + }, + "prop-2": { + "type": "string" + } + } + } + }, + "example": { + "name": "...", + "description": "...", + "foo": { + "prop-1": "", + "prop-2": "" + } + } + }, + "Bar": { + "$ref": "./types/bar-types.json#/components/schemas/Bar" + }, + "Foo": { + "$ref": "./types/foo-types.json#/components/schemas/Foo" + } + } + } +} \ No newline at end of file diff --git a/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/protobuf-with-refs.proto b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/protobuf-with-refs.proto new file mode 100644 index 0000000000..81cf94b6f3 --- /dev/null +++ b/schema-util/util-provider/src/test/resources/io/apicurio/registry/content/refs/protobuf-with-refs.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +option java_package = "io.api.sample"; +option java_multiple_files = true; + +import "google/protobuf/timestamp.proto"; +import "sample/table_info.proto"; +import "sample/table_notification_type.proto"; + +message TableNotification { + + google.protobuf.Timestamp timestamp = 1; + + string user = 2; + + string session_id = 3; + + sample.TableNotificationType table_notification_type = 4; + + sample.TableInfo table_info = 5; + +} \ No newline at end of file diff --git a/schema-util/wsdl/pom.xml b/schema-util/wsdl/pom.xml index 2065402124..b7555dcea3 100644 --- a/schema-util/wsdl/pom.xml +++ b/schema-util/wsdl/pom.xml @@ -6,7 +6,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/schema-util/xml/pom.xml b/schema-util/xml/pom.xml index b2d0e371a0..84f5137fae 100644 --- a/schema-util/xml/pom.xml +++ b/schema-util/xml/pom.xml @@ -6,7 +6,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/schema-util/xsd/pom.xml b/schema-util/xsd/pom.xml index 0d9f1b83c4..c88e7069f1 100644 --- a/schema-util/xsd/pom.xml +++ b/schema-util/xsd/pom.xml @@ -6,7 +6,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/serdes/avro-serde/pom.xml b/serdes/avro-serde/pom.xml index 6a5fb2d5d9..696e53bfad 100644 --- a/serdes/avro-serde/pom.xml +++ b/serdes/avro-serde/pom.xml @@ -7,7 +7,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/serdes/jsonschema-serde/pom.xml b/serdes/jsonschema-serde/pom.xml index d79ace08e1..673c4dcc13 100644 --- a/serdes/jsonschema-serde/pom.xml +++ b/serdes/jsonschema-serde/pom.xml @@ -5,7 +5,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/serdes/protobuf-serde/pom.xml b/serdes/protobuf-serde/pom.xml index fcc557c3eb..41760b92ca 100644 --- a/serdes/protobuf-serde/pom.xml +++ b/serdes/protobuf-serde/pom.xml @@ -5,7 +5,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/serdes/serde-common/pom.xml b/serdes/serde-common/pom.xml index d3e3b069c2..ed9b4782fe 100644 --- a/serdes/serde-common/pom.xml +++ b/serdes/serde-common/pom.xml @@ -7,7 +7,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/storage/kafkasql/pom.xml b/storage/kafkasql/pom.xml index 2def67d902..67ca0045a1 100644 --- a/storage/kafkasql/pom.xml +++ b/storage/kafkasql/pom.xml @@ -1,19 +1,19 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 io.apicurio apicurio-registry-storage - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml - + apicurio-registry-storage-kafkasql jar apicurio-registry-storage-kafkasql - + @@ -25,7 +25,7 @@ io.apicurio apicurio-registry-utils-kafka - + commons-codec @@ -35,10 +35,7 @@ commons-io commons-io - - io.strimzi - kafka-oauth-client - + org.testcontainers redpanda @@ -58,7 +55,7 @@ - + @@ -96,18 +93,23 @@ - unpack-app-dependencies - process-classes + unpack-static-resources + generate-resources - unpack-dependencies + unpack - io.apicurio - apicurio-common-app-components-config-index,apicurio-common-app-components-logging,apicurio-common-app-components-config-definitions,apicurio-common-app-components-config-impl,apicurio-common-app-components-core,apicurio-common-app-components-multitenancy - jar,maven-plugin - - ${project.build.directory}/classes - + + + ${project.groupId} + apicurio-registry-app + ${project.version} + jar + true + **/web.xml,**/application.properties + + + ${project.build.outputDirectory} false true @@ -225,7 +227,7 @@ - + no-slow-tests @@ -252,8 +254,11 @@ - ${project.build.directory}/${project.build.finalName}-runner - org.jboss.logmanager.LogManager + + ${project.build.directory}/${project.build.finalName}-runner + + org.jboss.logmanager.LogManager + ${maven.home} diff --git a/storage/kafkasql/src/main/resources/overlay.properties b/storage/kafkasql/src/main/resources/overlay.properties index 7b3ddf9d00..9d1f2772be 100644 --- a/storage/kafkasql/src/main/resources/overlay.properties +++ b/storage/kafkasql/src/main/resources/overlay.properties @@ -70,5 +70,5 @@ registry.name=Apicurio Registry (Kafka+SQL) %prod.registry.kafkasql.ssl.keystore.password=${KAFKA_SSL_KEYSTORE_PASSWORD:} %prod.registry.kafkasql.ssl.key.password=${KAFKA_SSL_KEY_PASSWORD:} - +quarkus.native.resources.includes=i18n/*.properties quarkus.native.additional-build-args=--initialize-at-run-time=org.apache.kafka.common.security.authenticator.SaslClientAuthenticator diff --git a/storage/mssql/pom.xml b/storage/mssql/pom.xml index 66218bdc39..ff3a87b219 100644 --- a/storage/mssql/pom.xml +++ b/storage/mssql/pom.xml @@ -1,10 +1,11 @@ - + 4.0.0 io.apicurio apicurio-registry-storage - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml @@ -70,18 +71,23 @@ maven-dependency-plugin - unpack-app-dependencies - process-classes + unpack-static-resources + generate-resources - unpack-dependencies + unpack - apicurio-common-app-components-config-index,apicurio-common-app-components-logging,apicurio-common-app-components-config-definitions,apicurio-common-app-components-config-impl,apicurio-common-app-components-core,apicurio-common-app-components-multitenancy - io.apicurio - jar,maven-plugin - - ${project.build.directory}/classes - + + + ${project.groupId} + apicurio-registry-app + ${project.version} + jar + true + **/web.xml,**/application.properties + + + ${project.build.outputDirectory} false true diff --git a/storage/mssql/src/main/resources/overlay.properties b/storage/mssql/src/main/resources/overlay.properties index 095cdbcd88..25f9ee458a 100644 --- a/storage/mssql/src/main/resources/overlay.properties +++ b/storage/mssql/src/main/resources/overlay.properties @@ -1,4 +1,4 @@ -quarkus.native.resources.includes=io/apicurio/registry/storage/impl/sql/mssql.ddl,io/apicurio/registry/storage/impl/sql/upgrades/**/*.ddl +quarkus.native.resources.includes=io/apicurio/registry/storage/impl/sql/mssql.ddl,io/apicurio/registry/storage/impl/sql/upgrades/**/*.ddl,i18n/*.properties registry.name=Apicurio Registry (MS SQL Server) diff --git a/storage/mysql/pom.xml b/storage/mysql/pom.xml index 1f46cc456d..f2cde4f936 100644 --- a/storage/mysql/pom.xml +++ b/storage/mysql/pom.xml @@ -111,18 +111,25 @@ ${apicurio-common-app-components.version} - merge-properties - process-classes + unpack-static-resources + generate-resources - merge + unpack - ${project.build.outputDirectory}/application.properties - - ${project.build.outputDirectory}/application.properties - ${project.build.outputDirectory}/overlay.properties - - true + + + ${project.groupId} + apicurio-registry-app + ${project.version} + jar + true + **/web.xml,**/application.properties + + + ${project.build.outputDirectory} + false + true diff --git a/storage/pom.xml b/storage/pom.xml index 6ebe8f8238..6fb54db53b 100644 --- a/storage/pom.xml +++ b/storage/pom.xml @@ -4,7 +4,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml apicurio-registry-storage @@ -86,8 +86,8 @@ test-jar - io.strimzi - strimzi-test-container + org.testcontainers + redpanda test diff --git a/storage/sql/pom.xml b/storage/sql/pom.xml index 7dbabfc41c..ee98a568f5 100644 --- a/storage/sql/pom.xml +++ b/storage/sql/pom.xml @@ -1,15 +1,15 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 io.apicurio apicurio-registry-storage - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml - + apicurio-registry-storage-sql jar apicurio-registry-storage-sql @@ -56,7 +56,7 @@ - + @@ -76,18 +76,23 @@ maven-dependency-plugin - unpack-app-dependencies - process-classes + unpack-static-resources + generate-resources - unpack-dependencies + unpack - apicurio-common-app-components-config-index,apicurio-common-app-components-logging,apicurio-common-app-components-config-definitions,apicurio-common-app-components-config-impl,apicurio-common-app-components-core,apicurio-common-app-components-multitenancy - io.apicurio - jar,maven-plugin - - ${project.build.directory}/classes - + + + ${project.groupId} + apicurio-registry-app + ${project.version} + jar + true + **/web.xml,**/application.properties + + + ${project.build.outputDirectory} false true @@ -206,7 +211,7 @@ - + no-docker @@ -239,8 +244,11 @@ - ${project.build.directory}/${project.build.finalName}-runner - org.jboss.logmanager.LogManager + + ${project.build.directory}/${project.build.finalName}-runner + + org.jboss.logmanager.LogManager + ${maven.home} diff --git a/storage/sql/src/main/resources/overlay.properties b/storage/sql/src/main/resources/overlay.properties index da434b8def..1332c6ec49 100644 --- a/storage/sql/src/main/resources/overlay.properties +++ b/storage/sql/src/main/resources/overlay.properties @@ -1,4 +1,4 @@ -quarkus.native.resources.includes=io/apicurio/registry/storage/impl/sql/postgresql.ddl,io/apicurio/registry/storage/impl/sql/upgrades/**/*.ddl +quarkus.native.resources.includes=io/apicurio/registry/storage/impl/sql/postgresql.ddl,io/apicurio/registry/storage/impl/sql/upgrades/**/*.ddl,i18n/*.properties registry.name=Apicurio Registry (SQL) diff --git a/storage/sql/src/test/java/io/apicurio/registry/storage/util/SqlStorageTestResources.java b/storage/sql/src/test/java/io/apicurio/registry/storage/util/SqlStorageTestResources.java index 5e8db644d7..47c7696bbf 100644 --- a/storage/sql/src/test/java/io/apicurio/registry/storage/util/SqlStorageTestResources.java +++ b/storage/sql/src/test/java/io/apicurio/registry/storage/util/SqlStorageTestResources.java @@ -16,6 +16,7 @@ package io.apicurio.registry.storage.util; +import io.apicurio.registry.utils.tests.PostgreSqlEmbeddedTestResource; import io.quarkus.test.common.QuarkusTestResource; /** diff --git a/system-tests/pom.xml b/system-tests/pom.xml index ed9271239d..4a624abb94 100644 --- a/system-tests/pom.xml +++ b/system-tests/pom.xml @@ -5,7 +5,7 @@ apicurio-registry io.apicurio - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT 4.0.0 @@ -18,9 +18,9 @@ 5.8.2 1.7.0 5.12.2 - 6.9.0 - 0.101.0 - 1.18.30 + 6.8.0 + 0.95.0 + 1.18.28 1.0.0-v2.0.0.final 2.2 2.0.9 diff --git a/ui/package-lock.json b/ui/package-lock.json index 46a916c80f..eceaab66b1 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -20978,9 +20978,9 @@ "license": "MIT" }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "engines": { "node": ">=0.10.0" } @@ -36827,9 +36827,9 @@ "dev": true }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==" }, "wrap-ansi": { "version": "7.0.0", diff --git a/ui/pom.xml b/ui/pom.xml index fff05a0f32..d38c692fe2 100644 --- a/ui/pom.xml +++ b/ui/pom.xml @@ -5,7 +5,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../pom.xml diff --git a/utils/converter/pom.xml b/utils/converter/pom.xml index a08b94e600..85153be0e7 100644 --- a/utils/converter/pom.xml +++ b/utils/converter/pom.xml @@ -7,7 +7,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/utils/exportConfluent/pom.xml b/utils/exportConfluent/pom.xml index 6a5ddab77e..fa3b30d59c 100644 --- a/utils/exportConfluent/pom.xml +++ b/utils/exportConfluent/pom.xml @@ -7,7 +7,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/utils/exportV1/pom.xml b/utils/exportV1/pom.xml index b5d3ed6bf9..530fe5ab20 100644 --- a/utils/exportV1/pom.xml +++ b/utils/exportV1/pom.xml @@ -7,7 +7,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/utils/importexport/pom.xml b/utils/importexport/pom.xml index 939c85071e..930991ba03 100644 --- a/utils/importexport/pom.xml +++ b/utils/importexport/pom.xml @@ -7,7 +7,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/utils/kafka/pom.xml b/utils/kafka/pom.xml index eefc8ccae0..0634a42c72 100644 --- a/utils/kafka/pom.xml +++ b/utils/kafka/pom.xml @@ -7,7 +7,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml @@ -27,20 +27,24 @@ kafka-clients - io.strimzi - strimzi-test-container - test + org.slf4j + slf4j-api - org.testcontainers - redpanda - test + org.jboss.slf4j + slf4j-jboss-logging + ${jboss-slf4j.version} io.quarkus quarkus-test-common test + + org.testcontainers + redpanda + test + org.junit.jupiter junit-jupiter diff --git a/utils/kafka/src/test/java/io/apicurio/registry/test/utils/KafkaTestContainerManager.java b/utils/kafka/src/test/java/io/apicurio/registry/test/utils/KafkaTestContainerManager.java index a1d7566b89..4afd154d37 100644 --- a/utils/kafka/src/test/java/io/apicurio/registry/test/utils/KafkaTestContainerManager.java +++ b/utils/kafka/src/test/java/io/apicurio/registry/test/utils/KafkaTestContainerManager.java @@ -27,6 +27,7 @@ /** * @author Fabian Martinez Gonzalez * @author Ales Justin + * @author Carles Arnal */ public class KafkaTestContainerManager implements QuarkusTestResourceLifecycleManager { private static final Logger log = LoggerFactory.getLogger(KafkaTestContainerManager.class); @@ -36,19 +37,21 @@ public class KafkaTestContainerManager implements QuarkusTestResourceLifecycleMa @Override public Map start() { log.info("Starting the Kafka Test Container"); - kafka = new RedpandaContainer("docker.redpanda.com/vectorized/redpanda:v22.2.1"); + kafka = new RedpandaContainer("docker.redpanda.com/vectorized/redpanda"); + kafka.addEnv("KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR", "1"); kafka.addEnv("KAFKA_TRANSACTION_STATE_LOG_MIN_ISR", "1"); kafka.withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("kafka-testcontainer"))); - kafka.start(); String bootstrapServers = kafka.getBootstrapServers(); + System.setProperty("bootstrap.servers", bootstrapServers); + return Map.of( - "bootstrap.servers", bootstrapServers, - "registry.events.kafka.config.bootstrap.servers", bootstrapServers, - "registry.kafkasql.bootstrap.servers", bootstrapServers); + "bootstrap.servers", bootstrapServers, + "registry.events.kafka.config.bootstrap.servers", bootstrapServers, + "registry.kafkasql.bootstrap.servers", bootstrapServers); } @Override diff --git a/utils/maven-plugin/pom.xml b/utils/maven-plugin/pom.xml index 99a920305a..873d02e3b9 100644 --- a/utils/maven-plugin/pom.xml +++ b/utils/maven-plugin/pom.xml @@ -7,7 +7,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml @@ -50,17 +50,9 @@ commons-io commons-io - - commons-io - commons-io - - - io.apicurio - apicurio-registry-protobuf-schema-utilities - io.apicurio - apicurio-registry-schema-util-json + apicurio-registry-schema-util-provider diff --git a/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/ExistingReference.java b/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/ExistingReference.java new file mode 100644 index 0000000000..4f7503417a --- /dev/null +++ b/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/ExistingReference.java @@ -0,0 +1,90 @@ +/* + * Copyright 2021 Red Hat + * + * Licensed 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 io.apicurio.registry.maven; + +/** + * @author eric.wittmann@gmail.com + */ +public class ExistingReference { + + private String resourceName; + private String groupId; + private String artifactId; + private String version; + + /** + * Constructor. + */ + public ExistingReference() { + } + + /** + * @return the groupId + */ + public String getGroupId() { + return groupId; + } + + /** + * @param groupId the groupId to set + */ + public void setGroupId(String groupId) { + this.groupId = groupId; + } + + /** + * @return the artifactId + */ + public String getArtifactId() { + return artifactId; + } + + /** + * @param artifactId the artifactId to set + */ + public void setArtifactId(String artifactId) { + this.artifactId = artifactId; + } + + /** + * @return the resourceName + */ + public String getResourceName() { + return resourceName; + } + + /** + * @param resourceName the resourceName to set + */ + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + /** + * @return the version + */ + public String getVersion() { + return version; + } + + /** + * @param version the version to set + */ + public void setVersion(String version) { + this.version = version; + } +} diff --git a/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/RegisterArtifact.java b/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/RegisterArtifact.java index 1eedf83b2b..66e3e0fc21 100644 --- a/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/RegisterArtifact.java +++ b/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/RegisterArtifact.java @@ -35,8 +35,10 @@ public class RegisterArtifact { private Boolean canonicalize; private Boolean minify; private Boolean analyzeDirectory; + private Boolean autoRefs; private String contentType; private List references; + private List existingReferences; /** * Constructor. @@ -191,4 +193,20 @@ public Boolean getAnalyzeDirectory() { public void setAnalyzeDirectory(Boolean analyzeDirectory) { this.analyzeDirectory = analyzeDirectory; } + + public Boolean getAutoRefs() { + return autoRefs; + } + + public void setAutoRefs(Boolean autoRefs) { + this.autoRefs = autoRefs; + } + + public List getExistingReferences() { + return existingReferences; + } + + public void setExistingReferences(List existingReferences) { + this.existingReferences = existingReferences; + } } diff --git a/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/RegisterRegistryMojo.java b/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/RegisterRegistryMojo.java index d6c9e4d4d9..340d332266 100644 --- a/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/RegisterRegistryMojo.java +++ b/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/RegisterRegistryMojo.java @@ -17,26 +17,44 @@ package io.apicurio.registry.maven; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.Stack; +import java.util.stream.Collectors; + +import org.apache.avro.Schema; +import org.apache.commons.io.FileUtils; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.protobuf.Descriptors.FileDescriptor; + +import io.apicurio.registry.content.ContentHandle; +import io.apicurio.registry.content.refs.ExternalReference; +import io.apicurio.registry.content.refs.ReferenceFinder; +import io.apicurio.registry.maven.refs.IndexedResource; +import io.apicurio.registry.maven.refs.ReferenceIndex; import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; import io.apicurio.registry.rest.v2.beans.ArtifactReference; import io.apicurio.registry.rest.v2.beans.IfExists; import io.apicurio.registry.types.ArtifactType; import io.apicurio.registry.types.ContentTypes; -import org.apache.avro.Schema; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; - -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; +import io.apicurio.registry.types.provider.ArtifactTypeUtilProvider; +import io.apicurio.registry.types.provider.DefaultArtifactTypeUtilProviderImpl; /** * Register artifacts against registry. @@ -46,11 +64,19 @@ @Mojo(name = "register") public class RegisterRegistryMojo extends AbstractRegistryMojo { + /** + * The list of pre-registered artifacts that can be used as references. + */ + @Parameter(required = true) + List existingReferences; + /** * The list of artifacts to register. */ @Parameter(required = true) List artifacts; + + DefaultArtifactTypeUtilProviderImpl utilProviderFactory = new DefaultArtifactTypeUtilProviderImpl(); /** * Validate the configuration. @@ -98,8 +124,15 @@ protected void executeInternal() throws MojoExecutionException { String groupId = artifact.getGroupId(); String artifactId = artifact.getArtifactId(); try { + if (artifact.getAutoRefs() != null && artifact.getAutoRefs()) { + // If we have references, then we'll need to create the local resource index and then process all refs. + ReferenceIndex index = createIndex(artifact.getFile()); + addExistingReferencesToIndex(index, existingReferences); + addExistingReferencesToIndex(index, artifact.getExistingReferences()); + Stack registrationStack = new Stack<>(); - if (artifact.getAnalyzeDirectory() != null && artifact.getAnalyzeDirectory()) { //Auto register selected, we must figure out if the artifact has reference using the directory structure + registerWithAutoRefs(artifact, index, registrationStack); + } else if (artifact.getAnalyzeDirectory() != null && artifact.getAnalyzeDirectory()) { //Auto register selected, we must figure out if the artifact has reference using the directory structure registerDirectory(artifact); } else { @@ -123,6 +156,59 @@ protected void executeInternal() throws MojoExecutionException { } } + private ArtifactMetaData registerWithAutoRefs(RegisterArtifact artifact, ReferenceIndex index, Stack registrationStack) throws IOException { + if (loopDetected(artifact, registrationStack)) { + throw new RuntimeException("Artifact reference loop detected (not supported): " + printLoop(registrationStack)); + } + registrationStack.push(artifact); + + // Read the artifact content. + ContentHandle artifactContent = readContent(artifact.getFile()); + + // Find all references in the content + ArtifactTypeUtilProvider provider = this.utilProviderFactory.getArtifactTypeProvider(artifact.getType()); + ReferenceFinder referenceFinder = provider.getReferenceFinder(); + Set externalReferences = referenceFinder.findExternalReferences(artifactContent); + + // Register all of the references first, then register the artifact. + List registeredReferences = externalReferences.stream().map(externalRef -> { + IndexedResource iresource = index.lookup(externalRef.getResource(), Paths.get(artifact.getFile().toURI())); + + // TODO: need a way to resolve references that are not local (already registered in the registry) + if (iresource == null) { + throw new RuntimeException("Reference could not be resolved. From: " + artifact.getFile().getName() + " To: " + externalRef.getFullReference()); + } + + // If the resource isn't already registered, then register it now. + if (!iresource.isRegistered()) { + // TODO: determine the artifactId better (type-specific logic here?) + String artifactId = externalRef.getResource(); + File localFile = getLocalFile(iresource.getPath()); + RegisterArtifact refArtifact = buildFromRoot(artifact, artifactId); + refArtifact.setType(iresource.getType()); + refArtifact.setVersion(null); + refArtifact.setFile(localFile); + refArtifact.setContentType(getContentTypeByExtension(localFile.getName())); + try { + ArtifactMetaData amd = registerWithAutoRefs(refArtifact, index, registrationStack); + iresource.setRegistration(amd); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + return new ArtifactReference( + iresource.getRegistration().getGroupId(), + iresource.getRegistration().getId(), + iresource.getRegistration().getVersion(), + externalRef.getFullReference()); + + }).sorted((ref1, ref2) -> ref1.getName().compareTo(ref2.getName())).collect(Collectors.toList()); + + registrationStack.pop(); + return registerArtifact(artifact, registeredReferences); + } + private void registerDirectory(RegisterArtifact artifact) throws IOException { switch (artifact.getType()) { case ArtifactType.AVRO: @@ -172,8 +258,7 @@ private ArtifactMetaData registerArtifact(RegisterArtifact artifact, InputStream return amd; } - - private boolean hasReferences(RegisterArtifact artifact) { + private static boolean hasReferences(RegisterArtifact artifact) { return artifact.getReferences() != null && !artifact.getReferences().isEmpty(); } @@ -192,7 +277,11 @@ private boolean hasReferences(RegisterArtifact artifact) { return references; } - private ArtifactReference buildReferenceFromMetadata(ArtifactMetaData amd, String referenceName) { + public void setArtifacts(List artifacts) { + this.artifacts = artifacts; + } + + private static ArtifactReference buildReferenceFromMetadata(ArtifactMetaData amd, String referenceName) { ArtifactReference reference = new ArtifactReference(); reference.setName(referenceName); reference.setArtifactId(amd.getId()); @@ -201,15 +290,78 @@ private ArtifactReference buildReferenceFromMetadata(ArtifactMetaData amd, Strin return reference; } - private String contentType(RegisterArtifact registerArtifact) { - String contentType = registerArtifact.getContentType(); - if (contentType != null) { - return contentType; + /** + * Create a local index relative to the given file location. + * @param file + */ + private static ReferenceIndex createIndex(File file) { + ReferenceIndex index = new ReferenceIndex(file.getParentFile().toPath()); + Collection allFiles = FileUtils.listFiles(file.getParentFile(), null, true); + allFiles.stream().filter(f -> f.isFile()).forEach(f -> { + index.index(f.toPath(), readContent(f)); + }); + return index; + } + + private void addExistingReferencesToIndex(ReferenceIndex index, List existingReferences) { + if (existingReferences != null && !existingReferences.isEmpty()) { + existingReferences.forEach(ref -> { + ArtifactMetaData amd; + if (ref.getVersion() == null || "LATEST".equalsIgnoreCase(ref.getVersion())) { + amd = getClient().getArtifactMetaData(ref.getGroupId(), ref.getArtifactId()); + } else { + amd = new ArtifactMetaData(); + amd.setGroupId(ref.getGroupId()); + amd.setId(ref.getArtifactId()); + amd.setVersion(ref.getVersion()); + } + index.index(ref.getResourceName(), amd); + }); } - return getContentTypeByExtension(registerArtifact.getFile().getName()); } - public void setArtifacts(List artifacts) { - this.artifacts = artifacts; + protected static ContentHandle readContent(File file) { + try { + return ContentHandle.create(Files.readAllBytes(file.toPath())); + } catch (IOException e) { + throw new RuntimeException("Failed to read schema file: " + file, e); + } + } + + protected static RegisterArtifact buildFromRoot(RegisterArtifact rootArtifact, String artifactId) { + RegisterArtifact nestedSchema = new RegisterArtifact(); + nestedSchema.setCanonicalize(rootArtifact.getCanonicalize()); + nestedSchema.setArtifactId(artifactId); + nestedSchema.setGroupId(rootArtifact.getGroupId()); + nestedSchema.setContentType(rootArtifact.getContentType()); + nestedSchema.setType(rootArtifact.getType()); + nestedSchema.setMinify(rootArtifact.getMinify()); + nestedSchema.setContentType(rootArtifact.getContentType()); + nestedSchema.setIfExists(rootArtifact.getIfExists()); + nestedSchema.setAutoRefs(rootArtifact.getAutoRefs()); + return nestedSchema; + } + + private static File getLocalFile(Path path) { + return path.toFile(); + } + + /** + * Detects a loop by looking for the given artifact in the registration stack. + * @param artifact + * @param registrationStack + */ + private static boolean loopDetected(RegisterArtifact artifact, Stack registrationStack) { + for (RegisterArtifact stackArtifact : registrationStack) { + if (artifact.getFile().equals(stackArtifact.getFile())) { + return true; + } + } + return false; + } + + private static String printLoop(Stack registrationStack) { + return registrationStack.stream().map(artifact -> artifact.getFile().getName()).collect(Collectors.joining(" -> ")); } + } diff --git a/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/refs/IndexedResource.java b/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/refs/IndexedResource.java new file mode 100644 index 0000000000..ca272964d4 --- /dev/null +++ b/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/refs/IndexedResource.java @@ -0,0 +1,122 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.maven.refs; + +import java.nio.file.Path; +import java.util.Set; + +import io.apicurio.registry.content.ContentHandle; +import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; +import io.apicurio.registry.types.ArtifactType; + +/** + * @author eric.wittmann@gmail.com + */ +public class IndexedResource { + + private final Path path; + private final String type; + private final String resourceName; + private final ContentHandle content; + private ArtifactMetaData registration; + + /** + * Constructor. + * @param path + * @param type + * @param resourceName + * @param content + */ + public IndexedResource(Path path, String type, String resourceName, ContentHandle content) { + super(); + this.path = path; + this.content = content; + this.type = type; + this.resourceName = resourceName; + } + + /** + * @return the content + */ + public ContentHandle getContent() { + return content; + } + + /** + * @return the type + */ + public String getType() { + return type; + } + + /** + * @return the resourceName + */ + public String getResourceName() { + return resourceName; + } + + /** + * @return the path + */ + public Path getPath() { + return path; + } + + public boolean matches(String resourceName, Path relativeToFile, Set schemaPaths) { + // If this is a pre-registered reference, the match has to happen by resource name. + if (this.path == null) { + return this.resourceName.equals(resourceName); + } + + // For Avro files the match can happen either via path (e.g. when referencing an Avro + // file from an AsyncAPI file) or via resource name (e.g. from Avro to Avro). + if (ArtifactType.AVRO.equals(this.type)) { + if (this.resourceName.equals(resourceName)) { + return true; + } + } + + // The resource name will otherwise be a relative path to the resource. + Path resolvedPath = relativeToFile.getParent().resolve(resourceName); + boolean resolves = this.path.normalize().equals(resolvedPath.normalize()); + + // Protobuf can resolve relative to the "schema paths" (aka --proto-paths in protoc). + if (!resolves && ArtifactType.PROTOBUF.equals(this.type)) { + resolves = schemaPaths.parallelStream().anyMatch(path -> this.path.normalize().equals(path.resolve(resourceName).normalize())); + } + return resolves; + } + + /** + * @return the registration + */ + public ArtifactMetaData getRegistration() { + return registration; + } + + /** + * @param registration the registration to set + */ + public void setRegistration(ArtifactMetaData registration) { + this.registration = registration; + } + + public boolean isRegistered() { + return this.registration != null; + } +} diff --git a/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/refs/ReferenceIndex.java b/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/refs/ReferenceIndex.java new file mode 100644 index 0000000000..332d12a195 --- /dev/null +++ b/utils/maven-plugin/src/main/java/io/apicurio/registry/maven/refs/ReferenceIndex.java @@ -0,0 +1,170 @@ +/* + * Copyright 2023 Red Hat Inc + * + * Licensed 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 io.apicurio.registry.maven.refs; + +import java.nio.file.Path; +import java.util.HashSet; +import java.util.Set; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.apicurio.datamodels.Library; +import io.apicurio.datamodels.models.Document; +import io.apicurio.datamodels.util.ModelTypeUtil; +import io.apicurio.registry.content.ContentHandle; +import io.apicurio.registry.rest.v2.beans.ArtifactMetaData; +import io.apicurio.registry.types.ArtifactType; +import io.apicurio.registry.utils.protobuf.schema.ProtobufFile; + +/** + * An index of the files available when discovering references in an artifact. This index is + * typically populated by getting a list of all files in a directory, or zip file. + * + * The index maps a resource name (this will vary depending on the artifact type) to the + * content of the resource. For example, Avro schemas will have resource names based on the + * qualified name of the type they define. JSON Schemas will have resources names based on + * the name of the file. + * + * The intent of this index is to resolve an external reference found in an artifact to an + * actual piece of content (e.g. file) in the index. If it cannot be resolved, that would + * typically mean that there is a broken reference in the schema/design. + * + * @author eric.wittmann@gmail.com + */ +public class ReferenceIndex { + + private static final ObjectMapper mapper = new ObjectMapper(); + + private Set index = new HashSet<>(); + private Set schemaPaths = new HashSet<>(); + + /** + * Constructor. + */ + public ReferenceIndex() { + } + + /** + * Constructor. + * @param schemaPath + */ + public ReferenceIndex(Path schemaPath) { + this.schemaPaths.add(schemaPath); + } + + /** + * @param path + */ + public void addSchemaPath(Path path) { + this.schemaPaths.add(path); + } + + /** + * Look up a resource in the index. Returns null if no resource with that + * name is found. + * @param resourceName + * @param relativeToFile + */ + public IndexedResource lookup(String resourceName, Path relativeToFile) { + return index.stream().filter(resource -> resource.matches(resourceName, relativeToFile, schemaPaths)).findFirst().orElse(null); + } + + /** + * Index an existing (remote) reference using a resource name and remote artifact metadata. + * @param resourceName + * @param amd + */ + public void index(String resourceName, ArtifactMetaData amd) { + IndexedResource res = new IndexedResource(null, null, resourceName, null); + res.setRegistration(amd); + this.index.add(res); + } + + /** + * Index the given content. Indexing will parse the content and figure out its resource + * name and type. + * @param path + * @param content + */ + public void index(Path path, ContentHandle content) { + try { + JsonNode tree = mapper.readTree(content.content()); + + // OpenAPI + if (tree.has("openapi") || tree.has("swagger") || tree.has("asyncapi")) { + indexDataModels(path, content); + } + // JSON Schema + if (tree.has("$schema") && !tree.get("$schema").isNull()) { + indexJsonSchema(tree, path, content); + } + // Avro + indexAvro(path, content, tree); + } catch (Exception e) { + // Must not be JSON... + } + + try { + indexProto(path, content); + return; + } catch (Exception e) { + // I guess it's not Protobuf. + } + } + + private void indexAvro(Path path, ContentHandle content, JsonNode parsed) { + // TODO: is namespace required for an Avro schema? + String ns = parsed.get("namespace").asText(); + String name = parsed.get("name").asText(); + String resourceName = ns != null ? ns + "." + name : name; + IndexedResource resource = new IndexedResource(path, ArtifactType.AVRO, resourceName, content); + this.index.add(resource); + } + + private void indexProto(Path path, ContentHandle content) { + ProtobufFile.toProtoFileElement(content.content()); + + IndexedResource resource = new IndexedResource(path, ArtifactType.PROTOBUF, null, content); + this.index.add(resource); + } + + private void indexJsonSchema(JsonNode schema, Path path, ContentHandle content) { + String resourceName = null; + if (schema.has("$id")) { + resourceName = schema.get("$id").asText(null); + } + IndexedResource resource = new IndexedResource(path, ArtifactType.JSON, resourceName, content); + this.index.add(resource); + } + + private void indexDataModels(Path path, ContentHandle content) { + Document doc = Library.readDocumentFromJSONString(content.content()); + if (doc == null) { + throw new UnsupportedOperationException("Content is not OpenAPI or AsyncAPI."); + } + + String type = ArtifactType.OPENAPI; + if (ModelTypeUtil.isAsyncApiModel(doc)) { + type = ArtifactType.ASYNCAPI; + } + + IndexedResource resource = new IndexedResource(path, type, null, content); + this.index.add(resource); + } + +} diff --git a/utils/protobuf-schema-utilities/pom.xml b/utils/protobuf-schema-utilities/pom.xml index 0e7681d53a..322440791d 100644 --- a/utils/protobuf-schema-utilities/pom.xml +++ b/utils/protobuf-schema-utilities/pom.xml @@ -5,7 +5,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml diff --git a/utils/protobuf-schema-utilities/src/main/java/io/apicurio/registry/utils/protobuf/schema/FileDescriptorUtils.java b/utils/protobuf-schema-utilities/src/main/java/io/apicurio/registry/utils/protobuf/schema/FileDescriptorUtils.java index 19b089cd03..294ed82afd 100644 --- a/utils/protobuf-schema-utilities/src/main/java/io/apicurio/registry/utils/protobuf/schema/FileDescriptorUtils.java +++ b/utils/protobuf-schema-utilities/src/main/java/io/apicurio/registry/utils/protobuf/schema/FileDescriptorUtils.java @@ -34,18 +34,7 @@ import com.squareup.wire.schema.Schema; import com.squareup.wire.schema.Service; import com.squareup.wire.schema.Type; -import com.squareup.wire.schema.internal.parser.EnumConstantElement; -import com.squareup.wire.schema.internal.parser.EnumElement; -import com.squareup.wire.schema.internal.parser.ExtensionsElement; -import com.squareup.wire.schema.internal.parser.FieldElement; -import com.squareup.wire.schema.internal.parser.MessageElement; -import com.squareup.wire.schema.internal.parser.OneOfElement; -import com.squareup.wire.schema.internal.parser.OptionElement; -import com.squareup.wire.schema.internal.parser.ProtoFileElement; -import com.squareup.wire.schema.internal.parser.ReservedElement; -import com.squareup.wire.schema.internal.parser.RpcElement; -import com.squareup.wire.schema.internal.parser.ServiceElement; -import com.squareup.wire.schema.internal.parser.TypeElement; +import com.squareup.wire.schema.internal.parser.*; import kotlin.ranges.IntRange; import metadata.ProtobufSchemaMetadata; import additionalTypes.Decimals; @@ -640,7 +629,7 @@ private static String determineFieldType(ProtoType protoType, Schema schema) { * This method generates the synthetic one-of from a Proto3 optional field. */ private static OneOf getProto3OptionalField(Field field) { - return new OneOf("_" + field.getName(), "", Collections.singletonList(field)); + return new OneOf("_" + field.getName(), "", Collections.singletonList(field), field.getLocation(), field.getOptions()); } private static EnumDescriptorProto enumElementToProto(EnumType enumElem) { @@ -922,17 +911,18 @@ private static MessageElement toMessage(FileDescriptorProto file, DescriptorProt descriptor.getOptions().getNoStandardDescriptorAccessor(), false); options.add(option); } + return new MessageElement(DEFAULT_LOCATION, name, "", nested.build(), options.build(), reserved.build(), fields.build(), oneofs.stream() //Ignore oneOfs with no fields (like Proto3 Optional) .filter(e -> e.getValue().build().size() != 0) .map(e -> toOneof(e.getKey(), e.getValue())).collect(Collectors.toList()), - extensions.build(), Collections.emptyList()); + extensions.build(), Collections.emptyList(), Collections.emptyList()); } private static OneOfElement toOneof(String name, ImmutableList.Builder fields) { - return new OneOfElement(name, "", fields.build(), Collections.emptyList(), Collections.emptyList()); + return new OneOfElement(name, "", fields.build(), Collections.emptyList(), Collections.emptyList(), DEFAULT_LOCATION); } private static EnumElement toEnum(EnumDescriptorProto ed) { diff --git a/utils/tests/pom.xml b/utils/tests/pom.xml index d239acbd5c..f01e4ca7df 100644 --- a/utils/tests/pom.xml +++ b/utils/tests/pom.xml @@ -7,7 +7,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml @@ -52,14 +52,14 @@ - com.github.dasniko - testcontainers-keycloak + org.keycloak + keycloak-admin-client-jakarta provided - org.keycloak - keycloak-admin-client-jakarta + io.zonky.test + embedded-postgres provided diff --git a/utils/tests/src/main/java/io/apicurio/registry/utils/tests/AuthTestProfile.java b/utils/tests/src/main/java/io/apicurio/registry/utils/tests/AuthTestProfile.java index dc76d5f150..1bf2782563 100644 --- a/utils/tests/src/main/java/io/apicurio/registry/utils/tests/AuthTestProfile.java +++ b/utils/tests/src/main/java/io/apicurio/registry/utils/tests/AuthTestProfile.java @@ -17,6 +17,7 @@ import io.quarkus.test.junit.QuarkusTestProfile; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -32,8 +33,11 @@ public Map getConfigOverrides() { @Override public List testResources() { - return List.of( - new TestResourceEntry(JWKSMockServer.class)); + if (!Boolean.parseBoolean(System.getProperty("cluster.tests"))) { + return List.of( + new TestResourceEntry(JWKSMockServer.class)); + } else { + return Collections.emptyList(); + } } - } diff --git a/utils/tests/src/main/java/io/apicurio/registry/utils/tests/JWKSMockServer.java b/utils/tests/src/main/java/io/apicurio/registry/utils/tests/JWKSMockServer.java index 0f48c3a149..198f7ff993 100644 --- a/utils/tests/src/main/java/io/apicurio/registry/utils/tests/JWKSMockServer.java +++ b/utils/tests/src/main/java/io/apicurio/registry/utils/tests/JWKSMockServer.java @@ -44,7 +44,7 @@ public class JWKSMockServer implements QuarkusTestResourceLifecycleManager { private WireMockServer server; public String authServerUrl; - public String realm = "test"; + public String realm = "registry"; public String tokenEndpoint; public static String ADMIN_CLIENT_ID = "admin-client"; @@ -53,7 +53,7 @@ public class JWKSMockServer implements QuarkusTestResourceLifecycleManager { public static String READONLY_CLIENT_ID = "readonly-client"; public static String NO_ROLE_CLIENT_ID = "no-role-client"; - public static String WRONG_CREDS_CLIENT_ID = "wrong-creds-client"; + public static String WRONG_CREDS_CLIENT_ID = "wrong-client"; public static String BASIC_USER = "sr-test-user"; public static String BASIC_PASSWORD = "sr-test-password"; diff --git a/utils/tests/src/main/java/io/apicurio/registry/utils/tests/MultitenancyNoAuthTestProfile.java b/utils/tests/src/main/java/io/apicurio/registry/utils/tests/MultitenancyNoAuthTestProfile.java new file mode 100644 index 0000000000..75a84e158d --- /dev/null +++ b/utils/tests/src/main/java/io/apicurio/registry/utils/tests/MultitenancyNoAuthTestProfile.java @@ -0,0 +1,40 @@ +/* + * Copyright 2021 Red Hat + * + * Licensed 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 io.apicurio.registry.utils.tests; + +import io.quarkus.test.junit.QuarkusTestProfile; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Carles Arnal + */ +public class MultitenancyNoAuthTestProfile implements QuarkusTestProfile { + + @Override + public Map getConfigOverrides() { + Map props = new HashMap<>(); + props.put("registry.enable.multitenancy", "true"); + props.put("registry.disable.apis", ""); + props.put("registry.multitenancy.reaper.period-seconds", "5"); + props.put("registry.multitenancy.reaper.every", "3s"); + props.put("quarkus.http.port", "8081"); + return props; + } + +} \ No newline at end of file diff --git a/storage/sql/src/test/java/io/apicurio/registry/storage/util/PostgreSqlEmbeddedTestResource.java b/utils/tests/src/main/java/io/apicurio/registry/utils/tests/PostgreSqlEmbeddedTestResource.java similarity index 64% rename from storage/sql/src/test/java/io/apicurio/registry/storage/util/PostgreSqlEmbeddedTestResource.java rename to utils/tests/src/main/java/io/apicurio/registry/utils/tests/PostgreSqlEmbeddedTestResource.java index 5e34c6df67..2935cdd8ab 100644 --- a/storage/sql/src/test/java/io/apicurio/registry/storage/util/PostgreSqlEmbeddedTestResource.java +++ b/utils/tests/src/main/java/io/apicurio/registry/utils/tests/PostgreSqlEmbeddedTestResource.java @@ -14,16 +14,17 @@ * limitations under the License. */ -package io.apicurio.registry.storage.util; +package io.apicurio.registry.utils.tests; + +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; +import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; import java.io.IOException; import java.io.UncheckedIOException; +import java.util.Collections; import java.util.HashMap; import java.util.Map; -import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; -import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; - /** * @author Fabian Martinez */ @@ -32,22 +33,25 @@ public class PostgreSqlEmbeddedTestResource implements QuarkusTestResourceLifecy private EmbeddedPostgres database; /** - * @see io.quarkus.test.common.QuarkusTestResourceLifecycleManager#start() + * @see QuarkusTestResourceLifecycleManager#start() */ @Override public Map start() { + if (!Boolean.parseBoolean(System.getProperty("cluster.tests"))) { - String currentEnv = System.getenv("CURRENT_ENV"); + String currentEnv = System.getenv("CURRENT_ENV"); - if (currentEnv != null && "mas".equals(currentEnv)) { - Map props = new HashMap<>(); - props.put("quarkus.datasource.jdbc.url", "jdbc:postgresql://localhost:5432/test"); - props.put("quarkus.datasource.username", "test"); - props.put("quarkus.datasource.password", "test"); - return props; - } else { - return startPostgresql(); + if (currentEnv != null && "mas".equals(currentEnv)) { + Map props = new HashMap<>(); + props.put("quarkus.datasource.jdbc.url", "jdbc:postgresql://localhost:5432/test"); + props.put("quarkus.datasource.username", "test"); + props.put("quarkus.datasource.password", "test"); + return props; + } else { + return startPostgresql(); + } } + return Collections.emptyMap(); } private Map startPostgresql() { @@ -57,18 +61,22 @@ private Map startPostgresql() { throw new UncheckedIOException(e); } - String datasourceUrl = database.getJdbcUrl("postgres", "postgres"); Map props = new HashMap<>(); props.put("quarkus.datasource.jdbc.url", datasourceUrl); props.put("quarkus.datasource.username", "postgres"); props.put("quarkus.datasource.password", "postgres"); + + System.setProperty("quarkus.datasource.jdbc.url", datasourceUrl); + System.setProperty("quarkus.datasource.username", "postgres"); + System.setProperty("quarkus.datasource.password", "postgres"); + return props; } /** - * @see io.quarkus.test.common.QuarkusTestResourceLifecycleManager#stop() + * @see QuarkusTestResourceLifecycleManager#stop() */ @Override public void stop() { diff --git a/utils/tools/pom.xml b/utils/tools/pom.xml index a57f7c0059..1e4eb387f6 100644 --- a/utils/tools/pom.xml +++ b/utils/tools/pom.xml @@ -7,7 +7,7 @@ io.apicurio apicurio-registry - 2.4.13-SNAPSHOT + 2.5.0-SNAPSHOT ../../pom.xml