├── .github ├── CODEOWNERS ├── dependabot.yml ├── project.yml └── workflows │ ├── build.yml │ ├── cli-integration-tests.yaml │ ├── docker.yaml │ ├── hooks │ └── pre-prepare-release.sh │ ├── pre-release.yml │ ├── quarkus-snapshot.yaml │ ├── release-perform.yml │ └── release-prepare.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── cli ├── pom.xml └── src │ └── main │ ├── java │ └── io │ │ └── quarkiverse │ │ └── backstage │ │ └── cli │ │ ├── BackstageCommand.java │ │ ├── EntitiesCommand.java │ │ ├── LocationCommand.java │ │ ├── TemplateCommand.java │ │ ├── common │ │ ├── BackstageClientAwareCommand.java │ │ ├── GenerationBaseCommand.java │ │ └── Properties.java │ │ ├── entities │ │ ├── EntityGenerateCommand.java │ │ ├── EntityInstallCommand.java │ │ ├── EntityListCommand.java │ │ ├── EntityListItem.java │ │ ├── EntityListTable.java │ │ └── EntityUninstallCommand.java │ │ ├── locations │ │ ├── LocationInstallCommand.java │ │ ├── LocationListCommand.java │ │ ├── LocationListItem.java │ │ ├── LocationListTable.java │ │ └── LocationUninstallCommand.java │ │ └── template │ │ ├── TemplateGenerateCommand.java │ │ ├── TemplateInfoCommand.java │ │ ├── TemplateInstallCommand.java │ │ ├── TemplateInstantiateCommand.java │ │ ├── TemplateListCommand.java │ │ ├── TemplateListItem.java │ │ ├── TemplateListTable.java │ │ └── TemplateUninstallCommand.java │ └── resources │ ├── application.properties │ └── version ├── client ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── quarkiverse │ └── backstage │ └── client │ ├── BackstageClient.java │ ├── BackstageClientContext.java │ ├── BackstageClientException.java │ ├── BackstageConflictException.java │ ├── BackstageEntityNotFoundException.java │ ├── dsl │ ├── BackstageDSL.java │ ├── entities │ │ ├── EntitiesClient.java │ │ └── EntitiesDslSpec.java │ ├── events │ │ ├── EventsClient.java │ │ └── EventsDslSpec.java │ ├── locations │ │ ├── LocationsClient.java │ │ └── LocationsDslSpec.java │ └── templates │ │ ├── TemplatesClient.java │ │ └── TemplatesDslSpec.java │ └── model │ ├── AnalyzeLocationRequest.java │ ├── AnalyzeLocationResponse.java │ ├── CreateLocationRequest.java │ ├── CreateLocationResponse.java │ ├── EntityFile.java │ ├── EntityQueryResult.java │ ├── Field.java │ ├── GenerateEntity.java │ ├── InstantiateErrorResponse.java │ ├── InstantiateRequest.java │ ├── InstantiateResponse.java │ ├── Location.java │ ├── LocationEntry.java │ ├── LocationItem.java │ ├── PageInfo.java │ ├── RefreshEntity.java │ └── ScaffolderEvent.java ├── common ├── pom.xml └── src │ ├── main │ └── java │ │ └── io │ │ └── quarkiverse │ │ └── backstage │ │ └── common │ │ ├── dsl │ │ ├── GitActions.java │ │ └── Gitea.java │ │ ├── handlers │ │ ├── GetBackstageEntitiesAsStringHandler.java │ │ ├── GetBackstageEntitiesHandler.java │ │ ├── GetBackstageTemplatesHandler.java │ │ └── HandlerProcessor.java │ │ ├── template │ │ ├── Devify.java │ │ └── TemplateGenerator.java │ │ ├── utils │ │ ├── ArgoCD.java │ │ ├── DevServices.java │ │ ├── Directories.java │ │ ├── Git.java │ │ ├── Github.java │ │ ├── Gradle.java │ │ ├── GradleKotlin.java │ │ ├── Helm.java │ │ ├── Maps.java │ │ ├── Maven.java │ │ ├── Namespaces.java │ │ ├── Packages.java │ │ ├── Projects.java │ │ ├── Serialization.java │ │ ├── SourceTransformer.java │ │ ├── Streams.java │ │ ├── Strings.java │ │ └── Templates.java │ │ └── visitors │ │ ├── ApplyLifecycle.java │ │ ├── ApplyMetadataAnnotation.java │ │ ├── ApplyMetadataDescription.java │ │ ├── ApplyMetadataLabel.java │ │ ├── ApplyMetadataName.java │ │ ├── ApplyMetadataTag.java │ │ ├── ApplyMetadataTitle.java │ │ ├── ApplyOwner.java │ │ ├── ApplyType.java │ │ ├── api │ │ ├── ApplyApiDescription.java │ │ ├── ApplyApiLifecycle.java │ │ ├── ApplyApiOwner.java │ │ ├── ApplyApiTitle.java │ │ ├── ApplyApiType.java │ │ └── ApplyOpenApiDefinitionPath.java │ │ ├── component │ │ ├── AddComponentApis.java │ │ ├── AddComponentDependencies.java │ │ ├── ApplyComponentAnnotation.java │ │ ├── ApplyComponentLabel.java │ │ ├── ApplyComponentLifecycle.java │ │ ├── ApplyComponentName.java │ │ ├── ApplyComponentOwner.java │ │ ├── ApplyComponentTag.java │ │ └── ApplyComponentType.java │ │ └── template │ │ ├── AddArgoCDCreateResourcesStep.java │ │ ├── AddDebugWaitStep.java │ │ ├── AddNewEntityRefToOutput.java │ │ ├── AddNewFetchTemplateStep.java │ │ ├── AddNewTemplateParameter.java │ │ ├── AddNewTemplateProperty.java │ │ ├── AddNewTemplateStep.java │ │ ├── AddNewUrlToOutput.java │ │ ├── AddPublishGiteaStep.java │ │ ├── AddPublishGithubStep.java │ │ ├── AddRegisterComponentStep.java │ │ ├── ApplyGiteaParameters.java │ │ ├── ApplyPublishGiteaStep.java │ │ ├── ApplyRegisterGiteaHostedComponentStep.java │ │ ├── RemoveNonDevFriendlySteps.java │ │ └── UseGiteaInPublishStep.java │ └── test │ └── java │ └── io │ └── quarkiverse │ └── backstage │ └── common │ ├── dsl │ ├── GitActionsTest.java │ └── GiteaTest.java │ └── utils │ ├── GithubTest.java │ ├── GradleKotlinTest.java │ ├── GradleTest.java │ ├── MavenTest.java │ └── ProjectsTest.java ├── deployment ├── pom.xml └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── backstage │ │ │ └── deployment │ │ │ ├── BackstageConfiguration.java │ │ │ ├── BackstageProcessor.java │ │ │ ├── IsDevTemplateGenerationEnabled.java │ │ │ ├── IsTemplateGenerationEnabled.java │ │ │ ├── IsUserProvidedTemplateGenerationEnabled.java │ │ │ ├── Utils.java │ │ │ ├── devservices │ │ │ ├── BackstageContainer.java │ │ │ ├── BackstageDevServiceInfoBuildItem.java │ │ │ ├── BackstageDevServiceProcessor.java │ │ │ └── BackstageDevServicesConfig.java │ │ │ └── devui │ │ │ └── BackstageDevUIProcessor.java │ └── resources │ │ └── dev-ui │ │ └── qwc-template.js │ └── test │ └── java │ └── io │ └── quarkiverse │ └── backstage │ └── deployment │ ├── SerializationTest.java │ └── UtilsTest.java ├── dev-service-image ├── .dockerignore ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .prettierignore ├── .yarn │ └── releases │ │ └── yarn-4.4.1.cjs ├── .yarnrc.yml ├── README.md ├── app-config.argocd.yaml ├── app-config.base.yaml ├── app-config.catalog.yaml ├── app-config.gitea.yaml ├── app-config.github.yaml ├── app-config.kubernetes.yaml ├── app-config.local.yaml ├── app-config.postgres.yaml ├── app-config.production.yaml ├── app-config.yaml ├── backstage.json ├── bin │ └── run ├── examples │ └── org.yaml ├── package.json ├── packages │ ├── app │ │ ├── .eslintignore │ │ ├── .eslintrc.js │ │ ├── e2e-tests │ │ │ └── app.test.ts │ │ ├── package.json │ │ ├── public │ │ │ ├── android-chrome-192x192.png │ │ │ ├── apple-touch-icon.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon.ico │ │ │ ├── index.html │ │ │ ├── manifest.json │ │ │ ├── robots.txt │ │ │ └── safari-pinned-tab.svg │ │ └── src │ │ │ ├── App.test.tsx │ │ │ ├── App.tsx │ │ │ ├── apis.ts │ │ │ ├── components │ │ │ ├── Root │ │ │ │ ├── LogoFull.tsx │ │ │ │ ├── LogoIcon.tsx │ │ │ │ ├── Root.tsx │ │ │ │ └── index.ts │ │ │ ├── catalog │ │ │ │ └── EntityPage.tsx │ │ │ └── search │ │ │ │ └── SearchPage.tsx │ │ │ ├── index.tsx │ │ │ └── setupTests.ts │ └── backend │ │ ├── .eslintrc.js │ │ ├── Dockerfile │ │ ├── package.json │ │ └── src │ │ └── index.ts ├── playwright.config.ts ├── plugins │ └── README.md ├── tsconfig.json └── yarn.lock ├── docs ├── antora.yml ├── modules │ └── ROOT │ │ ├── assets │ │ ├── casts │ │ │ ├── create-quarkus-app.cast │ │ │ ├── generate-template-using-the-build.cast │ │ │ ├── generate-template-using-the-cli.cast │ │ │ ├── install-backstage-cli-plguin.cast │ │ │ ├── install-backstage-cli-plugin.cast │ │ │ └── install-backstage-extension.cast │ │ ├── generate-screencasts │ │ ├── images │ │ │ ├── .keepme │ │ │ ├── backstage-dev-service.gif │ │ │ ├── create-quarkus-app.gif │ │ │ ├── exposing-an-api.gif │ │ │ ├── generate-template-using-the-build.gif │ │ │ ├── generate-template-using-the-cli.gif │ │ │ ├── generating-a-template-using-the-cli.gif │ │ │ ├── generating-a-template.gif │ │ │ ├── gitea-integration.gif │ │ │ ├── install-backstage-cli-plguin.gif │ │ │ ├── install-backstage-cli-plugin.gif │ │ │ ├── install-backstage-extension.gif │ │ │ ├── installing-quarkus-backstage.gif │ │ │ ├── installing-the-cli-plugin-and-generating-a-template.gif │ │ │ └── installing-the-cli-plugin.gif │ │ └── scenarios │ │ │ ├── generate-template-using-the-build.sh │ │ │ ├── generate-template-using-the-cli.sh │ │ │ ├── install-backstage-cli-plugin.sh │ │ │ └── install-backstage-extension.sh │ │ ├── examples │ │ └── .keepme │ │ ├── nav.adoc │ │ └── pages │ │ ├── catalog-info.adoc │ │ ├── cli.adoc │ │ ├── client.adoc │ │ ├── dev-service.adoc │ │ ├── includes │ │ └── attributes.adoc │ │ ├── index.adoc │ │ └── template-generator.adoc ├── pom.xml └── templates │ └── includes │ └── attributes.adoc ├── integration-tests ├── pom.xml └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── backstage │ │ │ └── it │ │ │ └── BackstageResource.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── io │ └── quarkiverse │ └── backstage │ └── it │ ├── BackstageDevServiceTest.java │ ├── BackstageResourceIT.java │ └── BackstageResourceTest.java ├── model-generator ├── base │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── io │ │ └── quarkiverse │ │ └── backstage │ │ ├── EntityLink.java │ │ ├── EntityMeta.java │ │ ├── Status.java │ │ ├── StatusItem.java │ │ ├── StatusLevel.java │ │ ├── scaffolder │ │ └── v1beta3 │ │ │ ├── Output.java │ │ │ ├── Parameter.java │ │ │ ├── Property.java │ │ │ ├── Step.java │ │ │ ├── Template.java │ │ │ └── TemplateSpec.java │ │ └── v1alpha1 │ │ ├── Api.java │ │ ├── ApiDefinition.java │ │ ├── ApiSpec.java │ │ ├── Component.java │ │ ├── ComponentSpec.java │ │ ├── Domain.java │ │ ├── DomainSpec.java │ │ ├── Entity.java │ │ ├── EntityList.java │ │ ├── Group.java │ │ ├── GroupSpec.java │ │ ├── Location.java │ │ ├── LocationSpec.java │ │ ├── MultilineApiDefintion.java │ │ ├── PathApiDefintion.java │ │ ├── Presence.java │ │ ├── Profile.java │ │ ├── Resource.java │ │ ├── ResourceSpec.java │ │ ├── System.java │ │ ├── SystemSpec.java │ │ ├── User.java │ │ └── UserSpec.java ├── builder-generator │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── io │ │ └── quarkiverse │ │ └── backstage │ │ └── codegen │ │ └── Codegen.java ├── model │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── io │ │ └── quarkiverse │ │ └── backstage │ │ ├── EntityLinkBuilder.java │ │ ├── EntityLinkFluent.java │ │ ├── EntityMetaBuilder.java │ │ ├── EntityMetaFluent.java │ │ ├── StatusBuilder.java │ │ ├── StatusFluent.java │ │ ├── StatusItemBuilder.java │ │ ├── StatusItemFluent.java │ │ ├── model │ │ └── builder │ │ │ ├── BaseFluent.java │ │ │ ├── Builder.java │ │ │ ├── DelegatingVisitor.java │ │ │ ├── Editable.java │ │ │ ├── Fluent.java │ │ │ ├── Nested.java │ │ │ ├── PathAwareTypedVisitor.java │ │ │ ├── TypedVisitor.java │ │ │ ├── Visitable.java │ │ │ ├── VisitableBuilder.java │ │ │ ├── VisitableMap.java │ │ │ ├── Visitor.java │ │ │ ├── VisitorListener.java │ │ │ ├── VisitorWiretap.java │ │ │ └── Visitors.java │ │ ├── scaffolder │ │ └── v1beta3 │ │ │ ├── OutputBuilder.java │ │ │ ├── OutputFluent.java │ │ │ ├── ParameterBuilder.java │ │ │ ├── ParameterFluent.java │ │ │ ├── PropertyBuilder.java │ │ │ ├── PropertyFluent.java │ │ │ ├── StepBuilder.java │ │ │ ├── StepFluent.java │ │ │ ├── TemplateBuilder.java │ │ │ ├── TemplateFluent.java │ │ │ ├── TemplateSpecBuilder.java │ │ │ └── TemplateSpecFluent.java │ │ └── v1alpha1 │ │ ├── ApiBuilder.java │ │ ├── ApiFluent.java │ │ ├── ApiSpecBuilder.java │ │ ├── ApiSpecFluent.java │ │ ├── ComponentBuilder.java │ │ ├── ComponentFluent.java │ │ ├── ComponentSpecBuilder.java │ │ ├── ComponentSpecFluent.java │ │ ├── DomainBuilder.java │ │ ├── DomainFluent.java │ │ ├── DomainSpecBuilder.java │ │ ├── DomainSpecFluent.java │ │ ├── EntityListBuilder.java │ │ ├── EntityListFluent.java │ │ ├── GroupBuilder.java │ │ ├── GroupFluent.java │ │ ├── GroupSpecBuilder.java │ │ ├── GroupSpecFluent.java │ │ ├── LocationBuilder.java │ │ ├── LocationFluent.java │ │ ├── LocationSpecBuilder.java │ │ ├── LocationSpecFluent.java │ │ ├── MultilineApiDefintionBuilder.java │ │ ├── MultilineApiDefintionFluent.java │ │ ├── PathApiDefintionBuilder.java │ │ ├── PathApiDefintionFluent.java │ │ ├── ProfileBuilder.java │ │ ├── ProfileFluent.java │ │ ├── ResourceBuilder.java │ │ ├── ResourceFluent.java │ │ ├── ResourceSpecBuilder.java │ │ ├── ResourceSpecFluent.java │ │ ├── SystemBuilder.java │ │ ├── SystemFluent.java │ │ ├── SystemSpecBuilder.java │ │ ├── SystemSpecFluent.java │ │ ├── UserBuilder.java │ │ ├── UserFluent.java │ │ ├── UserSpecBuilder.java │ │ └── UserSpecFluent.java └── pom.xml ├── pom.xml ├── runtime ├── pom.xml └── src │ └── main │ ├── java │ └── io │ │ └── quarkiverse │ │ └── backstage │ │ └── runtime │ │ ├── BackstageClientFactory.java │ │ ├── BackstageRuntimeConfiguration.java │ │ └── devui │ │ └── BackstageTemplateJsonRPCService.java │ └── resources │ └── META-INF │ └── quarkus-extension.yaml └── spi ├── pom.xml └── src └── main └── java └── io └── quarkiverse └── backstage └── spi ├── CatalogInfoRequiredFileBuildItem.java ├── CatalogInstallationBuildItem.java ├── DevTemplateBuildItem.java ├── DevTemplateInstallationBuildItem.java ├── EntityListBuildItem.java ├── TemplateBuildItem.java ├── TemplateInstallationBuildItem.java ├── UserProvidedTemplateBuildItem.java └── UserProvidedTemplateInstallationBuildItem.java /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Lines starting with '#' are comments. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # More details are here: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners 5 | 6 | # The '*' pattern is global owners. 7 | 8 | # Order is important. The last matching pattern has the most precedence. 9 | # The folders are ordered as follows: 10 | 11 | # In each subsection folders are ordered first by depth, then alphabetically. 12 | # This should make it easy to add new rules without breaking existing ones. 13 | 14 | * @quarkiverse/quarkiverse-backstage 15 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "maven" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /.github/project.yml: -------------------------------------------------------------------------------- 1 | release: 2 | current-version: "0.7.0" 3 | next-version: "999-SNAPSHOT" 4 | 5 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - "main" 7 | paths-ignore: 8 | - '.gitignore' 9 | - 'CODEOWNERS' 10 | - 'LICENSE' 11 | - '*.md' 12 | - '*.adoc' 13 | - '*.txt' 14 | - '.all-contributorsrc' 15 | pull_request: 16 | paths-ignore: 17 | - '.gitignore' 18 | - 'CODEOWNERS' 19 | - 'LICENSE' 20 | - '*.md' 21 | - '*.adoc' 22 | - '*.txt' 23 | - '.all-contributorsrc' 24 | 25 | concurrency: 26 | group: ${{ github.workflow }}-${{ github.ref }} 27 | cancel-in-progress: true 28 | 29 | defaults: 30 | run: 31 | shell: bash 32 | 33 | jobs: 34 | build: 35 | name: Build on ${{ matrix.os }} 36 | strategy: 37 | fail-fast: false 38 | matrix: 39 | # os: [windows-latest, macos-latest, ubuntu-latest] 40 | os: [ubuntu-latest] 41 | runs-on: ${{ matrix.os }} 42 | steps: 43 | - name: Prepare git 44 | run: git config --global core.autocrlf false 45 | if: startsWith(matrix.os, 'windows') 46 | 47 | - uses: actions/checkout@v3 48 | - name: Set up JDK 17 49 | uses: actions/setup-java@v3 50 | with: 51 | distribution: temurin 52 | java-version: 17 53 | cache: 'maven' 54 | 55 | - name: Build with Maven 56 | run: mvn -B clean install -Dno-format 57 | 58 | - name: Build with Maven (Native) 59 | run: mvn -B install -Dnative -Dquarkus.native.container-build -Dnative.surefire.skip 60 | -------------------------------------------------------------------------------- /.github/workflows/hooks/pre-prepare-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #------------------------------------- 3 | # Hook invoked by the release workflow 4 | #------------------------------------- 5 | 6 | # We need to rebuild the project 7 | mvn clean install -DskipTests 8 | 9 | # Update the package list 10 | sudo apt-get update 11 | 12 | # Install Quarkus CLI 13 | jbang trust add https://repo1.maven.org/maven2/io/quarkus/quarkus-cli/ 14 | jbang app install --fresh --force quarkus@quarkusio 15 | 16 | # Install Asciicinema 17 | sudo apt-get install asciinema 18 | 19 | # Install Asciinema-automation 20 | python3 -m pip install asciinema-automation 21 | 22 | # Install Asciinema-Agg 23 | cargo install --git https://github.com/asciinema/agg 24 | 25 | # Iterate all .sh files in the docs/modules/ROOT/assets/scenarios directory 26 | # and replace 999-SNAPSHOT with the current version 27 | sed -i "s/999-SNAPSHOT/${CURRENT_VERSION}/g" docs/modules/ROOT/assets/scenarios/*.sh 28 | 29 | # Generate screencasts 30 | cd docs/modules/ROOT/assets/ 31 | ./generate-screencasts 32 | cd ../../../../ 33 | 34 | # Revert changes to scenarios (we want to keep 999-SNAPSHOT in there). 35 | git checkout -- docs/modules/ROOT/assets/scenarios 36 | 37 | # Commit changes 38 | git checkout -b update-screencasts-${CURRENT_VERSION} 39 | 40 | git add docs/modules/ROOT/assets/casts 41 | git add docs/modules/ROOT/assets/images 42 | git commit -m "Update screencasts for ${CURRENT_VERSION}" 43 | 44 | 45 | git push --force --set-upstream origin update-screencasts-${CURRENT_VERSION} 46 | -------------------------------------------------------------------------------- /.github/workflows/pre-release.yml: -------------------------------------------------------------------------------- 1 | name: Quarkiverse Pre Release 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - '.github/project.yml' 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.ref }} 10 | cancel-in-progress: true 11 | 12 | jobs: 13 | pre-release: 14 | name: Pre-Release 15 | uses: quarkiverse/.github/.github/workflows/pre-release.yml@main 16 | secrets: inherit 17 | -------------------------------------------------------------------------------- /.github/workflows/release-perform.yml: -------------------------------------------------------------------------------- 1 | name: Quarkiverse Perform Release 2 | run-name: Perform ${{github.event.inputs.tag || github.ref_name}} Release 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | workflow_dispatch: 8 | inputs: 9 | tag: 10 | description: 'Tag to release' 11 | required: true 12 | 13 | permissions: 14 | attestations: write 15 | id-token: write 16 | contents: read 17 | 18 | concurrency: 19 | group: ${{ github.workflow }}-${{ github.ref }} 20 | cancel-in-progress: true 21 | 22 | jobs: 23 | perform-release: 24 | name: Perform Release 25 | uses: quarkiverse/.github/.github/workflows/perform-release.yml@main 26 | secrets: inherit 27 | with: 28 | version: ${{github.event.inputs.tag || github.ref_name}} 29 | -------------------------------------------------------------------------------- /.github/workflows/release-prepare.yml: -------------------------------------------------------------------------------- 1 | name: Quarkiverse Prepare Release 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | types: [ closed ] 7 | paths: 8 | - '.github/project.yml' 9 | 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.ref }} 12 | cancel-in-progress: true 13 | 14 | jobs: 15 | prepare-release: 16 | if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true}} 17 | name: Prepare Release 18 | uses: quarkiverse/.github/.github/workflows/prepare-release.yml@main 19 | secrets: inherit 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see https://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | # Eclipse 26 | .project 27 | .classpath 28 | .settings/ 29 | 30 | # IntelliJ 31 | .idea 32 | *.ipr 33 | *.iml 34 | *.iws 35 | 36 | # NetBeans 37 | nb-configuration.xml 38 | 39 | # Visual Studio Code 40 | .vscode 41 | .factorypath 42 | 43 | # OSX 44 | .DS_Store 45 | 46 | # Vim 47 | *.swp 48 | *.swo 49 | 50 | # patch 51 | *.orig 52 | *.rej 53 | 54 | # Gradle 55 | .gradle/ 56 | build/ 57 | 58 | # Maven 59 | target/ 60 | pom.xml.tag 61 | pom.xml.releaseBackup 62 | pom.xml.versionsBackup 63 | release.properties 64 | 65 | # Node 66 | node_modules/ 67 | dist/ 68 | 69 | .backstage 70 | catalog-info.yaml 71 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | SHELL := /bin/bash 3 | 4 | builders: 5 | mvn clean install -pl :quarkus-backstage-model-builder-generator -am && \ 6 | rm -rf model-generator/model/src/main/java/io.quarkiverse.backstage/*.java && \ 7 | rm -rf model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/* && \ 8 | rm -rf model-generator/model/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/* && \ 9 | rm -rf model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder/* && \ 10 | mkdir -p model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder && \ 11 | mkdir -p model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1 && \ 12 | mkdir -p model-generator/model/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3 && \ 13 | cp model-generator/builder-generator/target/generated-sources/annotations/io/quarkiverse/backstage/*.java model-generator/model/src/main/java/io/quarkiverse/backstage/ 14 | cp -r model-generator/builder-generator/target/generated-sources/annotations/io/quarkiverse/backstage/v1alpha1/* model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/ 15 | cp -r model-generator/builder-generator/target/generated-sources/annotations/io/quarkiverse/backstage/scaffolder/v1beta3/* model-generator/model/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/ 16 | cp -r model-generator/builder-generator/target/generated-sources/annotations/io/quarkiverse/backstage/model/builder/* model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder/ 17 | 18 | build: 19 | mvn clean install 20 | 21 | all: builders build 22 | -------------------------------------------------------------------------------- /cli/src/main/java/io/quarkiverse/backstage/cli/BackstageCommand.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.cli; 2 | 3 | import java.util.concurrent.Callable; 4 | 5 | import io.quarkus.picocli.runtime.annotations.TopCommand; 6 | import picocli.CommandLine; 7 | import picocli.CommandLine.Command; 8 | import picocli.CommandLine.Model.CommandSpec; 9 | import picocli.CommandLine.Option; 10 | import picocli.CommandLine.Spec; 11 | 12 | @TopCommand 13 | @Command(name = "backstage", sortOptions = false, mixinStandardHelpOptions = false, header = "Backstage CLI", subcommands = { 14 | EntitiesCommand.class, 15 | LocationCommand.class, 16 | TemplateCommand.class }) 17 | public class BackstageCommand implements Callable { 18 | 19 | @Spec 20 | protected CommandSpec spec; 21 | 22 | @Option(names = { "-h", "--help" }, usageHelp = true, description = "Display this help message.") 23 | public boolean help; 24 | 25 | @Override 26 | public Integer call() { 27 | CommandLine entitiesCommand = spec.subcommands().get("entities"); 28 | return entitiesCommand.execute(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /cli/src/main/java/io/quarkiverse/backstage/cli/EntitiesCommand.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.cli; 2 | 3 | import java.util.concurrent.Callable; 4 | 5 | import io.quarkiverse.backstage.cli.entities.*; 6 | import picocli.CommandLine; 7 | import picocli.CommandLine.Command; 8 | import picocli.CommandLine.Model.CommandSpec; 9 | import picocli.CommandLine.Option; 10 | import picocli.CommandLine.Spec; 11 | 12 | @Command(name = "entities", sortOptions = false, mixinStandardHelpOptions = false, header = "Backstage Entities", subcommands = { 13 | EntityListCommand.class, EntityInstallCommand.class, EntityUninstallCommand.class, EntityGenerateCommand.class }) 14 | public class EntitiesCommand implements Callable { 15 | 16 | @Spec 17 | protected CommandSpec spec; 18 | 19 | @Option(names = { "-h", "--help" }, usageHelp = true, description = "Display this help message.") 20 | public boolean help; 21 | 22 | @Override 23 | public Integer call() { 24 | CommandLine schemaCommand = spec.subcommands().get("list"); 25 | return schemaCommand.execute(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /cli/src/main/java/io/quarkiverse/backstage/cli/LocationCommand.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.cli; 2 | 3 | import java.util.concurrent.Callable; 4 | 5 | import io.quarkiverse.backstage.cli.locations.LocationInstallCommand; 6 | import io.quarkiverse.backstage.cli.locations.LocationListCommand; 7 | import io.quarkiverse.backstage.cli.locations.LocationUninstallCommand; 8 | import picocli.CommandLine; 9 | import picocli.CommandLine.Command; 10 | import picocli.CommandLine.Model.CommandSpec; 11 | import picocli.CommandLine.Option; 12 | import picocli.CommandLine.Spec; 13 | 14 | @Command(name = "location", sortOptions = false, mixinStandardHelpOptions = false, header = "Backstage Location", subcommands = { 15 | LocationListCommand.class, LocationInstallCommand.class, LocationUninstallCommand.class }) 16 | public class LocationCommand implements Callable { 17 | 18 | @Spec 19 | protected CommandSpec spec; 20 | 21 | @Option(names = { "-h", "--help" }, usageHelp = true, description = "Display this help message.") 22 | public boolean help; 23 | 24 | @Override 25 | public Integer call() { 26 | CommandLine listCommand = spec.subcommands().get("list"); 27 | return listCommand.execute(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /cli/src/main/java/io/quarkiverse/backstage/cli/TemplateCommand.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.cli; 2 | 3 | import java.util.concurrent.Callable; 4 | 5 | import io.quarkiverse.backstage.cli.template.TemplateGenerateCommand; 6 | import io.quarkiverse.backstage.cli.template.TemplateInfoCommand; 7 | import io.quarkiverse.backstage.cli.template.TemplateInstallCommand; 8 | import io.quarkiverse.backstage.cli.template.TemplateInstantiateCommand; 9 | import io.quarkiverse.backstage.cli.template.TemplateListCommand; 10 | import io.quarkiverse.backstage.cli.template.TemplateUninstallCommand; 11 | import picocli.CommandLine; 12 | import picocli.CommandLine.Command; 13 | import picocli.CommandLine.Model.CommandSpec; 14 | import picocli.CommandLine.Option; 15 | import picocli.CommandLine.Spec; 16 | 17 | @Command(name = "template", sortOptions = false, mixinStandardHelpOptions = false, header = "Backstage Template", subcommands = { 18 | TemplateListCommand.class, TemplateInstallCommand.class, TemplateUninstallCommand.class, TemplateGenerateCommand.class, 19 | TemplateInstantiateCommand.class, 20 | TemplateInfoCommand.class }) 21 | public class TemplateCommand implements Callable { 22 | 23 | @Spec 24 | protected CommandSpec spec; 25 | 26 | @Option(names = { "-h", "--help" }, usageHelp = true, description = "Display this help message.") 27 | public boolean help; 28 | 29 | @Override 30 | public Integer call() { 31 | CommandLine schemaCommand = spec.subcommands().get("list"); 32 | return schemaCommand.execute(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /cli/src/main/java/io/quarkiverse/backstage/cli/common/Properties.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.cli.common; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import io.quarkiverse.backstage.scaffolder.v1beta3.Property; 7 | 8 | public final class Properties { 9 | 10 | private Properties() { 11 | //Utility class 12 | } 13 | 14 | public static void displayProperty(String name, Property property, String indent) { 15 | if (property.getProperties() != null) { 16 | System.out.println(indent + property.getType() + " " + name + ": "); 17 | property.getProperties().forEach((n, p) -> displayProperty(n, p, indent + " ")); 18 | } else { 19 | System.out.println(indent + property.getType() + " " + name + ": " + property.getDescription()); 20 | } 21 | } 22 | 23 | public static Map extractValues(Map properties) { 24 | Map values = new HashMap<>(); 25 | for (Map.Entry entry : properties.entrySet()) { 26 | String name = entry.getKey(); 27 | Property property = entry.getValue(); 28 | property.getDefaultValue().ifPresentOrElse(value -> values.put(name, value), () -> { 29 | if (property.getProperties() != null) { 30 | values.put(name, extractValues(property.getProperties())); 31 | } 32 | }); 33 | } 34 | return values; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /cli/src/main/java/io/quarkiverse/backstage/cli/entities/EntityListCommand.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.cli.entities; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | import io.quarkiverse.backstage.cli.common.BackstageClientAwareCommand; 7 | import io.quarkiverse.backstage.client.BackstageClient; 8 | import io.quarkiverse.backstage.v1alpha1.Entity; 9 | import picocli.CommandLine.Command; 10 | import picocli.CommandLine.ExitCode; 11 | import picocli.CommandLine.Unmatched; 12 | 13 | @Command(name = "list", sortOptions = false, mixinStandardHelpOptions = false, header = "Backstage Entity List") 14 | public class EntityListCommand extends BackstageClientAwareCommand { 15 | 16 | public EntityListCommand(BackstageClient backstageClient) { 17 | super(backstageClient); 18 | } 19 | 20 | @Unmatched 21 | List unmatched; 22 | 23 | @Override 24 | public Integer call() throws Exception { 25 | List entities = getBackstageClient().entities().list(); 26 | List entityListItems = entities.stream().map(EntityListItem::from).collect(Collectors.toList()); 27 | 28 | EntityListTable table = new EntityListTable(entityListItems); 29 | System.out.println(table.getContent()); 30 | 31 | return ExitCode.OK; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /cli/src/main/java/io/quarkiverse/backstage/cli/entities/EntityListItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.cli.entities; 2 | 3 | import io.quarkiverse.backstage.v1alpha1.Entity; 4 | 5 | public class EntityListItem { 6 | 7 | private String apiVersion; 8 | private String kind; 9 | private String name; 10 | private String id; 11 | 12 | public EntityListItem(String apiVersion, String kind, String name, String id) { 13 | this.apiVersion = apiVersion; 14 | this.kind = kind; 15 | this.name = name; 16 | this.id = id; 17 | } 18 | 19 | public static EntityListItem from(Entity entity) { 20 | return new EntityListItem(entity.getApiVersion(), entity.getKind(), entity.getMetadata().getName(), 21 | entity.getMetadata().getUid().orElse("")); 22 | } 23 | 24 | public String getApiVersion() { 25 | return apiVersion; 26 | } 27 | 28 | public void setApiVersion(String apiVersion) { 29 | this.apiVersion = apiVersion; 30 | } 31 | 32 | public String getKind() { 33 | return kind; 34 | } 35 | 36 | public void setKind(String kind) { 37 | this.kind = kind; 38 | } 39 | 40 | public String getName() { 41 | return name; 42 | } 43 | 44 | public void setName(String name) { 45 | this.name = name; 46 | } 47 | 48 | public String getId() { 49 | return id; 50 | } 51 | 52 | public void setId(String id) { 53 | this.id = id; 54 | } 55 | 56 | public String[] getFields() { 57 | return new String[] { apiVersion, kind, name, id }; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /cli/src/main/java/io/quarkiverse/backstage/cli/locations/LocationInstallCommand.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.cli.locations; 2 | 3 | import io.quarkiverse.backstage.cli.common.BackstageClientAwareCommand; 4 | import io.quarkiverse.backstage.client.BackstageClient; 5 | import io.quarkiverse.backstage.client.model.CreateLocationResponse; 6 | import picocli.CommandLine.Command; 7 | import picocli.CommandLine.ExitCode; 8 | import picocli.CommandLine.Parameters; 9 | 10 | @Command(name = "install", sortOptions = false, mixinStandardHelpOptions = false, header = "Install Location.", headerHeading = "%n", commandListHeading = "%nCommands:%n", synopsisHeading = "%nUsage: ", optionListHeading = "%nOptions:%n") 11 | public class LocationInstallCommand extends BackstageClientAwareCommand { 12 | 13 | @Parameters(index = "0", arity = "1..1", description = "The location target.") 14 | private String target; 15 | 16 | public LocationInstallCommand(BackstageClient backstageClient) { 17 | super(backstageClient); 18 | } 19 | 20 | @Override 21 | public Integer call() throws Exception { 22 | CreateLocationResponse response; 23 | if (target.matches("^(http|https|git)://.*$")) { 24 | response = getBackstageClient().locations().createFromUrl(target); 25 | } else { 26 | response = getBackstageClient().locations().createFromFile(target); 27 | } 28 | 29 | System.out.println("Created location:" + response.getLocation().getId()); 30 | response.getEntities().forEach(e -> System.out.println(" - " + e.getKind() + ":" + e.getMetadata().getName())); 31 | 32 | return ExitCode.OK; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /cli/src/main/java/io/quarkiverse/backstage/cli/locations/LocationListCommand.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.cli.locations; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | import io.quarkiverse.backstage.cli.common.BackstageClientAwareCommand; 7 | import io.quarkiverse.backstage.client.BackstageClient; 8 | import io.quarkiverse.backstage.v1alpha1.Entity; 9 | import io.quarkiverse.backstage.v1alpha1.Location; 10 | import picocli.CommandLine.Command; 11 | import picocli.CommandLine.ExitCode; 12 | import picocli.CommandLine.Unmatched; 13 | 14 | @Command(name = "list", sortOptions = false, mixinStandardHelpOptions = false, header = "Backstage Locations List") 15 | public class LocationListCommand extends BackstageClientAwareCommand { 16 | 17 | public LocationListCommand(BackstageClient backstageClient) { 18 | super(backstageClient); 19 | } 20 | 21 | @Unmatched 22 | List unmatched; 23 | 24 | @Override 25 | public Integer call() throws Exception { 26 | List result = getBackstageClient().entities().list("kind=location"); 27 | List locationListItems = result.stream() 28 | .filter(e -> e instanceof Location) 29 | .map(e -> (Location) e) 30 | .map(LocationListItem::from).collect(Collectors.toList()); 31 | 32 | LocationListTable table = new LocationListTable(locationListItems); 33 | System.out.println(table.getContent()); 34 | 35 | return ExitCode.OK; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /cli/src/main/java/io/quarkiverse/backstage/cli/template/TemplateListCommand.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.cli.template; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | import io.quarkiverse.backstage.cli.common.BackstageClientAwareCommand; 7 | import io.quarkiverse.backstage.client.BackstageClient; 8 | import io.quarkiverse.backstage.v1alpha1.Entity; 9 | import picocli.CommandLine.Command; 10 | import picocli.CommandLine.ExitCode; 11 | import picocli.CommandLine.Unmatched; 12 | 13 | @Command(name = "list", sortOptions = false, mixinStandardHelpOptions = false, header = "Backstage Template List") 14 | public class TemplateListCommand extends BackstageClientAwareCommand { 15 | 16 | public TemplateListCommand(BackstageClient backstageClient) { 17 | super(backstageClient); 18 | } 19 | 20 | @Unmatched 21 | List unmatched; 22 | 23 | @Override 24 | public Integer call() throws Exception { 25 | List result = getBackstageClient().entities().list("kind=template"); 26 | List entityListItems = result.stream().map(TemplateListItem::from) 27 | .collect(Collectors.toList()); 28 | 29 | TemplateListTable table = new TemplateListTable(entityListItems); 30 | System.out.println(table.getContent()); 31 | 32 | return ExitCode.OK; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /cli/src/main/java/io/quarkiverse/backstage/cli/template/TemplateListItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.cli.template; 2 | 3 | import io.quarkiverse.backstage.v1alpha1.Entity; 4 | 5 | public class TemplateListItem { 6 | 7 | private String apiVersion; 8 | private String kind; 9 | private String name; 10 | private String id; 11 | 12 | public TemplateListItem(String apiVersion, String kind, String name, String id) { 13 | this.apiVersion = apiVersion; 14 | this.kind = kind; 15 | this.name = name; 16 | this.id = id; 17 | } 18 | 19 | public static TemplateListItem from(Entity entity) { 20 | return new TemplateListItem(entity.getApiVersion(), entity.getKind(), entity.getMetadata().getName(), 21 | entity.getMetadata().getUid() != null ? entity.getMetadata().getUid().orElse("") : ""); 22 | } 23 | 24 | public String getApiVersion() { 25 | return apiVersion; 26 | } 27 | 28 | public void setApiVersion(String apiVersion) { 29 | this.apiVersion = apiVersion; 30 | } 31 | 32 | public String getKind() { 33 | return kind; 34 | } 35 | 36 | public void setKind(String kind) { 37 | this.kind = kind; 38 | } 39 | 40 | public String getName() { 41 | return name; 42 | } 43 | 44 | public void setName(String name) { 45 | this.name = name; 46 | } 47 | 48 | public String getId() { 49 | return id; 50 | } 51 | 52 | public void setId(String id) { 53 | this.id = id; 54 | } 55 | 56 | public String[] getFields() { 57 | return new String[] { apiVersion, kind, name, id }; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /cli/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.log.level=ERROR 2 | quarkus.log.category."com.fasterxml.jackson".level=DEBUG 3 | quarkus.banner.enabled=false 4 | -------------------------------------------------------------------------------- /cli/src/main/resources/version: -------------------------------------------------------------------------------- 1 | ${project.version} 2 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/BackstageClientContext.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client; 2 | 3 | import io.vertx.core.Vertx; 4 | import io.vertx.ext.web.client.WebClient; 5 | import io.vertx.ext.web.client.WebClientOptions; 6 | 7 | public class BackstageClientContext { 8 | 9 | private final String host; 10 | private final int port; 11 | private final String token; 12 | private final WebClient webClient; 13 | 14 | public BackstageClientContext(String host, int port, String token) { 15 | this.host = host; 16 | this.port = port; 17 | this.token = token; 18 | 19 | WebClientOptions options = new WebClientOptions().setDefaultHost(host).setDefaultPort(port); 20 | this.webClient = WebClient.create(Vertx.vertx(), options); 21 | } 22 | 23 | public String getHost() { 24 | return host; 25 | } 26 | 27 | public int getPort() { 28 | return port; 29 | } 30 | 31 | public String getToken() { 32 | return token; 33 | } 34 | 35 | public WebClient getWebClient() { 36 | return webClient; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/BackstageClientException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client; 2 | 3 | import java.util.concurrent.ExecutionException; 4 | 5 | public class BackstageClientException extends RuntimeException { 6 | 7 | BackstageClientException(Throwable cause) { 8 | super(cause); 9 | } 10 | 11 | BackstageClientException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public BackstageClientException(String message) { 16 | super(message); 17 | } 18 | 19 | public static BackstageClientException launderThrowable(String message, Throwable throwable) { 20 | if (throwable instanceof BackstageClientException) { 21 | return (BackstageClientException) throwable; 22 | } else if (throwable instanceof ExecutionException) { 23 | return launderThrowable(throwable.getCause()); 24 | } 25 | return new BackstageClientException(message, throwable); 26 | } 27 | 28 | public static BackstageClientException launderThrowable(Throwable throwable) { 29 | if (throwable instanceof BackstageClientException) { 30 | return (BackstageClientException) throwable; 31 | } else if (throwable instanceof ExecutionException) { 32 | return launderThrowable(throwable.getCause()); 33 | } 34 | return new BackstageClientException(throwable); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/BackstageConflictException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client; 2 | 3 | public class BackstageConflictException extends BackstageClientException { 4 | 5 | public BackstageConflictException(Throwable cause) { 6 | super(cause); 7 | } 8 | 9 | public BackstageConflictException(String message) { 10 | super(message); 11 | } 12 | 13 | public BackstageConflictException(String message, Throwable cause) { 14 | super(message, cause); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/BackstageEntityNotFoundException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client; 2 | 3 | public class BackstageEntityNotFoundException extends BackstageClientException { 4 | 5 | public BackstageEntityNotFoundException(Throwable cause) { 6 | super(cause); 7 | } 8 | 9 | public BackstageEntityNotFoundException(String message) { 10 | super(message); 11 | } 12 | 13 | public BackstageEntityNotFoundException(String message, Throwable cause) { 14 | super(message, cause); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/dsl/BackstageDSL.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.dsl; 2 | 3 | import io.quarkiverse.backstage.client.dsl.entities.EntitiesDsl; 4 | import io.quarkiverse.backstage.client.dsl.events.EventsDsl; 5 | import io.quarkiverse.backstage.client.dsl.locations.LocationsDsl; 6 | import io.quarkiverse.backstage.client.dsl.templates.TemplatesDsl; 7 | 8 | public interface BackstageDSL extends EntitiesDsl, LocationsDsl, TemplatesDsl, EventsDsl { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/dsl/templates/TemplatesDslSpec.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.dsl.templates; 2 | 3 | import java.util.Map; 4 | 5 | import io.quarkiverse.backstage.scaffolder.v1beta3.Template; 6 | import io.sundr.dsl.annotations.All; 7 | import io.sundr.dsl.annotations.Any; 8 | import io.sundr.dsl.annotations.Dsl; 9 | import io.sundr.dsl.annotations.EntryPoint; 10 | import io.sundr.dsl.annotations.InterfaceName; 11 | import io.sundr.dsl.annotations.MethodName; 12 | import io.sundr.dsl.annotations.Terminal; 13 | 14 | @Dsl 15 | @InterfaceName("TemplatesDsl") 16 | public interface TemplatesDslSpec { 17 | 18 | @EntryPoint 19 | void templates(); 20 | 21 | @Any(methods = { "templates" }) 22 | void withName(String name); 23 | 24 | @Any(methods = { "templates" }) 25 | @All(methods = { "withName" }) 26 | void inNamespace(String namespace); 27 | 28 | @Terminal 29 | @MethodName("get") 30 | @All(methods = { "templates" }) 31 | @Any(methods = { "withName", "inNamespace" }) 32 | Template getTemplate(); 33 | 34 | @Terminal 35 | @MethodName("instantiate") 36 | @Any(methods = { "withName", "inNamespace" }) 37 | String instantiate(Map values); 38 | 39 | } 40 | 41 | interface Usage { 42 | default void usage(TemplatesDsl client) { 43 | String result = client.templates().withName("my-template").instantiate(Map.of("key", "value")); 44 | result = client.templates().withName("my-template").inNamespace("my-namespace").instantiate(Map.of("key", "value")); 45 | client.templates().withName("my-template").get(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/AnalyzeLocationRequest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 6 | 7 | import lombok.EqualsAndHashCode; 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | import lombok.ToString; 11 | 12 | @Getter 13 | @Setter 14 | @ToString 15 | @EqualsAndHashCode 16 | @JsonInclude(JsonInclude.Include.NON_NULL) 17 | @JsonPropertyOrder({ 18 | "location", 19 | "catalogFileName" 20 | }) 21 | public class AnalyzeLocationRequest { 22 | 23 | @JsonProperty("location") 24 | private Location loation; 25 | 26 | @JsonProperty("catalogFileName") 27 | private String catalogFileName; 28 | } 29 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/AnalyzeLocationResponse.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import java.util.List; 4 | 5 | import com.fasterxml.jackson.annotation.JsonInclude; 6 | import com.fasterxml.jackson.annotation.JsonProperty; 7 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 8 | 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.Setter; 12 | import lombok.ToString; 13 | 14 | @JsonInclude(JsonInclude.Include.NON_NULL) 15 | @JsonPropertyOrder({ 16 | "generateEntities", 17 | "existingEntityFiles" 18 | }) 19 | @Getter 20 | @Setter 21 | @ToString 22 | @EqualsAndHashCode 23 | public class AnalyzeLocationResponse { 24 | 25 | @JsonProperty("generateEntities") 26 | private List generateEntities; 27 | 28 | @JsonProperty("existingEntityFiles") 29 | private List existingEntityFiles; 30 | } 31 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/CreateLocationResponse.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import jakarta.validation.Valid; 8 | import jakarta.validation.constraints.Size; 9 | 10 | import com.fasterxml.jackson.annotation.JsonIgnore; 11 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 12 | import com.fasterxml.jackson.annotation.JsonInclude; 13 | import com.fasterxml.jackson.annotation.JsonProperty; 14 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 15 | 16 | import io.quarkiverse.backstage.v1alpha1.Entity; 17 | import lombok.EqualsAndHashCode; 18 | import lombok.Getter; 19 | import lombok.Setter; 20 | import lombok.ToString; 21 | 22 | @JsonIgnoreProperties(ignoreUnknown = true) 23 | @JsonInclude(JsonInclude.Include.NON_NULL) 24 | @JsonPropertyOrder({ 25 | "location", 26 | "entities" 27 | }) 28 | @Getter 29 | @Setter 30 | @ToString 31 | @EqualsAndHashCode 32 | public class CreateLocationResponse { 33 | 34 | public CreateLocationResponse() { 35 | } 36 | 37 | public CreateLocationResponse(LocationEntry location, List entities) { 38 | this.location = location; 39 | this.entities = entities; 40 | } 41 | 42 | @JsonProperty("location") 43 | @Size(min = 1) 44 | private LocationEntry location; 45 | 46 | @JsonProperty("entities") 47 | List entities; 48 | 49 | @JsonIgnore 50 | @Valid 51 | private Map additionalProperties = new LinkedHashMap(); 52 | } 53 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/EntityFile.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 6 | 7 | import lombok.EqualsAndHashCode; 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | import lombok.ToString; 11 | 12 | @Getter 13 | @Setter 14 | @ToString 15 | @EqualsAndHashCode 16 | @JsonInclude(JsonInclude.Include.NON_NULL) 17 | @JsonPropertyOrder({ 18 | "entity", 19 | "isRegistered", 20 | "location" 21 | }) 22 | public class EntityFile { 23 | 24 | @JsonProperty("entity") 25 | private Object entity; // Assuming 'entity' is a JSON object or `Entity` type 26 | 27 | @JsonProperty("isRegistered") 28 | private Boolean isRegistered; 29 | 30 | @JsonProperty("location") 31 | private Location location; 32 | } 33 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/EntityQueryResult.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import java.util.List; 4 | 5 | import com.fasterxml.jackson.annotation.JsonInclude; 6 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 7 | 8 | import io.quarkiverse.backstage.v1alpha1.Entity; 9 | import lombok.AllArgsConstructor; 10 | import lombok.EqualsAndHashCode; 11 | import lombok.Getter; 12 | import lombok.NoArgsConstructor; 13 | import lombok.Setter; 14 | import lombok.ToString; 15 | 16 | @JsonInclude(JsonInclude.Include.NON_NULL) 17 | @JsonPropertyOrder({ 18 | "items", 19 | "totalItems", 20 | "pageInfo", 21 | }) 22 | @AllArgsConstructor 23 | @NoArgsConstructor 24 | @Getter 25 | @Setter 26 | @ToString 27 | @EqualsAndHashCode 28 | public class EntityQueryResult { 29 | 30 | private List items; 31 | private int totalItems; 32 | private PageInfo pageInfo; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/Field.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 6 | 7 | import lombok.EqualsAndHashCode; 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | import lombok.ToString; 11 | 12 | @Getter 13 | @Setter 14 | @ToString 15 | @EqualsAndHashCode 16 | @JsonInclude(JsonInclude.Include.NON_NULL) 17 | @JsonPropertyOrder({ 18 | "description", 19 | "value", 20 | "state", 21 | "field" 22 | }) 23 | public class Field { 24 | 25 | @JsonProperty("description") 26 | private String description; 27 | 28 | @JsonProperty("value") 29 | private Object value; // Value can be either a String or an Object 30 | 31 | @JsonProperty("state") 32 | private String state; 33 | 34 | @JsonProperty("field") 35 | private String field; 36 | } 37 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/GenerateEntity.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.fasterxml.jackson.annotation.JsonInclude; 7 | import com.fasterxml.jackson.annotation.JsonProperty; 8 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 9 | 10 | import lombok.EqualsAndHashCode; 11 | import lombok.Getter; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @Getter 16 | @Setter 17 | @ToString 18 | @EqualsAndHashCode 19 | @JsonInclude(JsonInclude.Include.NON_NULL) 20 | @JsonPropertyOrder({ 21 | "fields", 22 | "entity" 23 | }) 24 | public class GenerateEntity { 25 | 26 | @JsonProperty("fields") 27 | private List fields; 28 | 29 | @JsonProperty("entity") 30 | private Map entity; // Assuming 'entity' is an arbitrary JSON object 31 | } 32 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/InstantiateErrorResponse.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 7 | 8 | import lombok.Data; 9 | 10 | @Data 11 | @JsonIgnoreProperties(ignoreUnknown = true) 12 | public class InstantiateErrorResponse { 13 | private List errors; 14 | 15 | @Data 16 | @JsonIgnoreProperties(ignoreUnknown = true) 17 | public static class ErrorDetail { 18 | private List path; 19 | private String property; 20 | private String message; 21 | private Schema schema; 22 | } 23 | 24 | @Data 25 | @JsonIgnoreProperties(ignoreUnknown = true) 26 | public static class Schema { 27 | private String title; 28 | private List required; 29 | private Map properties; 30 | } 31 | 32 | @Data 33 | @JsonIgnoreProperties(ignoreUnknown = true) 34 | public static class PropertyDetail { 35 | private String title; 36 | private String type; 37 | private String description; 38 | private String defaultValue; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/InstantiateRequest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import java.util.Map; 4 | 5 | import com.fasterxml.jackson.annotation.JsonInclude; 6 | import com.fasterxml.jackson.annotation.JsonProperty; 7 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 8 | 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.Setter; 12 | import lombok.ToString; 13 | 14 | @Getter 15 | @Setter 16 | @ToString 17 | @EqualsAndHashCode 18 | @JsonInclude(JsonInclude.Include.NON_NULL) 19 | @JsonPropertyOrder({ 20 | "templateRef", 21 | "values", 22 | "secrets" 23 | }) 24 | public class InstantiateRequest { 25 | 26 | @JsonProperty("templateRef") 27 | private String templateRef; 28 | @JsonProperty("values") 29 | private Map values; 30 | @JsonProperty("secrets") 31 | private Map secrets; 32 | } 33 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/InstantiateResponse.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 6 | 7 | import lombok.EqualsAndHashCode; 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | import lombok.ToString; 11 | 12 | @Getter 13 | @Setter 14 | @ToString 15 | @EqualsAndHashCode 16 | @JsonInclude(JsonInclude.Include.NON_NULL) 17 | @JsonPropertyOrder({ 18 | "id" 19 | }) 20 | public class InstantiateResponse { 21 | 22 | @JsonProperty("id") 23 | private String id; 24 | } 25 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/LocationItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 6 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 7 | 8 | import lombok.EqualsAndHashCode; 9 | import lombok.Getter; 10 | import lombok.Setter; 11 | import lombok.ToString; 12 | 13 | @JsonInclude(JsonInclude.Include.NON_NULL) 14 | @JsonPropertyOrder({ 15 | "data", 16 | }) 17 | @Getter 18 | @Setter 19 | @ToString 20 | @EqualsAndHashCode 21 | public class LocationItem { 22 | 23 | public LocationItem() { 24 | } 25 | 26 | @JsonProperty("data") 27 | @JsonPropertyDescription("The data of the location.") 28 | private LocationEntry data; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/PageInfo.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 5 | 6 | import lombok.AllArgsConstructor; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.Setter; 11 | import lombok.ToString; 12 | 13 | @JsonInclude(JsonInclude.Include.NON_NULL) 14 | @JsonPropertyOrder({ 15 | "nextCursor", 16 | "prevCursor", 17 | }) 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Getter 21 | @Setter 22 | @ToString 23 | @EqualsAndHashCode 24 | public class PageInfo { 25 | private String nextCursor; 26 | private String prevCursor; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /client/src/main/java/io/quarkiverse/backstage/client/model/RefreshEntity.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.client.model; 2 | 3 | import jakarta.validation.constraints.Size; 4 | 5 | import com.fasterxml.jackson.annotation.JsonInclude; 6 | import com.fasterxml.jackson.annotation.JsonProperty; 7 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 8 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 9 | 10 | import lombok.EqualsAndHashCode; 11 | import lombok.Getter; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "entityRef", 18 | }) 19 | @Getter 20 | @Setter 21 | @ToString 22 | @EqualsAndHashCode 23 | public class RefreshEntity { 24 | 25 | @JsonProperty("entityRef") 26 | @JsonPropertyDescription("The refence to the entity to refresh. This can be in the form of kind:namespace/name.") 27 | @Size(min = 1) 28 | private String entityRef; 29 | 30 | public RefreshEntity() { 31 | } 32 | 33 | public RefreshEntity(@Size(min = 1) String entityRef) { 34 | this.entityRef = entityRef; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/handlers/GetBackstageEntitiesAsStringHandler.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.handlers; 2 | 3 | import java.nio.file.Path; 4 | import java.util.List; 5 | import java.util.function.BiConsumer; 6 | import java.util.function.Consumer; 7 | 8 | import io.quarkiverse.backstage.common.utils.Serialization; 9 | import io.quarkiverse.backstage.spi.CatalogInfoRequiredFileBuildItem; 10 | import io.quarkiverse.backstage.spi.EntityListBuildItem; 11 | import io.quarkus.builder.BuildResult; 12 | 13 | public class GetBackstageEntitiesAsStringHandler implements BiConsumer { 14 | 15 | @Override 16 | public void accept(Object context, BuildResult buildResult) { 17 | EntityListBuildItem entityListBuildItem = buildResult.consume(EntityListBuildItem.class); 18 | Consumer consumer = (Consumer) context; 19 | consumer.accept(Serialization.asYaml(entityListBuildItem.getEntityList())); 20 | List catalogInfoRequiredFileBuildItem = buildResult 21 | .consumeMulti(CatalogInfoRequiredFileBuildItem.class); 22 | HandlerProcessor processor = (HandlerProcessor) context; 23 | processor.process(Serialization.asYaml(entityListBuildItem.getEntityList()), 24 | catalogInfoRequiredFileBuildItem.stream().map(CatalogInfoRequiredFileBuildItem::getPath).toArray(Path[]::new)); 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/handlers/GetBackstageEntitiesHandler.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.handlers; 2 | 3 | import java.nio.file.Path; 4 | import java.util.List; 5 | import java.util.function.BiConsumer; 6 | 7 | import io.quarkiverse.backstage.spi.CatalogInfoRequiredFileBuildItem; 8 | import io.quarkiverse.backstage.spi.EntityListBuildItem; 9 | import io.quarkiverse.backstage.v1alpha1.EntityList; 10 | import io.quarkus.builder.BuildResult; 11 | 12 | public class GetBackstageEntitiesHandler implements BiConsumer { 13 | 14 | @Override 15 | public void accept(Object context, BuildResult buildResult) { 16 | EntityListBuildItem entityListBuildItem = buildResult.consume(EntityListBuildItem.class); 17 | List catalogInfoRequiredFileBuildItem = buildResult 18 | .consumeMulti(CatalogInfoRequiredFileBuildItem.class); 19 | HandlerProcessor processor = (HandlerProcessor) context; 20 | processor.process(entityListBuildItem.getEntityList(), 21 | catalogInfoRequiredFileBuildItem.stream().map(CatalogInfoRequiredFileBuildItem::getPath).toArray(Path[]::new)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/handlers/HandlerProcessor.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.handlers; 2 | 3 | import java.nio.file.Path; 4 | 5 | public interface HandlerProcessor { 6 | 7 | void process(T obj, Path... additionalPaths); 8 | } 9 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/utils/Namespaces.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.utils; 2 | 3 | public final class Namespaces { 4 | 5 | public static String addNamespace(String content, String namespace) { 6 | // Split content into lines for processing 7 | String[] lines = content.split("\\r?\\n"); 8 | StringBuilder result = new StringBuilder(); 9 | boolean inMetadataSection = false; 10 | boolean namespaceAdded = false; 11 | 12 | for (String line : lines) { 13 | if (line.startsWith("metadata:")) { 14 | inMetadataSection = true; 15 | result.append(line).append("\n"); 16 | continue; 17 | } 18 | 19 | if (inMetadataSection) { 20 | // Check if namespace already exists 21 | if (line.matches("^\\s*namespace:")) { 22 | // Replace the existing namespace 23 | line = line.replaceAll("namespace:.*", "namespace: " + namespace); 24 | result.append(line).append("\n"); 25 | namespaceAdded = true; 26 | continue; 27 | } 28 | 29 | // Check for the end of the metadata section 30 | if (!line.startsWith(" ") && !line.isEmpty()) { 31 | inMetadataSection = false; 32 | 33 | // If namespace was not added, add it now 34 | if (!namespaceAdded) { 35 | result.append(" namespace: ").append(namespace).append("\n"); 36 | namespaceAdded = true; 37 | } 38 | } 39 | } 40 | result.append(line).append("\n"); 41 | } 42 | return result.toString(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/ApplyLifecycle.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors; 2 | 3 | import io.quarkiverse.backstage.common.visitors.api.ApplyApiLifecycle; 4 | import io.quarkiverse.backstage.common.visitors.component.ApplyComponentLifecycle; 5 | import io.quarkiverse.backstage.model.builder.BaseFluent; 6 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 7 | 8 | public class ApplyLifecycle extends TypedVisitor> { 9 | 10 | private final String lifecycle; 11 | private final boolean force; 12 | 13 | public ApplyLifecycle(String lifecycle) { 14 | this(lifecycle, false); 15 | } 16 | 17 | public ApplyLifecycle(String lifecycle, boolean force) { 18 | this.lifecycle = lifecycle; 19 | this.force = force; 20 | } 21 | 22 | @Override 23 | public void visit(BaseFluent fluent) { 24 | fluent.accept(new ApplyApiLifecycle(lifecycle, force)); 25 | fluent.accept(new ApplyComponentLifecycle(lifecycle, force)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/ApplyMetadataAnnotation.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors; 2 | 3 | import java.util.Optional; 4 | 5 | import io.quarkiverse.backstage.EntityMetaFluent; 6 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 7 | 8 | public class ApplyMetadataAnnotation extends TypedVisitor> { 9 | 10 | private final String key; 11 | private final Optional value; 12 | 13 | public ApplyMetadataAnnotation(String key, String value) { 14 | this(key, Optional.of(value)); 15 | } 16 | 17 | public ApplyMetadataAnnotation(String key, Optional value) { 18 | this.key = key; 19 | this.value = value; 20 | } 21 | 22 | @Override 23 | public void visit(EntityMetaFluent meta) { 24 | value.ifPresent(v -> { 25 | meta.addToAnnotations(key, v); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/ApplyMetadataDescription.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors; 2 | 3 | import io.quarkiverse.backstage.EntityMetaFluent; 4 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 5 | 6 | public class ApplyMetadataDescription extends TypedVisitor> { 7 | 8 | private final String description; 9 | 10 | public ApplyMetadataDescription(String description) { 11 | this.description = description; 12 | } 13 | 14 | @Override 15 | public void visit(EntityMetaFluent meta) { 16 | meta.withDescription(description); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/ApplyMetadataLabel.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors; 2 | 3 | import java.util.Optional; 4 | 5 | import io.quarkiverse.backstage.EntityMetaFluent; 6 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 7 | 8 | public class ApplyMetadataLabel extends TypedVisitor> { 9 | 10 | private final String key; 11 | private final Optional value; 12 | 13 | public ApplyMetadataLabel(String key, String value) { 14 | this(key, Optional.of(value)); 15 | } 16 | 17 | public ApplyMetadataLabel(String key, Optional value) { 18 | this.key = key; 19 | this.value = value; 20 | } 21 | 22 | @Override 23 | public void visit(EntityMetaFluent meta) { 24 | value.ifPresent(v -> { 25 | meta.addToLabels(key, v); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/ApplyMetadataName.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors; 2 | 3 | import io.quarkiverse.backstage.EntityMetaFluent; 4 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 5 | 6 | public class ApplyMetadataName extends TypedVisitor> { 7 | 8 | private final String name; 9 | 10 | public ApplyMetadataName(String name) { 11 | this.name = name; 12 | } 13 | 14 | @Override 15 | public void visit(EntityMetaFluent meta) { 16 | meta.withName(name); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/ApplyMetadataTag.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors; 2 | 3 | import io.quarkiverse.backstage.EntityMetaFluent; 4 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 5 | 6 | public class ApplyMetadataTag extends TypedVisitor> { 7 | 8 | private final String tag; 9 | 10 | public ApplyMetadataTag(String tag) { 11 | this.tag = tag; 12 | } 13 | 14 | @Override 15 | public void visit(EntityMetaFluent meta) { 16 | if (meta.hasTags() && meta.hasMatchingTag(t -> t.equals(tag))) { 17 | return; 18 | } 19 | meta.addToTags(tag); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/ApplyMetadataTitle.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors; 2 | 3 | import io.quarkiverse.backstage.EntityMetaFluent; 4 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 5 | 6 | public class ApplyMetadataTitle extends TypedVisitor> { 7 | 8 | private final String title; 9 | 10 | public ApplyMetadataTitle(String title) { 11 | this.title = title; 12 | } 13 | 14 | @Override 15 | public void visit(EntityMetaFluent meta) { 16 | meta.withTitle(title); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/ApplyOwner.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors; 2 | 3 | import io.quarkiverse.backstage.common.visitors.api.ApplyApiOwner; 4 | import io.quarkiverse.backstage.common.visitors.component.ApplyComponentOwner; 5 | import io.quarkiverse.backstage.model.builder.BaseFluent; 6 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 7 | 8 | public class ApplyOwner extends TypedVisitor> { 9 | 10 | private final String owner; 11 | private final boolean force; 12 | 13 | public ApplyOwner(String owner) { 14 | this(owner, false); 15 | } 16 | 17 | public ApplyOwner(String owner, boolean force) { 18 | this.owner = owner; 19 | this.force = force; 20 | } 21 | 22 | @Override 23 | public void visit(BaseFluent fluent) { 24 | fluent.accept(new ApplyApiOwner(owner, force)); 25 | fluent.accept(new ApplyComponentOwner(owner, force)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/ApplyType.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors; 2 | 3 | import io.quarkiverse.backstage.common.visitors.api.ApplyApiType; 4 | import io.quarkiverse.backstage.common.visitors.component.ApplyComponentType; 5 | import io.quarkiverse.backstage.model.builder.BaseFluent; 6 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 7 | 8 | public class ApplyType extends TypedVisitor> { 9 | 10 | private final String type; 11 | private final boolean force; 12 | 13 | public ApplyType(String type) { 14 | this(type, false); 15 | } 16 | 17 | public ApplyType(String type, boolean force) { 18 | this.type = type; 19 | this.force = force; 20 | } 21 | 22 | @Override 23 | public void visit(BaseFluent fluent) { 24 | fluent.accept(new ApplyApiType(type, force)); 25 | fluent.accept(new ApplyComponentType(type, force)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/api/ApplyApiDescription.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.api; 2 | 3 | import io.quarkiverse.backstage.common.visitors.ApplyMetadataDescription; 4 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 5 | import io.quarkiverse.backstage.v1alpha1.ApiFluent; 6 | 7 | public class ApplyApiDescription extends TypedVisitor> { 8 | 9 | private final String description; 10 | 11 | public ApplyApiDescription(String description) { 12 | this.description = description; 13 | } 14 | 15 | @Override 16 | public void visit(ApiFluent api) { 17 | api.accept(new ApplyMetadataDescription(description)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/api/ApplyApiLifecycle.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.api; 2 | 3 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 4 | import io.quarkiverse.backstage.v1alpha1.ApiSpecFluent; 5 | 6 | public class ApplyApiLifecycle extends TypedVisitor> { 7 | 8 | private final String lifecycle; 9 | private final boolean force; 10 | 11 | public ApplyApiLifecycle(String lifecycle) { 12 | this(lifecycle, false); 13 | } 14 | 15 | public ApplyApiLifecycle(String lifecycle, boolean force) { 16 | this.lifecycle = lifecycle; 17 | this.force = force; 18 | } 19 | 20 | @Override 21 | public void visit(ApiSpecFluent spec) { 22 | if (force || !spec.hasLifecycle()) { 23 | spec.withLifecycle(lifecycle); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/api/ApplyApiOwner.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.api; 2 | 3 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 4 | import io.quarkiverse.backstage.v1alpha1.ApiSpecFluent; 5 | 6 | public class ApplyApiOwner extends TypedVisitor> { 7 | 8 | private final String owner; 9 | private final boolean force; 10 | 11 | public ApplyApiOwner(String owner) { 12 | this(owner, false); 13 | } 14 | 15 | public ApplyApiOwner(String owner, boolean force) { 16 | this.owner = owner; 17 | this.force = force; 18 | } 19 | 20 | @Override 21 | public void visit(ApiSpecFluent spec) { 22 | if (force || !spec.hasOwner()) { 23 | spec.withOwner(owner); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/api/ApplyApiTitle.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.api; 2 | 3 | import io.quarkiverse.backstage.common.visitors.ApplyMetadataTitle; 4 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 5 | import io.quarkiverse.backstage.v1alpha1.ApiFluent; 6 | 7 | public class ApplyApiTitle extends TypedVisitor> { 8 | 9 | private final String title; 10 | 11 | public ApplyApiTitle(String title) { 12 | this.title = title; 13 | } 14 | 15 | @Override 16 | public void visit(ApiFluent api) { 17 | api.accept(new ApplyMetadataTitle(title)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/api/ApplyApiType.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.api; 2 | 3 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 4 | import io.quarkiverse.backstage.v1alpha1.ApiSpecFluent; 5 | 6 | public class ApplyApiType extends TypedVisitor> { 7 | 8 | private final String type; 9 | private final boolean force; 10 | 11 | public ApplyApiType(String type) { 12 | this(type, false); 13 | } 14 | 15 | public ApplyApiType(String type, boolean force) { 16 | this.type = type; 17 | this.force = force; 18 | } 19 | 20 | @Override 21 | public void visit(ApiSpecFluent spec) { 22 | if (force || !spec.hasType()) { 23 | spec.withType(type); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/api/ApplyOpenApiDefinitionPath.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.api; 2 | 3 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 4 | import io.quarkiverse.backstage.v1alpha1.ApiSpecFluent; 5 | 6 | public class ApplyOpenApiDefinitionPath extends TypedVisitor> { 7 | 8 | private final String path; 9 | 10 | public ApplyOpenApiDefinitionPath(String path) { 11 | this.path = path; 12 | } 13 | 14 | @Override 15 | public void visit(ApiSpecFluent spec) { 16 | spec.withNewPathApiDefintionDefinition(path); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/component/AddComponentApis.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.component; 2 | 3 | import java.util.List; 4 | import java.util.Optional; 5 | 6 | import io.quarkiverse.backstage.EntityMeta; 7 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 8 | import io.quarkiverse.backstage.v1alpha1.ComponentFluent; 9 | import io.quarkiverse.backstage.v1alpha1.ComponentSpecFluent; 10 | 11 | public class AddComponentApis extends TypedVisitor> { 12 | 13 | private final String[] apis; 14 | 15 | public AddComponentApis(List apis) { 16 | this(apis.toArray(new String[apis.size()])); 17 | } 18 | 19 | public AddComponentApis(String... apis) { 20 | this.apis = apis; 21 | } 22 | 23 | @Override 24 | public void visit(ComponentFluent component) { 25 | component.accept(new AddApis(component.buildMetadata(), apis)); 26 | } 27 | 28 | private class AddApis extends TypedVisitor> { 29 | private final EntityMeta meta; 30 | private final String[] apis; 31 | 32 | public AddApis(EntityMeta meta, String... apis) { 33 | this.meta = meta; 34 | this.apis = apis; 35 | } 36 | 37 | @Override 38 | public void visit(ComponentSpecFluent spec) { 39 | for (String api : apis) { 40 | String namespace = Optional.ofNullable(meta).flatMap(EntityMeta::getNamespace).orElse("default"); 41 | String apiRef = "api:" + namespace + "/" + api; 42 | spec.addToProvidesApis(api); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/component/AddComponentDependencies.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.component; 2 | 3 | import java.util.List; 4 | import java.util.Optional; 5 | 6 | import io.quarkiverse.backstage.EntityMeta; 7 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 8 | import io.quarkiverse.backstage.v1alpha1.ComponentFluent; 9 | import io.quarkiverse.backstage.v1alpha1.ComponentSpecFluent; 10 | 11 | public class AddComponentDependencies extends TypedVisitor> { 12 | 13 | private final String[] dependencies; 14 | 15 | public AddComponentDependencies(List dependencies) { 16 | this(dependencies.toArray(new String[dependencies.size()])); 17 | } 18 | 19 | public AddComponentDependencies(String... dependencies) { 20 | this.dependencies = dependencies; 21 | } 22 | 23 | @Override 24 | public void visit(ComponentFluent component) { 25 | component.accept(new AddDependencies(component.buildMetadata(), dependencies)); 26 | } 27 | 28 | private class AddDependencies extends TypedVisitor> { 29 | private final EntityMeta meta; 30 | private final String[] dependencies; 31 | 32 | public AddDependencies(EntityMeta meta, String... dependencies) { 33 | this.meta = meta; 34 | this.dependencies = dependencies; 35 | } 36 | 37 | @Override 38 | public void visit(ComponentSpecFluent spec) { 39 | for (String dependency : dependencies) { 40 | String namespace = Optional.ofNullable(meta).flatMap(EntityMeta::getNamespace).orElse("default"); 41 | String dependencyRef = "component:" + namespace + "/" + dependency; 42 | spec.addToDependsOn(dependencyRef); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/component/ApplyComponentAnnotation.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.component; 2 | 3 | import java.util.Optional; 4 | 5 | import io.quarkiverse.backstage.common.visitors.ApplyMetadataAnnotation; 6 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 7 | import io.quarkiverse.backstage.v1alpha1.ComponentFluent; 8 | 9 | public class ApplyComponentAnnotation extends TypedVisitor> { 10 | 11 | private final String key; 12 | private final Optional value; 13 | 14 | public ApplyComponentAnnotation(String key, String value) { 15 | this(key, Optional.ofNullable(value)); 16 | } 17 | 18 | public ApplyComponentAnnotation(String key, Optional value) { 19 | this.key = key; 20 | this.value = value; 21 | } 22 | 23 | @Override 24 | public void visit(ComponentFluent component) { 25 | component.accept(new ApplyMetadataAnnotation(key, value)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/component/ApplyComponentLabel.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.component; 2 | 3 | import java.util.Optional; 4 | 5 | import io.quarkiverse.backstage.common.visitors.ApplyMetadataLabel; 6 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 7 | import io.quarkiverse.backstage.v1alpha1.ComponentFluent; 8 | 9 | public class ApplyComponentLabel extends TypedVisitor> { 10 | 11 | private final String key; 12 | private final Optional value; 13 | 14 | public ApplyComponentLabel(String key, String value) { 15 | this(key, Optional.ofNullable(value)); 16 | } 17 | 18 | public ApplyComponentLabel(String key, Optional value) { 19 | this.key = key; 20 | this.value = value; 21 | } 22 | 23 | @Override 24 | public void visit(ComponentFluent component) { 25 | component.accept(new ApplyMetadataLabel(key, value)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/component/ApplyComponentLifecycle.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.component; 2 | 3 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 4 | import io.quarkiverse.backstage.v1alpha1.ComponentSpecFluent; 5 | 6 | public class ApplyComponentLifecycle extends TypedVisitor> { 7 | 8 | private final String lifecycle; 9 | private final boolean force; 10 | 11 | public ApplyComponentLifecycle(String lifecycle) { 12 | this(lifecycle, false); 13 | } 14 | 15 | public ApplyComponentLifecycle(String lifecycle, boolean force) { 16 | this.lifecycle = lifecycle; 17 | this.force = force; 18 | } 19 | 20 | @Override 21 | public void visit(ComponentSpecFluent spec) { 22 | if (force || !spec.hasLifecycle()) { 23 | spec.withLifecycle(lifecycle); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/component/ApplyComponentName.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.component; 2 | 3 | import io.quarkiverse.backstage.common.visitors.ApplyMetadataName; 4 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 5 | import io.quarkiverse.backstage.v1alpha1.ComponentFluent; 6 | 7 | public class ApplyComponentName extends TypedVisitor> { 8 | 9 | private final String name; 10 | 11 | public ApplyComponentName(String name) { 12 | this.name = name; 13 | } 14 | 15 | @Override 16 | public void visit(ComponentFluent component) { 17 | component.accept(new ApplyMetadataName(name)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/component/ApplyComponentOwner.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.component; 2 | 3 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 4 | import io.quarkiverse.backstage.v1alpha1.ComponentSpecFluent; 5 | 6 | public class ApplyComponentOwner extends TypedVisitor> { 7 | 8 | private final String owner; 9 | private final boolean force; 10 | 11 | public ApplyComponentOwner(String owner) { 12 | this(owner, false); 13 | } 14 | 15 | public ApplyComponentOwner(String owner, boolean force) { 16 | this.owner = owner; 17 | this.force = force; 18 | } 19 | 20 | @Override 21 | public void visit(ComponentSpecFluent spec) { 22 | if (force || !spec.hasOwner()) { 23 | spec.withOwner(owner); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/component/ApplyComponentTag.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.component; 2 | 3 | import io.quarkiverse.backstage.common.visitors.ApplyMetadataTag; 4 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 5 | import io.quarkiverse.backstage.v1alpha1.ComponentFluent; 6 | 7 | public class ApplyComponentTag extends TypedVisitor> { 8 | 9 | private final String tag; 10 | 11 | public ApplyComponentTag(String tag) { 12 | this.tag = tag; 13 | } 14 | 15 | @Override 16 | public void visit(ComponentFluent component) { 17 | component.accept(new ApplyMetadataTag(tag)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/component/ApplyComponentType.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.component; 2 | 3 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 4 | import io.quarkiverse.backstage.v1alpha1.ComponentSpecFluent; 5 | 6 | public class ApplyComponentType extends TypedVisitor> { 7 | 8 | private final String type; 9 | private final boolean force; 10 | 11 | public ApplyComponentType(String type) { 12 | this(type, false); 13 | } 14 | 15 | public ApplyComponentType(String type, boolean force) { 16 | this.type = type; 17 | this.force = force; 18 | } 19 | 20 | @Override 21 | public void visit(ComponentSpecFluent spec) { 22 | if (force || !spec.hasType()) { 23 | spec.withType(type); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/template/AddDebugWaitStep.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.template; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class AddDebugWaitStep extends AddNewTemplateStep { 7 | 8 | private int seconds = 10; 9 | 10 | public AddDebugWaitStep(String id) { 11 | this(id, 5); 12 | } 13 | 14 | public AddDebugWaitStep(String id, int seconds) { 15 | super(id, "Waiting", "debug:wait"); 16 | } 17 | 18 | @Override 19 | public Map getInput() { 20 | Map result = new HashMap<>(); 21 | result.put("seconds", seconds); 22 | return result; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/template/AddNewEntityRefToOutput.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.template; 2 | 3 | import java.util.Optional; 4 | 5 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 6 | import io.quarkiverse.backstage.scaffolder.v1beta3.OutputFluent; 7 | 8 | public class AddNewEntityRefToOutput extends TypedVisitor> { 9 | 10 | private final String title; 11 | private final String entityRef; 12 | private final Optional icon; 13 | 14 | public AddNewEntityRefToOutput(String title, String entityRef) { 15 | this(title, entityRef, Optional.empty()); 16 | } 17 | 18 | public AddNewEntityRefToOutput(String title, String entityRef, Optional icon) { 19 | this.title = title; 20 | this.entityRef = entityRef; 21 | this.icon = icon; 22 | } 23 | 24 | @Override 25 | public void visit(OutputFluent output) { 26 | output.addNewLink() 27 | .withTitle(title) 28 | .withEntityRef(entityRef) 29 | .withIcon(icon) 30 | .endLink(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/template/AddNewFetchTemplateStep.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.template; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | public class AddNewFetchTemplateStep extends AddNewTemplateStep { 8 | 9 | private String url; 10 | private boolean replace; 11 | private List ignore; 12 | private Map parameters; 13 | private Map values; 14 | 15 | public AddNewFetchTemplateStep(String id, String url, boolean replace, List ignore, Map parameters, 16 | Map values) { 17 | super(id, "Fetch Application Files", "fetch:template"); 18 | this.url = url; 19 | this.replace = replace; 20 | this.ignore = ignore; 21 | this.parameters = parameters; 22 | this.values = values; 23 | 24 | } 25 | 26 | @Override 27 | public Map getInput() { 28 | Map result = new HashMap<>(); 29 | Map newValues = new HashMap<>(values); 30 | result.put("url", url); 31 | result.put("replace", replace); 32 | result.put("copyWithoutTemplating", ignore.toArray(new String[ignore.size()])); 33 | result.put("values", newValues); 34 | parameters.forEach((k, v) -> newValues.put(k, "${{ parameters." + k + " }}")); 35 | return result; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/template/AddNewTemplateParameter.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.template; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 7 | import io.quarkiverse.backstage.scaffolder.v1beta3.ParameterFluent; 8 | import io.quarkiverse.backstage.scaffolder.v1beta3.Property; 9 | import io.quarkiverse.backstage.scaffolder.v1beta3.TemplateSpecFluent; 10 | 11 | public class AddNewTemplateParameter extends TypedVisitor> { 12 | 13 | private final String title; 14 | private final List properties; 15 | 16 | public AddNewTemplateParameter(String title, List properties) { 17 | this.title = title; 18 | this.properties = properties; 19 | } 20 | 21 | public AddNewTemplateParameter(String title, Property... properties) { 22 | this.title = title; 23 | this.properties = Arrays.asList(properties); 24 | } 25 | 26 | @Override 27 | public void visit(TemplateSpecFluent spec) { 28 | spec.addNewParameter() 29 | .withTitle(title) 30 | .accept(ParameterFluent.class, parameter -> { 31 | for (Property property : properties) { 32 | parameter.addToProperties(property.getName(), property); 33 | if (property.isRequired()) { 34 | parameter.addToRequired(property.getName()); 35 | } 36 | } 37 | }).endParameter(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/template/AddNewTemplateStep.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.template; 2 | 3 | import java.util.Collections; 4 | import java.util.Map; 5 | 6 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 7 | import io.quarkiverse.backstage.scaffolder.v1beta3.TemplateSpecFluent; 8 | 9 | public class AddNewTemplateStep extends TypedVisitor> { 10 | 11 | private final String id; 12 | private final String name; 13 | private final String action; 14 | private final Map input; 15 | 16 | public AddNewTemplateStep(String id, String name, String action) { 17 | this(id, name, action, Collections.emptyMap()); 18 | } 19 | 20 | public AddNewTemplateStep(String id, String name, String action, Map input) { 21 | this.id = id; 22 | this.name = name; 23 | this.action = action; 24 | this.input = input; 25 | } 26 | 27 | @Override 28 | public void visit(TemplateSpecFluent spec) { 29 | spec.addNewStep() 30 | .withId(id) 31 | .withName(name) 32 | .withAction(action) 33 | .withInput(getInput()) 34 | .endStep(); 35 | } 36 | 37 | public Map getInput() { 38 | return input; 39 | } 40 | 41 | @Override 42 | public int order() { 43 | return super.order(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/template/AddNewUrlToOutput.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.template; 2 | 3 | import java.util.Optional; 4 | 5 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 6 | import io.quarkiverse.backstage.scaffolder.v1beta3.OutputFluent; 7 | 8 | public class AddNewUrlToOutput extends TypedVisitor> { 9 | 10 | private final String title; 11 | private final String url; 12 | private final Optional icon; 13 | 14 | public AddNewUrlToOutput(String title, String url) { 15 | this(title, url, Optional.empty()); 16 | } 17 | 18 | public AddNewUrlToOutput(String title, String url, Optional icon) { 19 | this.title = title; 20 | this.url = url; 21 | this.icon = icon; 22 | } 23 | 24 | @Override 25 | public void visit(OutputFluent output) { 26 | output.addNewLink() 27 | .withTitle(title) 28 | .withUrl(url) 29 | .withIcon(icon) 30 | .endLink(); 31 | } 32 | 33 | public String getTitle() { 34 | return title; 35 | } 36 | 37 | public String getUrl() { 38 | return url; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/template/AddPublishGiteaStep.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.template; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class AddPublishGiteaStep extends AddNewTemplateStep { 7 | 8 | public AddPublishGiteaStep(String id) { 9 | super(id, "Publish to Gitea", "publish:gitea"); 10 | } 11 | 12 | @Override 13 | public Map getInput() { 14 | Map result = new HashMap<>(); 15 | result.put("name", "${{ parameters.componentId }}"); 16 | result.put("description", "This is ${{ parameters.description }}"); 17 | result.put("repoUrl", "${{ parameters.repoHost }}?owner=${{ parameters.repoOrg }}&repo=${{ parameters.repoName }}"); 18 | result.put("defaultBranch", "main"); 19 | result.put("repoVisibility", "${{ parameters.repoVisibility }}"); 20 | return result; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/template/AddPublishGithubStep.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.template; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class AddPublishGithubStep extends AddNewTemplateStep { 7 | 8 | public AddPublishGithubStep(String id) { 9 | super(id, "Publish to Github", "publish:github"); 10 | } 11 | 12 | @Override 13 | public Map getInput() { 14 | Map result = new HashMap<>(); 15 | result.put("allowedHosts", "['github.com']"); 16 | result.put("description", "This is ${{ parameters.description }}"); 17 | result.put("repoUrl", "${{ parameters.repoHost }}?owner=${{ parameters.repoOrg }}&repo=${{ parameters.repoName }}"); 18 | result.put("defaultBranch", "main"); 19 | result.put("protectDefaultBranch", false); 20 | result.put("repoVisibility", "${{ parameters.repo.visibility }}"); 21 | return result; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/template/ApplyPublishGiteaStep.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.template; 2 | 3 | import java.util.Collections; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 9 | import io.quarkiverse.backstage.scaffolder.v1beta3.TemplateSpecFluent; 10 | 11 | public class ApplyPublishGiteaStep extends TypedVisitor> { 12 | 13 | private static List BACKSTAGE_PUBLISH_STEP_ACTIONS = List.of("publish:github", "publish:bitbucket", 14 | "publish:azure"); 15 | 16 | @Override 17 | public void visit(TemplateSpecFluent spec) { 18 | spec.editMatchingStep(step -> BACKSTAGE_PUBLISH_STEP_ACTIONS.contains(step.getAction())) 19 | .withId("publish:gitea") 20 | .withName("Publish to Gitea") 21 | .withAction("publish:gitea") 22 | .withInput(createInput(Collections.emptyMap())) 23 | .endStep(); 24 | } 25 | 26 | private static Map createInput(Map parameters) { 27 | Map result = new HashMap<>(); 28 | result.put("name", "${{ parameters.componentId }}"); 29 | result.put("description", "This is ${{ parameters.description }}"); 30 | result.put("repoUrl", "${{ parameters.repoHost }}?owner=${{ parameters.repoOrg }}&repo=${{ parameters.repoName }}"); 31 | result.put("defaultBranch", "main"); 32 | result.put("repoVisibility", "${{ parameters.repoVisibility }}"); 33 | return result; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/template/ApplyRegisterGiteaHostedComponentStep.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.template; 2 | 3 | import java.util.Map; 4 | 5 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 6 | import io.quarkiverse.backstage.scaffolder.v1beta3.StepFluent; 7 | 8 | public class ApplyRegisterGiteaHostedComponentStep extends TypedVisitor> { 9 | 10 | private static final String CATALOG_REGISTER = "catalog:register"; 11 | 12 | @Override 13 | public void visit(StepFluent step) { 14 | if (CATALOG_REGISTER.equals(step.getAction())) { 15 | step.withInput(Map.of("catalogInfoUrl", 16 | "http://${{ parameters.repoHost }}/${{ parameters.repoOrg }}/${{ parameters.repoName }}/src/branch/${{ parameters.repoBranch}}/catalog-info.yaml")); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/template/RemoveNonDevFriendlySteps.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.template; 2 | 3 | import java.util.List; 4 | 5 | import io.quarkiverse.backstage.model.builder.TypedVisitor; 6 | import io.quarkiverse.backstage.scaffolder.v1beta3.TemplateSpecFluent; 7 | 8 | public class RemoveNonDevFriendlySteps extends TypedVisitor> { 9 | 10 | private final List devFriendlyActions; 11 | 12 | public RemoveNonDevFriendlySteps(List devFriendlyActions) { 13 | this.devFriendlyActions = devFriendlyActions; 14 | } 15 | 16 | @Override 17 | public void visit(TemplateSpecFluent spec) { 18 | spec.removeMatchingFromSteps(step -> !devFriendlyActions.contains(step.getAction())); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /common/src/main/java/io/quarkiverse/backstage/common/visitors/template/UseGiteaInPublishStep.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.visitors.template; 2 | 3 | import java.util.Collections; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | public class UseGiteaInPublishStep extends AddNewTemplateStep { 8 | 9 | public UseGiteaInPublishStep(String id) { 10 | this(id, Collections.emptyMap()); 11 | } 12 | 13 | public UseGiteaInPublishStep(String id, Map parameters) { 14 | super(id, "Publish to Gitea", "publish:gitea", createInput(parameters)); 15 | } 16 | 17 | private static Map createInput(Map parameters) { 18 | Map result = new HashMap<>(); 19 | Map values = new HashMap<>(); 20 | result.put("name", "${{ parameters.componentId }}"); 21 | result.put("description", "This is ${{ parameters.description }}"); 22 | result.put("repoUrl", "${{ parameters.repoHost }}?owner=${{ parameters.repoOrg }}&repo=${{ parameters.repoName }}"); 23 | result.put("defaultBranch", "main"); 24 | result.put("repoVisibility", "${{ parameters.repoVisibility }}"); 25 | parameters.forEach((k, v) -> values.put(k, "${{ parameters." + k + " }}")); 26 | return result; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /common/src/test/java/io/quarkiverse/backstage/common/dsl/GiteaTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.common.dsl; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | public class GiteaTest { 8 | 9 | @Test 10 | void shouldGetHost() { 11 | String host = Gitea.getHost("http://localhost:3000/"); 12 | assertEquals("localhost", host); 13 | } 14 | 15 | @Test 16 | void shouldGetPort() { 17 | assertEquals(3000, Gitea.getPort("http://localhost:3000")); 18 | assertEquals(3000, Gitea.getPort("http://localhost:3000/some/path")); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /deployment/src/main/java/io/quarkiverse/backstage/deployment/IsDevTemplateGenerationEnabled.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.deployment; 2 | 3 | import java.util.function.BooleanSupplier; 4 | 5 | import io.quarkiverse.backstage.deployment.devservices.BackstageDevServicesConfig; 6 | 7 | public class IsDevTemplateGenerationEnabled implements BooleanSupplier { 8 | 9 | BackstageConfiguration config; 10 | BackstageDevServicesConfig devServicesConfig; 11 | 12 | @Override 13 | public boolean getAsBoolean() { 14 | return config.devTemplate().generation().enabled() || devServicesConfig.devTemplate().installation().enabled(); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /deployment/src/main/java/io/quarkiverse/backstage/deployment/IsTemplateGenerationEnabled.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.deployment; 2 | 3 | import java.util.function.BooleanSupplier; 4 | 5 | import io.quarkiverse.backstage.deployment.devservices.BackstageDevServicesConfig; 6 | 7 | public class IsTemplateGenerationEnabled implements BooleanSupplier { 8 | 9 | BackstageConfiguration config; 10 | BackstageDevServicesConfig devServicesConfig; 11 | 12 | @Override 13 | public boolean getAsBoolean() { 14 | return config.template().generation().enabled() || devServicesConfig.template().installation().enabled(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /deployment/src/main/java/io/quarkiverse/backstage/deployment/IsUserProvidedTemplateGenerationEnabled.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.deployment; 2 | 3 | import java.util.function.BooleanSupplier; 4 | 5 | import io.quarkiverse.backstage.deployment.devservices.BackstageDevServicesConfig; 6 | 7 | public class IsUserProvidedTemplateGenerationEnabled implements BooleanSupplier { 8 | 9 | BackstageConfiguration config; 10 | BackstageDevServicesConfig devServicesConfig; 11 | 12 | @Override 13 | public boolean getAsBoolean() { 14 | return config.userProvidedTemplates().generation().enabled() 15 | || devServicesConfig.userProvidedTemplates().installation().enabled(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /deployment/src/main/java/io/quarkiverse/backstage/deployment/Utils.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.deployment; 2 | 3 | import java.util.Optional; 4 | import java.util.regex.Matcher; 5 | import java.util.regex.Pattern; 6 | 7 | public final class Utils { 8 | 9 | private static final Pattern REST_CLIENT_URL_PATTERN = Pattern.compile("quarkus\\.rest-client\\.(?[^.]+)\\.url"); 10 | 11 | public static Optional getRestClientName(String propertyName) { 12 | Matcher matcher = REST_CLIENT_URL_PATTERN.matcher(propertyName); 13 | if (!matcher.matches()) { 14 | return Optional.empty(); 15 | } 16 | return Optional.of(matcher.group("name")); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /deployment/src/main/java/io/quarkiverse/backstage/deployment/devservices/BackstageDevServiceInfoBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.deployment.devservices; 2 | 3 | import io.quarkus.builder.item.SimpleBuildItem; 4 | 5 | public final class BackstageDevServiceInfoBuildItem extends SimpleBuildItem { 6 | 7 | private final String url; 8 | private final String token; 9 | 10 | public BackstageDevServiceInfoBuildItem(String url, String token) { 11 | this.url = url; 12 | this.token = token; 13 | } 14 | 15 | public String getUrl() { 16 | return url; 17 | } 18 | 19 | public String getToken() { 20 | return token; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /deployment/src/test/java/io/quarkiverse/backstage/deployment/SerializationTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.deployment; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertTrue; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | import com.fasterxml.jackson.annotation.JsonInclude.Include; 8 | import com.fasterxml.jackson.core.JsonProcessingException; 9 | import com.fasterxml.jackson.databind.ObjectMapper; 10 | import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; 11 | import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; 12 | import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; 13 | import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; 14 | 15 | import io.quarkiverse.backstage.v1alpha1.Api; 16 | import io.quarkiverse.backstage.v1alpha1.ApiBuilder; 17 | 18 | public class SerializationTest { 19 | 20 | private static YAMLFactory YAML_FACTORY = new YAMLFactory() 21 | .enable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER) 22 | .enable(YAMLGenerator.Feature.MINIMIZE_QUOTES); 23 | 24 | private static final ObjectMapper YAML_MAPPER = new YAMLMapper(YAML_FACTORY).registerModule(new Jdk8Module()) 25 | .setSerializationInclusion(Include.NON_EMPTY); 26 | 27 | @Test 28 | public void testApiSerialization() throws JsonProcessingException { 29 | Api api = new ApiBuilder() 30 | .withNewSpec() 31 | .withNewPathApiDefintionDefinition("/openapi") 32 | .endSpec() 33 | .build(); 34 | 35 | String s = YAML_MAPPER.writeValueAsString(api).replaceAll("!<.*>", ""); 36 | System.out.println(s); 37 | assertTrue(s.contains("$text: /openapi")); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /deployment/src/test/java/io/quarkiverse/backstage/deployment/UtilsTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.deployment; 2 | 3 | import static io.quarkiverse.backstage.deployment.Utils.getRestClientName; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | 6 | import java.util.Optional; 7 | 8 | import org.junit.jupiter.api.Test; 9 | 10 | public class UtilsTest { 11 | 12 | @Test 13 | public void testServiceNameExtraction() { 14 | assertEquals(getRestClientName("quarkus.rest-client.my-service.url"), Optional.of("my-service")); 15 | assertEquals(getRestClientName("quarkus.rest-client.other-service.url"), Optional.of("other-service")); 16 | assertEquals(getRestClientName("quarkus.rest-client.yet-another-service.url"), Optional.of("yet-another-service")); 17 | assertEquals(getRestClientName("quarkus.rest-client..url"), Optional.empty()); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /dev-service-image/.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | .yarn/cache 3 | .yarn/install-state.gz 4 | node_modules 5 | packages/*/src 6 | packages/*/node_modules 7 | plugins 8 | *.local.yaml 9 | -------------------------------------------------------------------------------- /dev-service-image/.eslintignore: -------------------------------------------------------------------------------- 1 | playwright.config.ts 2 | -------------------------------------------------------------------------------- /dev-service-image/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | }; 4 | -------------------------------------------------------------------------------- /dev-service-image/.gitignore: -------------------------------------------------------------------------------- 1 | # macOS 2 | .DS_Store 3 | 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | 12 | # Coverage directory generated when running tests with coverage 13 | coverage 14 | 15 | # Dependencies 16 | node_modules/ 17 | 18 | # Yarn files 19 | .pnp.* 20 | .yarn/* 21 | !.yarn/patches 22 | !.yarn/plugins 23 | !.yarn/releases 24 | !.yarn/sdks 25 | !.yarn/versions 26 | 27 | # Node version directives 28 | .nvmrc 29 | 30 | # dotenv environment variables file 31 | .env 32 | .env.test 33 | 34 | # Build output 35 | dist 36 | dist-types 37 | 38 | # Temporary change files created by Vim 39 | *.swp 40 | 41 | # MkDocs build output 42 | site 43 | 44 | # Local configuration files 45 | *.local.yaml 46 | 47 | # Sensitive credentials 48 | *-credentials.yaml 49 | 50 | # vscode database functionality support files 51 | *.session.sql 52 | 53 | # E2E test reports 54 | e2e-test-report/ 55 | -------------------------------------------------------------------------------- /dev-service-image/.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | dist-types 3 | coverage 4 | .vscode 5 | -------------------------------------------------------------------------------- /dev-service-image/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | yarnPath: .yarn/releases/yarn-4.4.1.cjs 4 | -------------------------------------------------------------------------------- /dev-service-image/app-config.argocd.yaml: -------------------------------------------------------------------------------- 1 | argocd: 2 | username: ${ARGOCD_ADMIN_USER} 3 | password: ${ARGOCD_ADMIN_PASSWORD} 4 | baseUrl: ${ARGOCD_SERVER} 5 | appLocatorMethods: 6 | - type: config 7 | instances: 8 | - name: ${ARGOCD_NAME} 9 | url: ${ARGOCD_SERVER} 10 | -------------------------------------------------------------------------------- /dev-service-image/app-config.catalog.yaml: -------------------------------------------------------------------------------- 1 | catalog: 2 | import: 3 | entityFilename: catalog-info.yaml 4 | rules: 5 | - allow: [API,Component,User,Group,Location,Resource,System,Template] 6 | # Overrides the default list locations from app-config.yaml as these contain example data. 7 | # See https://backstage.io/docs/features/software-catalog/#adding-components-to-the-catalog for more details 8 | # on how to get entities into the catalog. 9 | locations: 10 | # Local example organizational data 11 | - type: file 12 | target: ./examples/org.yaml 13 | rules: 14 | - allow: [User, Group] 15 | -------------------------------------------------------------------------------- /dev-service-image/app-config.gitea.yaml: -------------------------------------------------------------------------------- 1 | gitea: 2 | - host: ${GITEA_HOST} 3 | baseUrl: ${GITEA_BASE_URL} 4 | username: ${GITEA_USERNAME} 5 | password: ${GITEA_PASSWORD} 6 | -------------------------------------------------------------------------------- /dev-service-image/app-config.github.yaml: -------------------------------------------------------------------------------- 1 | github: 2 | - host: ${GITHUB_HOST} 3 | token: ${GITHUB_TOKEN} 4 | -------------------------------------------------------------------------------- /dev-service-image/app-config.kubernetes.yaml: -------------------------------------------------------------------------------- 1 | kubernetes: 2 | serviceLocatorMethod: 3 | type: 'multiTenant' 4 | clusterLocatorMethods: 5 | - type: 'config' 6 | clusters: 7 | - url: ${KUBERNETES_API_URL} 8 | name: ${KUBERNETES_CLUSTER_NAME} 9 | authProvider: 'serviceAccount' 10 | skipTLSVerify: true 11 | skipMetricsLookup: true 12 | serviceAccountToken: ${KUBERNETES_SERVICE_ACCOUNT_TOKEN} 13 | customResources: 14 | - group: 'tekton.dev' 15 | apiVersion: 'v1' 16 | plural: 'pipelineruns' 17 | - group: 'tekton.dev' 18 | apiVersion: 'v1' 19 | plural: 'taskruns' 20 | -------------------------------------------------------------------------------- /dev-service-image/app-config.local.yaml: -------------------------------------------------------------------------------- 1 | # Backstage override configuration for your local development environment 2 | -------------------------------------------------------------------------------- /dev-service-image/app-config.postgres.yaml: -------------------------------------------------------------------------------- 1 | # config options: https://node-postgres.com/apis/client 2 | database: 3 | client: pg 4 | connection: 5 | host: ${POSTGRES_HOST} 6 | port: ${POSTGRES_PORT} 7 | user: ${POSTGRES_USER} 8 | password: ${POSTGRES_PASSWORD} 9 | # https://node-postgres.com/features/ssl 10 | # you can set the sslmode configuration option via the `PGSSLMODE` environment variable 11 | # see https://www.postgresql.org/docs/current/libpq-ssl.html Table 33.1. SSL Mode Descriptions (e.g. require) 12 | # ssl: 13 | # ca: # if you have a CA file and want to verify it you can uncomment this section 14 | # $file: /ca/server.crt 15 | -------------------------------------------------------------------------------- /dev-service-image/backstage.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.31.1" 3 | } 4 | -------------------------------------------------------------------------------- /dev-service-image/bin/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Fallback to second argument if first argument is empty and export 4 | setf() { 5 | if [ -z "${!1}" ]; then 6 | export $1="$2" 7 | fi 8 | } 9 | 10 | setf "BACKSTAGE_TOKEN" `node -p 'require("crypto").randomBytes(24).toString("base64")'` 11 | 12 | cat app-config.base.yaml > app-config.production.yaml 13 | 14 | if [ -n "$GITHUB_TOKEN" ]; then 15 | setf "GITHUB_HOST" "github.com" 16 | cat app-config.github.yaml >> app-config.production.yaml 17 | fi 18 | 19 | if [ -n "$GITEA_HOST" ] && [ -n "$GITEA_USERNAME" ] && [ -n "$GITEA_PASSWORD" ]; then 20 | echo "Setting up Gitea" 21 | cat app-config.gitea.yaml >> app-config.production.yaml 22 | fi 23 | 24 | if [ -n "$ARGOCD_NAME" ] && [ -n "$ARGOCD_SERVER" ] && [ -n "$ARGOCD_ADMIN_USER" ] && [ -n "$ARGOCD_ADMIN_PASSWORD" ]; then 25 | echo "Setting up ArgoCD" 26 | cat app-config.argocd.yaml >> app-config.production.yaml 27 | fi 28 | 29 | if [ -n "$KUBERNETES_CLUSTER_NAME" ] && [ -n "$KUBERNETES_API_URL" ] && [ -n "$KUBERNETES_SERVICE_ACCOUNT_TOKEN" ]; then 30 | echo "Setting up Kubernetes" 31 | cat app-config.kubernetes.yaml >> app-config.production.yaml 32 | fi 33 | 34 | 35 | cat app-config.catalog.yaml >> app-config.production.yaml 36 | 37 | node packages/backend --config app-config.production.yaml 38 | -------------------------------------------------------------------------------- /dev-service-image/examples/org.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # https://backstage.io/docs/features/software-catalog/descriptor-format#kind-user 3 | apiVersion: backstage.io/v1alpha1 4 | kind: User 5 | metadata: 6 | name: guest 7 | spec: 8 | memberOf: [guests] 9 | --- 10 | # https://backstage.io/docs/features/software-catalog/descriptor-format#kind-group 11 | apiVersion: backstage.io/v1alpha1 12 | kind: Group 13 | metadata: 14 | name: guests 15 | spec: 16 | type: team 17 | children: [] 18 | -------------------------------------------------------------------------------- /dev-service-image/packages/app/.eslintignore: -------------------------------------------------------------------------------- 1 | public 2 | -------------------------------------------------------------------------------- /dev-service-image/packages/app/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); 2 | -------------------------------------------------------------------------------- /dev-service-image/packages/app/e2e-tests/app.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Backstage Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { test, expect } from '@playwright/test'; 18 | 19 | test('App should render the welcome page', async ({ page }) => { 20 | await page.goto('/'); 21 | 22 | const enterButton = page.getByRole('button', { name: 'Enter' }); 23 | await expect(enterButton).toBeVisible(); 24 | await enterButton.click(); 25 | 26 | await expect(page.getByText('My Company Catalog')).toBeVisible(); 27 | }); 28 | -------------------------------------------------------------------------------- /dev-service-image/packages/app/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/dev-service-image/packages/app/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /dev-service-image/packages/app/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/dev-service-image/packages/app/public/apple-touch-icon.png -------------------------------------------------------------------------------- /dev-service-image/packages/app/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/dev-service-image/packages/app/public/favicon-16x16.png -------------------------------------------------------------------------------- /dev-service-image/packages/app/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/dev-service-image/packages/app/public/favicon-32x32.png -------------------------------------------------------------------------------- /dev-service-image/packages/app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/dev-service-image/packages/app/public/favicon.ico -------------------------------------------------------------------------------- /dev-service-image/packages/app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Backstage", 3 | "name": "Backstage", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "48x48", 8 | "type": "image/png" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /dev-service-image/packages/app/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /dev-service-image/packages/app/public/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | Created by potrace 1.11, written by Peter Selinger 2001-2013 -------------------------------------------------------------------------------- /dev-service-image/packages/app/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, waitFor } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | describe('App', () => { 6 | it('should render', async () => { 7 | process.env = { 8 | NODE_ENV: 'test', 9 | APP_CONFIG: [ 10 | { 11 | data: { 12 | app: { title: 'Test' }, 13 | backend: { baseUrl: 'http://localhost:7007' }, 14 | techdocs: { 15 | storageUrl: 'http://localhost:7007/api/techdocs/static/docs', 16 | }, 17 | }, 18 | context: 'test', 19 | }, 20 | ] as any, 21 | }; 22 | 23 | const rendered = render(); 24 | 25 | await waitFor(() => { 26 | expect(rendered.baseElement).toBeInTheDocument(); 27 | }); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /dev-service-image/packages/app/src/apis.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ScmIntegrationsApi, 3 | scmIntegrationsApiRef, 4 | ScmAuth, 5 | } from '@backstage/integration-react'; 6 | import { 7 | AnyApiFactory, 8 | configApiRef, 9 | createApiFactory, 10 | } from '@backstage/core-plugin-api'; 11 | 12 | export const apis: AnyApiFactory[] = [ 13 | createApiFactory({ 14 | api: scmIntegrationsApiRef, 15 | deps: { configApi: configApiRef }, 16 | factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi), 17 | }), 18 | ScmAuth.createDefaultApiFactory(), 19 | ]; 20 | -------------------------------------------------------------------------------- /dev-service-image/packages/app/src/components/Root/index.ts: -------------------------------------------------------------------------------- 1 | export { Root } from './Root'; 2 | -------------------------------------------------------------------------------- /dev-service-image/packages/app/src/index.tsx: -------------------------------------------------------------------------------- 1 | import '@backstage/cli/asset-types'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom/client'; 4 | import App from './App'; 5 | 6 | ReactDOM.createRoot(document.getElementById('root')!).render(); 7 | -------------------------------------------------------------------------------- /dev-service-image/packages/app/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom'; 2 | -------------------------------------------------------------------------------- /dev-service-image/packages/backend/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); 2 | -------------------------------------------------------------------------------- /dev-service-image/plugins/README.md: -------------------------------------------------------------------------------- 1 | # The Plugins Folder 2 | 3 | This is where your own plugins and their associated modules live, each in a 4 | separate folder of its own. 5 | 6 | If you want to create a new plugin here, go to your project root directory, run 7 | the command `yarn new`, and follow the on-screen instructions. 8 | 9 | You can also check out existing plugins on [the plugin marketplace](https://backstage.io/plugins)! 10 | -------------------------------------------------------------------------------- /dev-service-image/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@backstage/cli/config/tsconfig.json", 3 | "include": [ 4 | "packages/*/src", 5 | "packages/*/config.d.ts", 6 | "plugins/*/src", 7 | "plugins/*/config.d.ts", 8 | "plugins/*/dev", 9 | "plugins/*/migrations" 10 | ], 11 | "exclude": ["node_modules"], 12 | "compilerOptions": { 13 | "outDir": "dist-types", 14 | "rootDir": "." 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /docs/antora.yml: -------------------------------------------------------------------------------- 1 | name: quarkus-backstage 2 | title: Backstage 3 | version: dev 4 | nav: 5 | - modules/ROOT/nav.adoc 6 | -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/.keepme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/.keepme -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/backstage-dev-service.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/backstage-dev-service.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/create-quarkus-app.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/create-quarkus-app.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/exposing-an-api.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/exposing-an-api.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/generate-template-using-the-build.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/generate-template-using-the-build.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/generate-template-using-the-cli.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/generate-template-using-the-cli.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/generating-a-template-using-the-cli.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/generating-a-template-using-the-cli.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/generating-a-template.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/generating-a-template.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/gitea-integration.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/gitea-integration.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/install-backstage-cli-plguin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/install-backstage-cli-plguin.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/install-backstage-cli-plugin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/install-backstage-cli-plugin.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/install-backstage-extension.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/install-backstage-extension.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/installing-quarkus-backstage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/installing-quarkus-backstage.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/installing-the-cli-plugin-and-generating-a-template.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/installing-the-cli-plugin-and-generating-a-template.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/installing-the-cli-plugin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/assets/images/installing-the-cli-plugin.gif -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/scenarios/generate-template-using-the-build.sh: -------------------------------------------------------------------------------- 1 | #$ expect \$ 2 | rm -rf .backstage 3 | #$ expect \$ 4 | ls -al 5 | #$ expect \$ 6 | echo "quarkus.backstage.template.generation.enabled=true" >> src/main/resources/application.properties 7 | #$ expect \$ 8 | mvn clean install -DskipTests 9 | #$ expect \$ 10 | ls -al 11 | #$ expect \$ 12 | tree .backstage 13 | #$ expect \$ 14 | -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/scenarios/generate-template-using-the-cli.sh: -------------------------------------------------------------------------------- 1 | #$ delay 10 2 | quarkus backstage template --help 3 | #$ expect \$ 4 | quarkus backstage template generate 5 | #$ expect \$ 6 | ls -al 7 | #$ expect \$ 8 | tree .backstage 9 | #$ expect \$ 10 | -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/scenarios/install-backstage-cli-plugin.sh: -------------------------------------------------------------------------------- 1 | #$ delay 10 2 | quarkus plug add io.quarkiverse.backstage:quarkus-backstage-cli:999-SNAPSHOT 3 | #$ expect \$ 4 | quarkus backstage --help 5 | #$ expect \$ 6 | quarkus backstage entities --help 7 | #$ expect \$ 8 | rm -rf catalog-info.yaml 9 | #$ expect \$ 10 | ls -al 11 | #$ expect \$ 12 | quarkus backstage entities generate 13 | #$ expect \$ 14 | ls -al 15 | #$ expect \$ 16 | cat catalog-info.yaml 17 | #$ expect \$ 18 | -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/scenarios/install-backstage-extension.sh: -------------------------------------------------------------------------------- 1 | #$ delay 10 2 | quarkus create app hello-backstage 3 | #$ expect \$ 4 | cd hello-backstage 5 | #$ expect \$ 6 | quarkus ext add io.quarkiverse.backstage:quarkus-backstage:999-SNAPSHOT 7 | #$ expect \$ 8 | mvn clean install -DskipTests 9 | #$ expect \$ 10 | ls -al 11 | #$ expect \$ 12 | cat catalog-info.yaml 13 | #$ expect \$ 14 | -------------------------------------------------------------------------------- /docs/modules/ROOT/examples/.keepme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-backstage/bafdd0f9f27fb81f3e54e5c95e4dcd1e7e9dd9c7/docs/modules/ROOT/examples/.keepme -------------------------------------------------------------------------------- /docs/modules/ROOT/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Getting Started] 2 | 3 | * Generators 4 | ** xref:catalog-info.adoc[Catalog Info] 5 | ** xref:template-generator.adoc[Template Generator] 6 | 7 | * xref:client.adoc[Java Client] 8 | * xref:cli.adoc[Command Line Interface] 9 | * xref:dev-service.adoc[Dev Service] 10 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/includes/attributes.adoc: -------------------------------------------------------------------------------- 1 | :project-version: 0.6.0 2 | 3 | :examples-dir: ./../examples/ -------------------------------------------------------------------------------- /docs/templates/includes/attributes.adoc: -------------------------------------------------------------------------------- 1 | :project-version: ${release.current-version} 2 | 3 | :examples-dir: ./../examples/ -------------------------------------------------------------------------------- /integration-tests/src/main/java/io/quarkiverse/backstage/it/BackstageResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.quarkiverse.backstage.it; 18 | 19 | import jakarta.enterprise.context.ApplicationScoped; 20 | import jakarta.ws.rs.GET; 21 | import jakarta.ws.rs.Path; 22 | 23 | @Path("/backstage") 24 | @ApplicationScoped 25 | public class BackstageResource { 26 | // add some rest methods here 27 | 28 | @GET 29 | public String hello() { 30 | return "Hello backstage"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /integration-tests/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.backstage.devservices.enabled=true 2 | quarkus.backstage.devservices.template.installation.enabled=true 3 | quarkus.backstage.devservices.dev-template.installation.enabled=true 4 | 5 | quarkus.log.category."io.quarkiverse.backstage".level=DEBUG 6 | -------------------------------------------------------------------------------- /integration-tests/src/test/java/io/quarkiverse/backstage/it/BackstageResourceIT.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.it; 2 | 3 | import io.quarkus.test.junit.QuarkusIntegrationTest; 4 | 5 | @QuarkusIntegrationTest 6 | public class BackstageResourceIT extends BackstageResourceTest { 7 | } 8 | -------------------------------------------------------------------------------- /integration-tests/src/test/java/io/quarkiverse/backstage/it/BackstageResourceTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.it; 2 | 3 | import static io.restassured.RestAssured.given; 4 | import static org.hamcrest.Matchers.is; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | import io.quarkus.test.junit.QuarkusTest; 9 | 10 | @QuarkusTest 11 | public class BackstageResourceTest { 12 | 13 | @Test 14 | public void testHelloEndpoint() { 15 | given() 16 | .when().get("/backstage") 17 | .then() 18 | .statusCode(200) 19 | .body(is("Hello backstage")); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /model-generator/base/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | io.quarkiverse.backstage 6 | quarkus-backstage-model-generator 7 | 999-SNAPSHOT 8 | ../pom.xml 9 | 10 | 11 | io.quarkiverse.backstage 12 | quarkus-backstage-model-base 13 | jar 14 | Quarkus Backstage - Model Generator - Base 15 | 16 | 17 | 18 | com.fasterxml.jackson.core 19 | jackson-annotations 20 | 21 | 22 | com.fasterxml.jackson.core 23 | jackson-databind 24 | 25 | 26 | jakarta.validation 27 | jakarta.validation-api 28 | 29 | 30 | org.projectlombok 31 | lombok 32 | ${lombok.version} 33 | provided 34 | true 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/EntityLink.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage; 2 | 3 | import java.util.Optional; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.Getter; 8 | import lombok.NoArgsConstructor; 9 | import lombok.Setter; 10 | import lombok.ToString; 11 | 12 | @Getter 13 | @Setter 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @ToString 17 | @EqualsAndHashCode 18 | public class EntityLink { 19 | 20 | /** 21 | * An optional descriptive title for the link. 22 | */ 23 | private String title; 24 | 25 | /** 26 | * The url to the external site, document, etc. 27 | */ 28 | private Optional url; 29 | 30 | /** 31 | * An optional reference to another entity in the catalog. 32 | */ 33 | private Optional entityRef; 34 | 35 | /** 36 | * An optional semantic key that represents a visual icon. 37 | */ 38 | private Optional icon; 39 | 40 | /** 41 | * An optional value to categorize links into specific groups 42 | */ 43 | private Optional type; 44 | } 45 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/Status.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage; 2 | 3 | import java.util.List; 4 | 5 | import com.fasterxml.jackson.annotation.JsonInclude; 6 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 7 | 8 | import lombok.AllArgsConstructor; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "items", 18 | }) 19 | @Getter 20 | @Setter 21 | @AllArgsConstructor 22 | @NoArgsConstructor 23 | @ToString 24 | @EqualsAndHashCode 25 | public class Status { 26 | 27 | private List items; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/StatusItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage; 2 | 3 | import java.util.Map; 4 | 5 | import com.fasterxml.jackson.annotation.JsonInclude; 6 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 7 | 8 | import lombok.AllArgsConstructor; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "type", 18 | "level", 19 | "message", 20 | "error", 21 | }) 22 | @Getter 23 | @Setter 24 | @AllArgsConstructor 25 | @NoArgsConstructor 26 | @ToString 27 | @EqualsAndHashCode 28 | public class StatusItem { 29 | /** 30 | * The type of status as a unique key per source. 31 | */ 32 | private String type; 33 | 34 | /** 35 | * The level / severity of the status item. If the level is "error", the 36 | * processing of the entity may be entirely blocked. In this case the status 37 | * entry may apply to a different, newer version of the data than what is 38 | * being returned in the catalog response. 39 | */ 40 | private StatusLevel level; 41 | /** 42 | * A brief message describing the status, intended for human consumption. 43 | */ 44 | private String message; 45 | 46 | /** 47 | * An optional serialized error object related to the status. 48 | */ 49 | private Map error; 50 | } 51 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/StatusLevel.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage; 2 | 3 | public enum StatusLevel { 4 | info, // Only informative data 5 | warning, // Warnings were found 6 | error; // Errors were found 7 | } 8 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/Output.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.scaffolder.v1beta3; 2 | 3 | import java.util.List; 4 | 5 | import com.fasterxml.jackson.annotation.JsonInclude; 6 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 7 | 8 | import io.quarkiverse.backstage.EntityLink; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "links", 18 | }) 19 | @Getter 20 | @Setter 21 | @NoArgsConstructor 22 | @ToString 23 | @EqualsAndHashCode 24 | public class Output { 25 | 26 | private List links; 27 | 28 | public Output(List links) { 29 | this.links = links; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/Parameter.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.scaffolder.v1beta3; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.fasterxml.jackson.annotation.JsonInclude; 7 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 8 | 9 | import lombok.AllArgsConstructor; 10 | import lombok.EqualsAndHashCode; 11 | import lombok.Getter; 12 | import lombok.NoArgsConstructor; 13 | import lombok.Setter; 14 | import lombok.ToString; 15 | 16 | @JsonInclude(JsonInclude.Include.NON_NULL) 17 | @JsonPropertyOrder({ 18 | "title", 19 | "required", 20 | "properties", 21 | "dependencies" 22 | }) 23 | @Getter 24 | @Setter 25 | @NoArgsConstructor 26 | @AllArgsConstructor 27 | @ToString 28 | @EqualsAndHashCode 29 | public class Parameter { 30 | 31 | private String title; 32 | private List required; 33 | private Map properties; 34 | private Map dependencies; 35 | } 36 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/Step.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.scaffolder.v1beta3; 2 | 3 | import java.util.Map; 4 | 5 | import com.fasterxml.jackson.annotation.JsonInclude; 6 | import com.fasterxml.jackson.annotation.JsonProperty; 7 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 8 | 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "id", 18 | "name", 19 | "action", 20 | "input" 21 | }) 22 | @Getter 23 | @Setter 24 | @NoArgsConstructor 25 | @ToString 26 | @EqualsAndHashCode 27 | public class Step { 28 | 29 | private String id; 30 | private String name; 31 | private String action; 32 | private Map input; 33 | 34 | @JsonProperty("if") 35 | private String _if; 36 | 37 | public Step(String id, String name, String action, Map input) { 38 | this.id = id; 39 | this.name = name; 40 | this.action = action; 41 | this.input = input; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/Template.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.scaffolder.v1beta3; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 5 | 6 | import io.quarkiverse.backstage.EntityMeta; 7 | import io.quarkiverse.backstage.Status; 8 | import io.quarkiverse.backstage.v1alpha1.Entity; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "apiVersion", 18 | "kind", 19 | "metadata", 20 | "spec", 21 | "status", 22 | }) 23 | @Getter 24 | @Setter 25 | @NoArgsConstructor 26 | @ToString 27 | @EqualsAndHashCode 28 | public class Template implements Entity { 29 | 30 | private String kind = "Template"; 31 | private final String apiVersion = "scaffolder.backstage.io/v1beta3"; 32 | private EntityMeta metadata = new EntityMeta(); 33 | private TemplateSpec spec = new TemplateSpec(); 34 | private Status status; 35 | 36 | public Template(EntityMeta metadata, TemplateSpec spec, Status status) { 37 | this.metadata = metadata; 38 | this.spec = spec; 39 | this.status = status; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/TemplateSpec.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.scaffolder.v1beta3; 2 | 3 | import java.util.List; 4 | 5 | import com.fasterxml.jackson.annotation.JsonInclude; 6 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 7 | 8 | import lombok.EqualsAndHashCode; 9 | import lombok.Getter; 10 | import lombok.NoArgsConstructor; 11 | import lombok.Setter; 12 | import lombok.ToString; 13 | 14 | @JsonInclude(JsonInclude.Include.NON_NULL) 15 | @JsonPropertyOrder({ 16 | "type", 17 | "owner", 18 | "system", 19 | "parameters", 20 | "steps", 21 | "output" 22 | }) 23 | @Getter 24 | @Setter 25 | @NoArgsConstructor 26 | @ToString 27 | @EqualsAndHashCode 28 | public class TemplateSpec { 29 | 30 | private String type; 31 | private String owner; 32 | private String system; 33 | private List parameters; 34 | private List steps; 35 | private Output output; 36 | 37 | public TemplateSpec(String type, String owner, String system, List parameters, List steps, Output output) { 38 | this.type = type; 39 | this.owner = owner; 40 | this.system = system; 41 | this.parameters = parameters; 42 | this.steps = steps; 43 | this.output = output; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/Api.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 5 | 6 | import io.quarkiverse.backstage.EntityMeta; 7 | import io.quarkiverse.backstage.Status; 8 | import lombok.EqualsAndHashCode; 9 | import lombok.Getter; 10 | import lombok.NoArgsConstructor; 11 | import lombok.Setter; 12 | import lombok.ToString; 13 | 14 | @JsonInclude(JsonInclude.Include.NON_NULL) 15 | @JsonPropertyOrder({ 16 | "apiVersion", 17 | "kind", 18 | "spec", 19 | "status", 20 | }) 21 | @Getter 22 | @Setter 23 | @NoArgsConstructor 24 | @ToString 25 | @EqualsAndHashCode 26 | public class Api implements Entity { 27 | 28 | private String kind = "API"; 29 | private String apiVersion = BACKSTAGE_IO_V1ALPHA1; 30 | private EntityMeta metadata = new EntityMeta(); 31 | private ApiSpec spec; 32 | private Status status; 33 | 34 | public Api(EntityMeta metadata, ApiSpec spec, Status status) { 35 | this.metadata = metadata; 36 | this.spec = spec; 37 | this.status = status; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/ApiDefinition.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import java.io.IOException; 4 | 5 | import com.fasterxml.jackson.core.JsonParser; 6 | import com.fasterxml.jackson.core.JsonProcessingException; 7 | import com.fasterxml.jackson.databind.DeserializationContext; 8 | import com.fasterxml.jackson.databind.JsonDeserializer; 9 | import com.fasterxml.jackson.databind.JsonNode; 10 | import com.fasterxml.jackson.databind.ObjectMapper; 11 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 12 | 13 | @JsonDeserialize(using = ApiDefinition.Deserializer.class) 14 | public interface ApiDefinition { 15 | 16 | public static class Deserializer extends JsonDeserializer { 17 | @Override 18 | public ApiDefinition deserialize(JsonParser p, DeserializationContext ctxt) 19 | throws IOException, JsonProcessingException { 20 | JsonNode node = p.readValueAsTree(); 21 | ObjectMapper mapper = (ObjectMapper) p.getCodec(); 22 | if (node.isTextual()) { 23 | return new MultilineApiDefintion(node.asText()); 24 | } else if (node.has("$text")) { 25 | return new PathApiDefintion(node.get("$text").asText()); 26 | } 27 | return null; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/Component.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 5 | 6 | import io.quarkiverse.backstage.EntityMeta; 7 | import io.quarkiverse.backstage.Status; 8 | import lombok.EqualsAndHashCode; 9 | import lombok.Getter; 10 | import lombok.NoArgsConstructor; 11 | import lombok.Setter; 12 | import lombok.ToString; 13 | 14 | @JsonInclude(JsonInclude.Include.NON_NULL) 15 | @JsonPropertyOrder({ 16 | "apiVersion", 17 | "kind", 18 | "spec", 19 | "status", 20 | }) 21 | @Getter 22 | @Setter 23 | @NoArgsConstructor 24 | @ToString 25 | @EqualsAndHashCode 26 | public class Component implements Entity { 27 | 28 | private String kind = "Component"; 29 | private final String apiVersion = BACKSTAGE_IO_V1ALPHA1; 30 | private EntityMeta metadata = new EntityMeta(); 31 | private ComponentSpec spec = new ComponentSpec(); 32 | private Status status; 33 | 34 | public Component(EntityMeta metadata, ComponentSpec spec, Status status) { 35 | this.metadata = metadata; 36 | this.spec = spec; 37 | this.status = status; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/Domain.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 5 | 6 | import io.quarkiverse.backstage.EntityMeta; 7 | import io.quarkiverse.backstage.Status; 8 | import lombok.AllArgsConstructor; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "apiVersion", 18 | "kind", 19 | "spec", 20 | }) 21 | @Getter 22 | @Setter 23 | @AllArgsConstructor 24 | @NoArgsConstructor 25 | @ToString 26 | @EqualsAndHashCode 27 | public class Domain implements Entity { 28 | 29 | private String kind = "Domain"; 30 | private final String apiVersion = BACKSTAGE_IO_V1ALPHA1; 31 | private EntityMeta metadata = new EntityMeta(); 32 | private DomainSpec spec; 33 | private Status status; 34 | } 35 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/DomainSpec.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | 6 | import com.fasterxml.jackson.annotation.JsonIgnore; 7 | import com.fasterxml.jackson.annotation.JsonInclude; 8 | import com.fasterxml.jackson.annotation.JsonProperty; 9 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 10 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 11 | 12 | import lombok.AllArgsConstructor; 13 | import lombok.EqualsAndHashCode; 14 | import lombok.Getter; 15 | import lombok.NoArgsConstructor; 16 | import lombok.Setter; 17 | import lombok.ToString; 18 | 19 | @JsonInclude(JsonInclude.Include.NON_NULL) 20 | @JsonPropertyOrder({ 21 | "owner" 22 | }) 23 | @Getter 24 | @Setter 25 | @AllArgsConstructor 26 | @NoArgsConstructor 27 | @ToString 28 | @EqualsAndHashCode 29 | public class DomainSpec { 30 | /** 31 | * An entity reference to the owner of the component. 32 | * (Required) 33 | * 34 | */ 35 | @JsonProperty("owner") 36 | @JsonPropertyDescription("An entity reference to the owner of the component.") 37 | private String owner; 38 | 39 | @JsonIgnore 40 | private Map additionalProperties = new LinkedHashMap(); 41 | } 42 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/Entity.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonSubTypes; 5 | import com.fasterxml.jackson.annotation.JsonTypeInfo; 6 | 7 | import io.quarkiverse.backstage.EntityMeta; 8 | import io.quarkiverse.backstage.Status; 9 | import io.quarkiverse.backstage.scaffolder.v1beta3.Template; 10 | 11 | @JsonIgnoreProperties(ignoreUnknown = true) 12 | @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "kind") 13 | @JsonSubTypes({ 14 | @JsonSubTypes.Type(value = Api.class, name = "API"), 15 | @JsonSubTypes.Type(value = Component.class, name = "Component"), 16 | @JsonSubTypes.Type(value = Domain.class, name = "Domain"), 17 | @JsonSubTypes.Type(value = Group.class, name = "Group"), 18 | @JsonSubTypes.Type(value = Location.class, name = "Location"), 19 | @JsonSubTypes.Type(value = Resource.class, name = "Resource"), 20 | @JsonSubTypes.Type(value = System.class, name = "System"), 21 | @JsonSubTypes.Type(value = Template.class, name = "Template"), 22 | @JsonSubTypes.Type(value = User.class, name = "User"), 23 | }) 24 | public interface Entity { 25 | 26 | String BACKSTAGE_IO_V1ALPHA1 = "backstage.io/v1alpha1"; 27 | 28 | default String getKind() { 29 | throw new UnsupportedOperationException(); 30 | } 31 | 32 | default String getApiVersion() { 33 | return BACKSTAGE_IO_V1ALPHA1; 34 | } 35 | 36 | default EntityMeta getMetadata() { 37 | throw new UnsupportedOperationException(); 38 | } 39 | 40 | default Status getStatus() { 41 | throw new UnsupportedOperationException(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/EntityList.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import java.util.List; 4 | 5 | import com.fasterxml.jackson.annotation.JsonInclude; 6 | 7 | import lombok.AllArgsConstructor; 8 | import lombok.EqualsAndHashCode; 9 | import lombok.Getter; 10 | import lombok.NoArgsConstructor; 11 | import lombok.Setter; 12 | import lombok.ToString; 13 | 14 | @Getter 15 | @Setter 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | @EqualsAndHashCode 19 | @ToString 20 | @JsonInclude(JsonInclude.Include.NON_NULL) 21 | public class EntityList { 22 | 23 | private List items; 24 | } 25 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/Group.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 5 | 6 | import io.quarkiverse.backstage.EntityMeta; 7 | import io.quarkiverse.backstage.Status; 8 | import lombok.AllArgsConstructor; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "apiVersion", 18 | "kind", 19 | "spec", 20 | }) 21 | @Getter 22 | @Setter 23 | @AllArgsConstructor 24 | @NoArgsConstructor 25 | @ToString 26 | @EqualsAndHashCode 27 | public class Group implements Entity { 28 | 29 | private String kind = "Group"; 30 | private final String apiVersion = BACKSTAGE_IO_V1ALPHA1; 31 | private EntityMeta metadata = new EntityMeta(); 32 | private GroupSpec spec; 33 | private Status status; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/Location.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 5 | 6 | import io.quarkiverse.backstage.EntityMeta; 7 | import io.quarkiverse.backstage.Status; 8 | import lombok.AllArgsConstructor; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "apiVersion", 18 | "kind", 19 | "spec", 20 | }) 21 | @NoArgsConstructor 22 | @AllArgsConstructor 23 | @Getter 24 | @Setter 25 | @ToString 26 | @EqualsAndHashCode 27 | public class Location implements Entity { 28 | 29 | private String kind = "Location"; 30 | private String apiVersion = BACKSTAGE_IO_V1ALPHA1; 31 | private EntityMeta metadata = new EntityMeta(); 32 | private LocationSpec spec; 33 | private Status status; 34 | } 35 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/MultilineApiDefintion.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import com.fasterxml.jackson.annotation.JsonValue; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | import lombok.Setter; 9 | import lombok.ToString; 10 | 11 | @Setter 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @ToString 15 | @EqualsAndHashCode 16 | public class MultilineApiDefintion implements ApiDefinition { 17 | 18 | private String value; 19 | 20 | @JsonValue 21 | public String getValue() { 22 | return value; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/PathApiDefintion.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.Getter; 8 | import lombok.NoArgsConstructor; 9 | import lombok.Setter; 10 | import lombok.ToString; 11 | 12 | @Getter 13 | @Setter 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @ToString 17 | @EqualsAndHashCode 18 | public class PathApiDefintion implements ApiDefinition { 19 | 20 | @JsonProperty("$text") 21 | private String path; 22 | } 23 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/Presence.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.fasterxml.jackson.annotation.JsonCreator; 7 | import com.fasterxml.jackson.annotation.JsonValue; 8 | 9 | public enum Presence { 10 | 11 | REQUIRED("required"), 12 | OPTIONAL("optional"); 13 | 14 | private final String value; 15 | private final static Map CONSTANTS = new HashMap<>(); 16 | 17 | static { 18 | for (Presence c : values()) { 19 | CONSTANTS.put(c.value, c); 20 | } 21 | } 22 | 23 | Presence(String value) { 24 | this.value = value; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return this.value; 30 | } 31 | 32 | @JsonValue 33 | public String value() { 34 | return this.value; 35 | } 36 | 37 | @JsonCreator 38 | public static Presence fromValue(String value) { 39 | Presence constant = CONSTANTS.get(value); 40 | if (constant == null) { 41 | throw new IllegalArgumentException(value); 42 | } else { 43 | return constant; 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/Resource.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 5 | 6 | import io.quarkiverse.backstage.EntityMeta; 7 | import io.quarkiverse.backstage.Status; 8 | import lombok.AllArgsConstructor; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "apiVersion", 18 | "kind", 19 | "spec", 20 | }) 21 | @Getter 22 | @Setter 23 | @AllArgsConstructor 24 | @NoArgsConstructor 25 | @ToString 26 | @EqualsAndHashCode 27 | public class Resource implements Entity { 28 | 29 | private String kind = "Resource"; 30 | private final String apiVersion = BACKSTAGE_IO_V1ALPHA1; 31 | private EntityMeta metadata = new EntityMeta(); 32 | private ResourceSpec spec; 33 | private Status status; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/System.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 5 | 6 | import io.quarkiverse.backstage.EntityMeta; 7 | import io.quarkiverse.backstage.Status; 8 | import lombok.AllArgsConstructor; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "apiVersion", 18 | "kind", 19 | "spec", 20 | }) 21 | @Getter 22 | @Setter 23 | @AllArgsConstructor 24 | @NoArgsConstructor 25 | @ToString 26 | @EqualsAndHashCode 27 | public class System implements Entity { 28 | 29 | private String kind = "System"; 30 | private final String apiVersion = BACKSTAGE_IO_V1ALPHA1; 31 | private EntityMeta metadata = new EntityMeta(); 32 | private SystemSpec spec; 33 | private Status status; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/SystemSpec.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | 6 | import jakarta.validation.Valid; 7 | import jakarta.validation.constraints.NotNull; 8 | import jakarta.validation.constraints.Size; 9 | 10 | import com.fasterxml.jackson.annotation.JsonIgnore; 11 | import com.fasterxml.jackson.annotation.JsonInclude; 12 | import com.fasterxml.jackson.annotation.JsonProperty; 13 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 14 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 15 | 16 | import lombok.AllArgsConstructor; 17 | import lombok.EqualsAndHashCode; 18 | import lombok.Getter; 19 | import lombok.NoArgsConstructor; 20 | import lombok.Setter; 21 | import lombok.ToString; 22 | 23 | @JsonInclude(JsonInclude.Include.NON_NULL) 24 | @JsonPropertyOrder({ 25 | "owner", 26 | "domain" 27 | }) 28 | @Getter 29 | @Setter 30 | @AllArgsConstructor 31 | @NoArgsConstructor 32 | @ToString 33 | @EqualsAndHashCode 34 | public class SystemSpec { 35 | 36 | /** 37 | * An entity reference to the owner of the component. 38 | * (Required) 39 | * 40 | */ 41 | @JsonProperty("owner") 42 | @JsonPropertyDescription("An entity reference to the owner of the component.") 43 | @Size(min = 1) 44 | @NotNull 45 | private String owner; 46 | /** 47 | * An entity reference to the domain that the system belongs to. 48 | * 49 | */ 50 | @JsonProperty("domain") 51 | @JsonPropertyDescription("An entity reference to the domain that the system belongs to.") 52 | @Size(min = 1) 53 | private String domain; 54 | @JsonIgnore 55 | @Valid 56 | private Map additionalProperties = new LinkedHashMap(); 57 | 58 | } 59 | -------------------------------------------------------------------------------- /model-generator/base/src/main/java/io/quarkiverse/backstage/v1alpha1/User.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 5 | 6 | import io.quarkiverse.backstage.EntityMeta; 7 | import io.quarkiverse.backstage.Status; 8 | import lombok.AllArgsConstructor; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | import lombok.ToString; 14 | 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | @JsonPropertyOrder({ 17 | "apiVersion", 18 | "kind", 19 | "spec", 20 | }) 21 | @Getter 22 | @Setter 23 | @AllArgsConstructor 24 | @NoArgsConstructor 25 | @ToString 26 | @EqualsAndHashCode 27 | public class User implements Entity { 28 | 29 | private String kind = "User"; 30 | private final String apiVersion = BACKSTAGE_IO_V1ALPHA1; 31 | private EntityMeta metadata = new EntityMeta(); 32 | private UserSpec spec; 33 | private Status status; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /model-generator/builder-generator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | io.quarkiverse.backstage 6 | quarkus-backstage-model-generator 7 | 999-SNAPSHOT 8 | ../pom.xml 9 | 10 | 11 | io.quarkiverse.backstage 12 | quarkus-backstage-model-builder-generator 13 | jar 14 | Quarkus Backstage - Model Generator - Builder 15 | 16 | 17 | 18 | ${project.groupId} 19 | quarkus-backstage-model-base 20 | ${project.version} 21 | 22 | 23 | io.sundr 24 | builder-annotations 25 | ${sundr.version} 26 | compile 27 | true 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /model-generator/builder-generator/src/main/java/io/quarkiverse/backstage/codegen/Codegen.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 The original authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | **/ 17 | 18 | package io.quarkiverse.backstage.codegen; 19 | 20 | import io.sundr.builder.annotations.ExternalBuildables; 21 | 22 | @ExternalBuildables(skipExistingTypes = false, lazyCollectionInitEnabled = false, lazyMapInitEnabled = false, includeAbstractClasses = true, includeInterfaces = false, value = { 23 | "io.quarkiverse.backstage", 24 | "io.quarkiverse.backstage.v1alpha1", 25 | "io.quarkiverse.backstage.scaffolder.v1beta3", 26 | }, excludes = { 27 | ".*Fluent$", 28 | }, generateBuilderPackage = true, builderPackage = "io.quarkiverse.backstage.model.builder") 29 | public class Codegen { 30 | } 31 | -------------------------------------------------------------------------------- /model-generator/model/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | io.quarkiverse.backstage 6 | quarkus-backstage-model-generator 7 | 999-SNAPSHOT 8 | ../pom.xml 9 | 10 | 11 | io.quarkiverse.backstage 12 | quarkus-backstage-model 13 | jar 14 | Quarkus Backstage - Model Generator - Model 15 | 16 | 17 | 18 | ${project.groupId} 19 | quarkus-backstage-model-base 20 | ${project.version} 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/EntityLinkBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class EntityLinkBuilder extends EntityLinkFluent 6 | implements VisitableBuilder { 7 | public EntityLinkBuilder() { 8 | this(new EntityLink()); 9 | } 10 | 11 | public EntityLinkBuilder(EntityLinkFluent fluent) { 12 | this(fluent, new EntityLink()); 13 | } 14 | 15 | public EntityLinkBuilder(EntityLinkFluent fluent, EntityLink instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public EntityLinkBuilder(EntityLink instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | EntityLinkFluent fluent; 26 | 27 | public EntityLink build() { 28 | EntityLink buildable = new EntityLink(fluent.getTitle(), fluent.getUrl(), fluent.getEntityRef(), fluent.getIcon(), 29 | fluent.getType()); 30 | return buildable; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/EntityMetaBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class EntityMetaBuilder extends EntityMetaFluent 6 | implements VisitableBuilder { 7 | public EntityMetaBuilder() { 8 | this(new EntityMeta()); 9 | } 10 | 11 | public EntityMetaBuilder(EntityMetaFluent fluent) { 12 | this(fluent, new EntityMeta()); 13 | } 14 | 15 | public EntityMetaBuilder(EntityMetaFluent fluent, EntityMeta instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public EntityMetaBuilder(EntityMeta instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | EntityMetaFluent fluent; 26 | 27 | public EntityMeta build() { 28 | EntityMeta buildable = new EntityMeta(fluent.getUid(), fluent.getEtag(), fluent.getName(), fluent.getNamespace(), 29 | fluent.getTitle(), fluent.getDescription(), fluent.getLabels(), fluent.getAnnotations(), fluent.getTags(), 30 | fluent.buildLinks()); 31 | return buildable; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/StatusBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class StatusBuilder extends StatusFluent implements VisitableBuilder { 6 | public StatusBuilder() { 7 | this(new Status()); 8 | } 9 | 10 | public StatusBuilder(StatusFluent fluent) { 11 | this(fluent, new Status()); 12 | } 13 | 14 | public StatusBuilder(StatusFluent fluent, Status instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public StatusBuilder(Status instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | StatusFluent fluent; 25 | 26 | public Status build() { 27 | Status buildable = new Status(fluent.buildItems()); 28 | return buildable; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/StatusItemBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class StatusItemBuilder extends StatusItemFluent 6 | implements VisitableBuilder { 7 | public StatusItemBuilder() { 8 | this(new StatusItem()); 9 | } 10 | 11 | public StatusItemBuilder(StatusItemFluent fluent) { 12 | this(fluent, new StatusItem()); 13 | } 14 | 15 | public StatusItemBuilder(StatusItemFluent fluent, StatusItem instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public StatusItemBuilder(StatusItem instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | StatusItemFluent fluent; 26 | 27 | public StatusItem build() { 28 | StatusItem buildable = new StatusItem(fluent.getType(), fluent.getLevel(), fluent.getMessage(), fluent.getError()); 29 | return buildable; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder/Builder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.model.builder; 2 | 3 | import java.lang.FunctionalInterface; 4 | 5 | @FunctionalInterface 6 | public interface Builder { 7 | 8 | T build(); 9 | 10 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder/DelegatingVisitor.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.model.builder; 2 | 3 | import java.lang.Class; 4 | import java.lang.Object; 5 | import java.lang.String; 6 | import java.util.List; 7 | import java.util.Map.Entry; 8 | import java.util.function.Predicate; 9 | 10 | public class DelegatingVisitor implements Visitor { 11 | DelegatingVisitor(Class type, Visitor delegate) { 12 | this.type = type; 13 | this.delegate = delegate; 14 | } 15 | 16 | private final Class type; 17 | private final Visitor delegate; 18 | 19 | public Class getType() { 20 | return type; 21 | } 22 | 23 | public void visit(T target) { 24 | delegate.visit(target); 25 | } 26 | 27 | public int order() { 28 | return delegate.order(); 29 | } 30 | 31 | public void visit(List> path, T target) { 32 | delegate.visit(path, target); 33 | } 34 | 35 | public Predicate>> getRequirement() { 36 | return delegate.getRequirement(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder/Editable.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.model.builder; 2 | 3 | public interface Editable { 4 | 5 | T edit(); 6 | 7 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder/Fluent.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.model.builder; 2 | 3 | public interface Fluent> { 4 | 5 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder/Nested.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.model.builder; 2 | 3 | public interface Nested { 4 | 5 | F and(); 6 | 7 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder/PathAwareTypedVisitor.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.model.builder; 2 | 3 | import java.lang.Class; 4 | import java.lang.Object; 5 | import java.lang.String; 6 | import java.util.List; 7 | import java.util.Map.Entry; 8 | 9 | public class PathAwareTypedVisitor extends TypedVisitor { 10 | PathAwareTypedVisitor() { 11 | List args = Visitors.getTypeArguments(PathAwareTypedVisitor.class, getClass()); 12 | if (args == null || args.isEmpty()) { 13 | throw new IllegalStateException("Could not determine type arguments for path aware typed visitor."); 14 | } 15 | this.type = (Class) args.get(0); 16 | this.parentType = (Class

) args.get(1); 17 | } 18 | 19 | private final Class type; 20 | private final Class

parentType; 21 | 22 | public void visit(V element) { 23 | 24 | } 25 | 26 | public void visit(List> path, V element) { 27 | visit(element); 28 | } 29 | 30 | public P getParent(List> path) { 31 | return path.size() - 1 >= 0 ? (P) path.get(path.size() - 1) : null; 32 | } 33 | 34 | public Class

getParentType() { 35 | return parentType; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder/TypedVisitor.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.model.builder; 2 | 3 | import java.lang.Class; 4 | 5 | public abstract class TypedVisitor implements Visitor { 6 | 7 | public Class getType() { 8 | return (Class) Visitors.getTypeArguments(TypedVisitor.class, getClass()).get(0); 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder/Visitable.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.model.builder; 2 | 3 | import java.lang.Class; 4 | import java.lang.Object; 5 | import java.lang.String; 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.Map.Entry; 9 | 10 | public interface Visitable { 11 | 12 | default T accept(Class type, Visitor visitor) { 13 | return accept(new Visitor() { 14 | @Override 15 | public Class getType() { 16 | return type; 17 | } 18 | 19 | @Override 20 | public void visit(V element) { 21 | visitor.visit(element); 22 | } 23 | }); 24 | } 25 | 26 | default T accept(io.quarkiverse.backstage.model.builder.Visitor... visitors) { 27 | for (Visitor visitor : visitors) { 28 | if (visitor.canVisit(Collections.emptyList(), this)) { 29 | visitor.visit(this); 30 | } 31 | } 32 | return getTarget(this); 33 | } 34 | 35 | default T accept(List> path, io.quarkiverse.backstage.model.builder.Visitor... visitors) { 36 | return accept(path, "", visitors); 37 | } 38 | 39 | default T accept(List> path, String currentKey, 40 | io.quarkiverse.backstage.model.builder.Visitor... visitors) { 41 | for (Visitor visitor : visitors) { 42 | if (visitor.canVisit(path, this)) { 43 | visitor.visit(path, this); 44 | } 45 | } 46 | return getTarget(this); 47 | } 48 | 49 | default T getTarget(Visitable visitable) { 50 | return (T) visitable; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder/VisitableBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.model.builder; 2 | 3 | public interface VisitableBuilder> extends Builder, Visitable { 4 | 5 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/model/builder/VisitableMap.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.model.builder; 2 | 3 | import java.lang.Iterable; 4 | import java.lang.Object; 5 | import java.lang.String; 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.Iterator; 9 | import java.util.List; 10 | import java.util.Spliterator; 11 | import java.util.function.Consumer; 12 | import java.util.stream.Collectors; 13 | 14 | public class VisitableMap extends HashMap>> implements Iterable> { 15 | 16 | public List> get(Object key) { 17 | if (!containsKey(key)) { 18 | put(String.valueOf(key), new ArrayList()); 19 | } 20 | return super.get(key); 21 | } 22 | 23 | public List> aggregate() { 24 | return values().stream().flatMap(l -> l.stream()).collect(Collectors.toList()); 25 | } 26 | 27 | public Iterator> iterator() { 28 | return aggregate().iterator(); 29 | } 30 | 31 | public void forEach(Consumer> action) { 32 | aggregate().forEach(action); 33 | } 34 | 35 | public Spliterator spliterator() { 36 | return aggregate().spliterator(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/OutputBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.scaffolder.v1beta3; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class OutputBuilder extends OutputFluent implements VisitableBuilder { 6 | public OutputBuilder() { 7 | this(new Output()); 8 | } 9 | 10 | public OutputBuilder(OutputFluent fluent) { 11 | this(fluent, new Output()); 12 | } 13 | 14 | public OutputBuilder(OutputFluent fluent, Output instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public OutputBuilder(Output instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | OutputFluent fluent; 25 | 26 | public Output build() { 27 | Output buildable = new Output(fluent.buildLinks()); 28 | return buildable; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/ParameterBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.scaffolder.v1beta3; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class ParameterBuilder extends ParameterFluent 6 | implements VisitableBuilder { 7 | public ParameterBuilder() { 8 | this(new Parameter()); 9 | } 10 | 11 | public ParameterBuilder(ParameterFluent fluent) { 12 | this(fluent, new Parameter()); 13 | } 14 | 15 | public ParameterBuilder(ParameterFluent fluent, Parameter instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public ParameterBuilder(Parameter instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | ParameterFluent fluent; 26 | 27 | public Parameter build() { 28 | Parameter buildable = new Parameter(fluent.getTitle(), fluent.getRequired(), fluent.getProperties(), 29 | fluent.getDependencies()); 30 | return buildable; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/PropertyBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.scaffolder.v1beta3; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class PropertyBuilder extends PropertyFluent implements VisitableBuilder { 6 | public PropertyBuilder() { 7 | this(new Property()); 8 | } 9 | 10 | public PropertyBuilder(PropertyFluent fluent) { 11 | this(fluent, new Property()); 12 | } 13 | 14 | public PropertyBuilder(PropertyFluent fluent, Property instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public PropertyBuilder(Property instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | PropertyFluent fluent; 25 | 26 | public Property build() { 27 | Property buildable = new Property(); 28 | buildable.setName(fluent.getName()); 29 | buildable.setTitle(fluent.getTitle()); 30 | buildable.setType(fluent.getType()); 31 | buildable.setDescription(fluent.getDescription()); 32 | buildable.setProperties(fluent.getProperties()); 33 | buildable.setDefaultValue(fluent.getDefaultValue()); 34 | buildable.setUiAutoFocus(fluent.getUiAutoFocus()); 35 | buildable.setUiField(fluent.getUiField()); 36 | buildable.setUiWidget(fluent.getUiWidget()); 37 | buildable.setUiOptions(fluent.getUiOptions()); 38 | buildable.setEnumValues(fluent.getEnumValues()); 39 | buildable.setEnumNames(fluent.getEnumNames()); 40 | buildable.setRequired(fluent.isRequired()); 41 | return buildable; 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/StepBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.scaffolder.v1beta3; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class StepBuilder extends StepFluent implements VisitableBuilder { 6 | public StepBuilder() { 7 | this(new Step()); 8 | } 9 | 10 | public StepBuilder(StepFluent fluent) { 11 | this(fluent, new Step()); 12 | } 13 | 14 | public StepBuilder(StepFluent fluent, Step instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public StepBuilder(Step instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | StepFluent fluent; 25 | 26 | public Step build() { 27 | Step buildable = new Step(fluent.getId(), fluent.getName(), fluent.getAction(), fluent.getInput()); 28 | return buildable; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/TemplateBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.scaffolder.v1beta3; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class TemplateBuilder extends TemplateFluent implements VisitableBuilder { 6 | public TemplateBuilder() { 7 | this(new Template()); 8 | } 9 | 10 | public TemplateBuilder(TemplateFluent fluent) { 11 | this(fluent, new Template()); 12 | } 13 | 14 | public TemplateBuilder(TemplateFluent fluent, Template instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public TemplateBuilder(Template instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | TemplateFluent fluent; 25 | 26 | public Template build() { 27 | Template buildable = new Template(fluent.buildMetadata(), fluent.buildSpec(), fluent.buildStatus()); 28 | buildable.setKind(fluent.getKind()); 29 | return buildable; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/scaffolder/v1beta3/TemplateSpecBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.scaffolder.v1beta3; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class TemplateSpecBuilder extends TemplateSpecFluent 6 | implements VisitableBuilder { 7 | public TemplateSpecBuilder() { 8 | this(new TemplateSpec()); 9 | } 10 | 11 | public TemplateSpecBuilder(TemplateSpecFluent fluent) { 12 | this(fluent, new TemplateSpec()); 13 | } 14 | 15 | public TemplateSpecBuilder(TemplateSpecFluent fluent, TemplateSpec instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public TemplateSpecBuilder(TemplateSpec instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | TemplateSpecFluent fluent; 26 | 27 | public TemplateSpec build() { 28 | TemplateSpec buildable = new TemplateSpec(fluent.getType(), fluent.getOwner(), fluent.getSystem(), 29 | fluent.buildParameters(), fluent.buildSteps(), fluent.buildOutput()); 30 | return buildable; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/ApiBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class ApiBuilder extends ApiFluent implements VisitableBuilder { 6 | public ApiBuilder() { 7 | this(new Api()); 8 | } 9 | 10 | public ApiBuilder(ApiFluent fluent) { 11 | this(fluent, new Api()); 12 | } 13 | 14 | public ApiBuilder(ApiFluent fluent, Api instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public ApiBuilder(Api instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | ApiFluent fluent; 25 | 26 | public Api build() { 27 | Api buildable = new Api(fluent.buildMetadata(), fluent.buildSpec(), fluent.buildStatus()); 28 | buildable.setKind(fluent.getKind()); 29 | buildable.setApiVersion(fluent.getApiVersion()); 30 | return buildable; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/ApiSpecBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class ApiSpecBuilder extends ApiSpecFluent implements VisitableBuilder { 6 | public ApiSpecBuilder() { 7 | this(new ApiSpec()); 8 | } 9 | 10 | public ApiSpecBuilder(ApiSpecFluent fluent) { 11 | this(fluent, new ApiSpec()); 12 | } 13 | 14 | public ApiSpecBuilder(ApiSpecFluent fluent, ApiSpec instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public ApiSpecBuilder(ApiSpec instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | ApiSpecFluent fluent; 25 | 26 | public ApiSpec build() { 27 | ApiSpec buildable = new ApiSpec(fluent.getType(), fluent.getLifecycle(), fluent.getOwner(), fluent.getSystem(), 28 | fluent.buildDefinition(), fluent.getAdditionalProperties()); 29 | return buildable; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/ComponentBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class ComponentBuilder extends ComponentFluent 6 | implements VisitableBuilder { 7 | public ComponentBuilder() { 8 | this(new Component()); 9 | } 10 | 11 | public ComponentBuilder(ComponentFluent fluent) { 12 | this(fluent, new Component()); 13 | } 14 | 15 | public ComponentBuilder(ComponentFluent fluent, Component instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public ComponentBuilder(Component instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | ComponentFluent fluent; 26 | 27 | public Component build() { 28 | Component buildable = new Component(fluent.buildMetadata(), fluent.buildSpec(), fluent.buildStatus()); 29 | buildable.setKind(fluent.getKind()); 30 | return buildable; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/ComponentSpecBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class ComponentSpecBuilder extends ComponentSpecFluent 6 | implements VisitableBuilder { 7 | public ComponentSpecBuilder() { 8 | this(new ComponentSpec()); 9 | } 10 | 11 | public ComponentSpecBuilder(ComponentSpecFluent fluent) { 12 | this(fluent, new ComponentSpec()); 13 | } 14 | 15 | public ComponentSpecBuilder(ComponentSpecFluent fluent, ComponentSpec instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public ComponentSpecBuilder(ComponentSpec instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | ComponentSpecFluent fluent; 26 | 27 | public ComponentSpec build() { 28 | ComponentSpec buildable = new ComponentSpec(fluent.getType(), fluent.getLifecycle(), fluent.getOwner(), 29 | fluent.getSystem(), fluent.getSubcomponentOf(), fluent.getProvidesApis(), fluent.getConsumesApis(), 30 | fluent.getDependsOn(), fluent.getAdditionalProperties()); 31 | return buildable; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/DomainBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class DomainBuilder extends DomainFluent implements VisitableBuilder { 6 | public DomainBuilder() { 7 | this(new Domain()); 8 | } 9 | 10 | public DomainBuilder(DomainFluent fluent) { 11 | this(fluent, new Domain()); 12 | } 13 | 14 | public DomainBuilder(DomainFluent fluent, Domain instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public DomainBuilder(Domain instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | DomainFluent fluent; 25 | 26 | public Domain build() { 27 | Domain buildable = new Domain(fluent.getKind(), fluent.buildMetadata(), fluent.buildSpec(), fluent.buildStatus()); 28 | return buildable; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/DomainSpecBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class DomainSpecBuilder extends DomainSpecFluent 6 | implements VisitableBuilder { 7 | public DomainSpecBuilder() { 8 | this(new DomainSpec()); 9 | } 10 | 11 | public DomainSpecBuilder(DomainSpecFluent fluent) { 12 | this(fluent, new DomainSpec()); 13 | } 14 | 15 | public DomainSpecBuilder(DomainSpecFluent fluent, DomainSpec instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public DomainSpecBuilder(DomainSpec instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | DomainSpecFluent fluent; 26 | 27 | public DomainSpec build() { 28 | DomainSpec buildable = new DomainSpec(fluent.getOwner(), fluent.getAdditionalProperties()); 29 | return buildable; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/EntityListBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class EntityListBuilder extends EntityListFluent 6 | implements VisitableBuilder { 7 | public EntityListBuilder() { 8 | this(new EntityList()); 9 | } 10 | 11 | public EntityListBuilder(EntityListFluent fluent) { 12 | this(fluent, new EntityList()); 13 | } 14 | 15 | public EntityListBuilder(EntityListFluent fluent, EntityList instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public EntityListBuilder(EntityList instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | EntityListFluent fluent; 26 | 27 | public EntityList build() { 28 | EntityList buildable = new EntityList(fluent.buildItems()); 29 | return buildable; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/GroupBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class GroupBuilder extends GroupFluent implements VisitableBuilder { 6 | public GroupBuilder() { 7 | this(new Group()); 8 | } 9 | 10 | public GroupBuilder(GroupFluent fluent) { 11 | this(fluent, new Group()); 12 | } 13 | 14 | public GroupBuilder(GroupFluent fluent, Group instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public GroupBuilder(Group instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | GroupFluent fluent; 25 | 26 | public Group build() { 27 | Group buildable = new Group(fluent.getKind(), fluent.buildMetadata(), fluent.buildSpec(), fluent.buildStatus()); 28 | return buildable; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/GroupSpecBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class GroupSpecBuilder extends GroupSpecFluent 6 | implements VisitableBuilder { 7 | public GroupSpecBuilder() { 8 | this(new GroupSpec()); 9 | } 10 | 11 | public GroupSpecBuilder(GroupSpecFluent fluent) { 12 | this(fluent, new GroupSpec()); 13 | } 14 | 15 | public GroupSpecBuilder(GroupSpecFluent fluent, GroupSpec instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public GroupSpecBuilder(GroupSpec instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | GroupSpecFluent fluent; 26 | 27 | public GroupSpec build() { 28 | GroupSpec buildable = new GroupSpec(fluent.getType(), fluent.buildProfile(), fluent.getParent(), fluent.getChildren(), 29 | fluent.getMembers(), fluent.getAdditionalProperties()); 30 | return buildable; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/LocationBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class LocationBuilder extends LocationFluent implements VisitableBuilder { 6 | public LocationBuilder() { 7 | this(new Location()); 8 | } 9 | 10 | public LocationBuilder(LocationFluent fluent) { 11 | this(fluent, new Location()); 12 | } 13 | 14 | public LocationBuilder(LocationFluent fluent, Location instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public LocationBuilder(Location instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | LocationFluent fluent; 25 | 26 | public Location build() { 27 | Location buildable = new Location(fluent.getKind(), fluent.getApiVersion(), fluent.buildMetadata(), fluent.buildSpec(), 28 | fluent.buildStatus()); 29 | return buildable; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/LocationSpecBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class LocationSpecBuilder extends LocationSpecFluent 6 | implements VisitableBuilder { 7 | public LocationSpecBuilder() { 8 | this(new LocationSpec()); 9 | } 10 | 11 | public LocationSpecBuilder(LocationSpecFluent fluent) { 12 | this(fluent, new LocationSpec()); 13 | } 14 | 15 | public LocationSpecBuilder(LocationSpecFluent fluent, LocationSpec instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public LocationSpecBuilder(LocationSpec instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | LocationSpecFluent fluent; 26 | 27 | public LocationSpec build() { 28 | LocationSpec buildable = new LocationSpec(fluent.getType(), fluent.getTarget(), fluent.getTargets(), 29 | fluent.getPresence(), fluent.getAdditionalProperties()); 30 | return buildable; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/MultilineApiDefintionBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class MultilineApiDefintionBuilder extends MultilineApiDefintionFluent 6 | implements VisitableBuilder { 7 | public MultilineApiDefintionBuilder() { 8 | this(new MultilineApiDefintion()); 9 | } 10 | 11 | public MultilineApiDefintionBuilder(MultilineApiDefintionFluent fluent) { 12 | this(fluent, new MultilineApiDefintion()); 13 | } 14 | 15 | public MultilineApiDefintionBuilder(MultilineApiDefintionFluent fluent, MultilineApiDefintion instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public MultilineApiDefintionBuilder(MultilineApiDefintion instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | MultilineApiDefintionFluent fluent; 26 | 27 | public MultilineApiDefintion build() { 28 | MultilineApiDefintion buildable = new MultilineApiDefintion(fluent.getValue()); 29 | return buildable; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/PathApiDefintionBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class PathApiDefintionBuilder extends PathApiDefintionFluent 6 | implements VisitableBuilder { 7 | public PathApiDefintionBuilder() { 8 | this(new PathApiDefintion()); 9 | } 10 | 11 | public PathApiDefintionBuilder(PathApiDefintionFluent fluent) { 12 | this(fluent, new PathApiDefintion()); 13 | } 14 | 15 | public PathApiDefintionBuilder(PathApiDefintionFluent fluent, PathApiDefintion instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public PathApiDefintionBuilder(PathApiDefintion instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | PathApiDefintionFluent fluent; 26 | 27 | public PathApiDefintion build() { 28 | PathApiDefintion buildable = new PathApiDefintion(fluent.getPath()); 29 | return buildable; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/ProfileBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class ProfileBuilder extends ProfileFluent implements VisitableBuilder { 6 | public ProfileBuilder() { 7 | this(new Profile()); 8 | } 9 | 10 | public ProfileBuilder(ProfileFluent fluent) { 11 | this(fluent, new Profile()); 12 | } 13 | 14 | public ProfileBuilder(ProfileFluent fluent, Profile instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public ProfileBuilder(Profile instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | ProfileFluent fluent; 25 | 26 | public Profile build() { 27 | Profile buildable = new Profile(fluent.getDisplayName(), fluent.getEmail(), fluent.getPicture(), 28 | fluent.getAdditionalProperties()); 29 | return buildable; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/ResourceBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class ResourceBuilder extends ResourceFluent implements VisitableBuilder { 6 | public ResourceBuilder() { 7 | this(new Resource()); 8 | } 9 | 10 | public ResourceBuilder(ResourceFluent fluent) { 11 | this(fluent, new Resource()); 12 | } 13 | 14 | public ResourceBuilder(ResourceFluent fluent, Resource instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public ResourceBuilder(Resource instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | ResourceFluent fluent; 25 | 26 | public Resource build() { 27 | Resource buildable = new Resource(fluent.getKind(), fluent.buildMetadata(), fluent.buildSpec(), fluent.buildStatus()); 28 | return buildable; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/ResourceSpecBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class ResourceSpecBuilder extends ResourceSpecFluent 6 | implements VisitableBuilder { 7 | public ResourceSpecBuilder() { 8 | this(new ResourceSpec()); 9 | } 10 | 11 | public ResourceSpecBuilder(ResourceSpecFluent fluent) { 12 | this(fluent, new ResourceSpec()); 13 | } 14 | 15 | public ResourceSpecBuilder(ResourceSpecFluent fluent, ResourceSpec instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public ResourceSpecBuilder(ResourceSpec instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | ResourceSpecFluent fluent; 26 | 27 | public ResourceSpec build() { 28 | ResourceSpec buildable = new ResourceSpec(fluent.getType(), fluent.getOwner(), fluent.getDependsOn(), 29 | fluent.getSystem(), fluent.getAdditionalProperties()); 30 | return buildable; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/SystemBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class SystemBuilder extends SystemFluent implements VisitableBuilder { 6 | public SystemBuilder() { 7 | this(new System()); 8 | } 9 | 10 | public SystemBuilder(SystemFluent fluent) { 11 | this(fluent, new System()); 12 | } 13 | 14 | public SystemBuilder(SystemFluent fluent, System instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public SystemBuilder(System instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | SystemFluent fluent; 25 | 26 | public System build() { 27 | System buildable = new System(fluent.getKind(), fluent.buildMetadata(), fluent.buildSpec(), fluent.buildStatus()); 28 | return buildable; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/SystemSpecBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class SystemSpecBuilder extends SystemSpecFluent 6 | implements VisitableBuilder { 7 | public SystemSpecBuilder() { 8 | this(new SystemSpec()); 9 | } 10 | 11 | public SystemSpecBuilder(SystemSpecFluent fluent) { 12 | this(fluent, new SystemSpec()); 13 | } 14 | 15 | public SystemSpecBuilder(SystemSpecFluent fluent, SystemSpec instance) { 16 | this.fluent = fluent; 17 | fluent.copyInstance(instance); 18 | } 19 | 20 | public SystemSpecBuilder(SystemSpec instance) { 21 | this.fluent = this; 22 | this.copyInstance(instance); 23 | } 24 | 25 | SystemSpecFluent fluent; 26 | 27 | public SystemSpec build() { 28 | SystemSpec buildable = new SystemSpec(fluent.getOwner(), fluent.getDomain(), fluent.getAdditionalProperties()); 29 | return buildable; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/UserBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class UserBuilder extends UserFluent implements VisitableBuilder { 6 | public UserBuilder() { 7 | this(new User()); 8 | } 9 | 10 | public UserBuilder(UserFluent fluent) { 11 | this(fluent, new User()); 12 | } 13 | 14 | public UserBuilder(UserFluent fluent, User instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public UserBuilder(User instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | UserFluent fluent; 25 | 26 | public User build() { 27 | User buildable = new User(fluent.getKind(), fluent.buildMetadata(), fluent.buildSpec(), fluent.buildStatus()); 28 | return buildable; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /model-generator/model/src/main/java/io/quarkiverse/backstage/v1alpha1/UserSpecBuilder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.v1alpha1; 2 | 3 | import io.quarkiverse.backstage.model.builder.VisitableBuilder; 4 | 5 | public class UserSpecBuilder extends UserSpecFluent implements VisitableBuilder { 6 | public UserSpecBuilder() { 7 | this(new UserSpec()); 8 | } 9 | 10 | public UserSpecBuilder(UserSpecFluent fluent) { 11 | this(fluent, new UserSpec()); 12 | } 13 | 14 | public UserSpecBuilder(UserSpecFluent fluent, UserSpec instance) { 15 | this.fluent = fluent; 16 | fluent.copyInstance(instance); 17 | } 18 | 19 | public UserSpecBuilder(UserSpec instance) { 20 | this.fluent = this; 21 | this.copyInstance(instance); 22 | } 23 | 24 | UserSpecFluent fluent; 25 | 26 | public UserSpec build() { 27 | UserSpec buildable = new UserSpec(fluent.buildProfile(), fluent.getMemberOf(), fluent.getAdditionalProperties()); 28 | return buildable; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /model-generator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | io.quarkiverse.backstage 6 | quarkus-backstage-parent 7 | 999-SNAPSHOT 8 | ../pom.xml 9 | 10 | 11 | io.quarkiverse.backstage 12 | quarkus-backstage-model-generator 13 | pom 14 | Quarkus Backstage - Model Generator 15 | 16 | 17 | base 18 | builder-generator 19 | model 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /runtime/src/main/java/io/quarkiverse/backstage/runtime/BackstageClientFactory.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.runtime; 2 | 3 | import java.net.URI; 4 | 5 | import jakarta.enterprise.context.ApplicationScoped; 6 | import jakarta.enterprise.inject.Produces; 7 | import jakarta.inject.Singleton; 8 | 9 | import io.quarkiverse.backstage.client.BackstageClient; 10 | import io.quarkus.arc.DefaultBean; 11 | 12 | @ApplicationScoped 13 | public class BackstageClientFactory { 14 | 15 | @DefaultBean 16 | @Produces 17 | @Singleton 18 | public BackstageClient produce(BackstageRuntimeConfiguration config) { 19 | String url = config.url().orElse("http://localhost:7000"); 20 | String host = URI.create(url).getHost(); 21 | int port = URI.create(url).getPort(); 22 | String token = config.token().orElse(null); 23 | return new BackstageClient(host, port, token); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /runtime/src/main/java/io/quarkiverse/backstage/runtime/BackstageRuntimeConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.runtime; 2 | 3 | import java.util.Optional; 4 | 5 | import io.quarkus.runtime.annotations.ConfigPhase; 6 | import io.quarkus.runtime.annotations.ConfigRoot; 7 | import io.smallrye.config.ConfigMapping; 8 | 9 | @ConfigMapping(prefix = "quarkus.backstage") 10 | @ConfigRoot(phase = ConfigPhase.RUN_TIME) 11 | public interface BackstageRuntimeConfiguration { 12 | 13 | /** 14 | * The URL of the Backstage API 15 | */ 16 | Optional url(); 17 | 18 | /** 19 | * 20 | * The token needed to authenticate with the Backstage API 21 | */ 22 | Optional token(); 23 | } 24 | -------------------------------------------------------------------------------- /runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Backstage 2 | #description: Do something useful. 3 | metadata: 4 | # keywords: 5 | # - backstage 6 | # guide: https://quarkiverse.github.io/quarkiverse-docs/backstage/dev/ # To create and publish this guide, see https://github.com/quarkiverse/quarkiverse/wiki#documenting-your-extension 7 | # categories: 8 | # - "miscellaneous" 9 | # status: "preview" 10 | -------------------------------------------------------------------------------- /spi/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | io.quarkiverse.backstage 6 | quarkus-backstage-parent 7 | 999-SNAPSHOT 8 | 9 | 10 | quarkus-backstage-spi 11 | Quarkus Backstage - SPI 12 | 13 | 14 | 15 | io.quarkus 16 | quarkus-core-deployment 17 | 18 | 19 | ${project.groupId} 20 | quarkus-backstage-model 21 | ${project.version} 22 | 23 | 24 | 25 | 26 | 27 | 28 | io.quarkus 29 | quarkus-maven-plugin 30 | true 31 | 32 | 33 | 34 | build 35 | generate-code 36 | generate-code-tests 37 | 38 | 39 | 40 | 41 | 42 | maven-compiler-plugin 43 | 44 | 45 | -parameters 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /spi/src/main/java/io/quarkiverse/backstage/spi/CatalogInfoRequiredFileBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.spi; 2 | 3 | import java.nio.file.Path; 4 | 5 | import io.quarkus.builder.item.MultiBuildItem; 6 | 7 | /** 8 | * A build item that represents an additional file that should be added to the Backstage location. 9 | * Files catalog-info.yaml may reference additional files. 10 | * These files need to be part of the location (usually git repository) so that Backstage can read them. 11 | **/ 12 | public final class CatalogInfoRequiredFileBuildItem extends MultiBuildItem { 13 | 14 | private final Path path; 15 | 16 | public CatalogInfoRequiredFileBuildItem(Path path) { 17 | this.path = path; 18 | } 19 | 20 | public Path getPath() { 21 | return path; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spi/src/main/java/io/quarkiverse/backstage/spi/CatalogInstallationBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.spi; 2 | 3 | import io.quarkiverse.backstage.v1alpha1.EntityList; 4 | import io.quarkus.builder.item.SimpleBuildItem; 5 | 6 | public final class CatalogInstallationBuildItem extends SimpleBuildItem { 7 | 8 | private final EntityList entityList; 9 | private final String url; 10 | 11 | public CatalogInstallationBuildItem(EntityList entityList, String url) { 12 | this.entityList = entityList; 13 | this.url = url; 14 | } 15 | 16 | public EntityList getEntityList() { 17 | return entityList; 18 | } 19 | 20 | public String getUrl() { 21 | return url; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spi/src/main/java/io/quarkiverse/backstage/spi/DevTemplateBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.spi; 2 | 3 | import java.nio.file.Path; 4 | import java.util.Map; 5 | 6 | import io.quarkiverse.backstage.scaffolder.v1beta3.Template; 7 | import io.quarkus.builder.item.MultiBuildItem; 8 | 9 | public final class DevTemplateBuildItem extends MultiBuildItem { 10 | private final Template template; 11 | private final Map content; 12 | 13 | public DevTemplateBuildItem(Template template, Map content) { 14 | this.template = template; 15 | this.content = content; 16 | } 17 | 18 | public Template getTemplate() { 19 | return template; 20 | } 21 | 22 | public Map getContent() { 23 | return content; 24 | } 25 | 26 | public TemplateBuildItem toTemplateBuildItem() { 27 | return new TemplateBuildItem(template, content); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /spi/src/main/java/io/quarkiverse/backstage/spi/DevTemplateInstallationBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.spi; 2 | 3 | import java.nio.file.Path; 4 | import java.util.Map; 5 | 6 | import io.quarkiverse.backstage.scaffolder.v1beta3.Template; 7 | import io.quarkus.builder.item.MultiBuildItem; 8 | 9 | public final class DevTemplateInstallationBuildItem extends MultiBuildItem { 10 | private final Template template; 11 | private final Map content; 12 | private final String url; 13 | 14 | public DevTemplateInstallationBuildItem(DevTemplateBuildItem devTemplate, String url) { 15 | this(devTemplate.getTemplate(), devTemplate.getContent(), url); 16 | } 17 | 18 | public DevTemplateInstallationBuildItem(Template template, Map content, String url) { 19 | this.template = template; 20 | this.content = content; 21 | this.url = url; 22 | } 23 | 24 | public Template getTemplate() { 25 | return template; 26 | } 27 | 28 | public Map getContent() { 29 | return content; 30 | } 31 | 32 | public String getUrl() { 33 | return url; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /spi/src/main/java/io/quarkiverse/backstage/spi/EntityListBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.spi; 2 | 3 | import io.quarkiverse.backstage.v1alpha1.EntityList; 4 | import io.quarkus.builder.item.SimpleBuildItem; 5 | 6 | public final class EntityListBuildItem extends SimpleBuildItem { 7 | 8 | private final EntityList entityList; 9 | 10 | public EntityListBuildItem(EntityList entityList) { 11 | this.entityList = entityList; 12 | } 13 | 14 | public EntityList getEntityList() { 15 | return entityList; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /spi/src/main/java/io/quarkiverse/backstage/spi/TemplateBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.spi; 2 | 3 | import java.nio.file.Path; 4 | import java.util.Map; 5 | 6 | import io.quarkiverse.backstage.scaffolder.v1beta3.Template; 7 | import io.quarkus.builder.item.MultiBuildItem; 8 | 9 | public final class TemplateBuildItem extends MultiBuildItem { 10 | private final Template template; 11 | private final Map content; 12 | 13 | public TemplateBuildItem(Template template, Map content) { 14 | this.template = template; 15 | this.content = content; 16 | } 17 | 18 | public Template getTemplate() { 19 | return template; 20 | } 21 | 22 | public Map getContent() { 23 | return content; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /spi/src/main/java/io/quarkiverse/backstage/spi/TemplateInstallationBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.spi; 2 | 3 | import java.nio.file.Path; 4 | import java.util.Map; 5 | 6 | import io.quarkiverse.backstage.scaffolder.v1beta3.Template; 7 | import io.quarkus.builder.item.MultiBuildItem; 8 | 9 | public final class TemplateInstallationBuildItem extends MultiBuildItem { 10 | private final Template template; 11 | private final Map content; 12 | private final String url; 13 | 14 | public TemplateInstallationBuildItem(TemplateBuildItem template, String url) { 15 | this(template.getTemplate(), template.getContent(), url); 16 | } 17 | 18 | public TemplateInstallationBuildItem(Template template, Map content, String url) { 19 | this.template = template; 20 | this.content = content; 21 | this.url = url; 22 | } 23 | 24 | public Template getTemplate() { 25 | return template; 26 | } 27 | 28 | public Map getContent() { 29 | return content; 30 | } 31 | 32 | public String getUrl() { 33 | return url; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /spi/src/main/java/io/quarkiverse/backstage/spi/UserProvidedTemplateBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.spi; 2 | 3 | import java.nio.file.Path; 4 | import java.util.Map; 5 | 6 | import io.quarkiverse.backstage.scaffolder.v1beta3.Template; 7 | import io.quarkus.builder.item.MultiBuildItem; 8 | 9 | public final class UserProvidedTemplateBuildItem extends MultiBuildItem { 10 | private final Template template; 11 | private final Map content; 12 | 13 | public UserProvidedTemplateBuildItem(Template template, Map content) { 14 | this.template = template; 15 | this.content = content; 16 | } 17 | 18 | public Template getTemplate() { 19 | return template; 20 | } 21 | 22 | public Map getContent() { 23 | return content; 24 | } 25 | 26 | public TemplateBuildItem toTemplateBuildItem() { 27 | return new TemplateBuildItem(template, content); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /spi/src/main/java/io/quarkiverse/backstage/spi/UserProvidedTemplateInstallationBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.backstage.spi; 2 | 3 | import java.nio.file.Path; 4 | import java.util.Map; 5 | 6 | import io.quarkiverse.backstage.scaffolder.v1beta3.Template; 7 | import io.quarkus.builder.item.MultiBuildItem; 8 | 9 | public final class UserProvidedTemplateInstallationBuildItem extends MultiBuildItem { 10 | private final Template template; 11 | private final Map content; 12 | private final String url; 13 | 14 | public UserProvidedTemplateInstallationBuildItem(TemplateBuildItem template, String url) { 15 | this(template.getTemplate(), template.getContent(), url); 16 | } 17 | 18 | public UserProvidedTemplateInstallationBuildItem(Template template, Map content, String url) { 19 | this.template = template; 20 | this.content = content; 21 | this.url = url; 22 | } 23 | 24 | public Template getTemplate() { 25 | return template; 26 | } 27 | 28 | public Map getContent() { 29 | return content; 30 | } 31 | 32 | public String getUrl() { 33 | return url; 34 | } 35 | } 36 | --------------------------------------------------------------------------------