From f548b1ff5bd3d5b2544089e3e719f3c45289c7ac Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Mon, 28 Oct 2024 22:01:40 +0100 Subject: [PATCH 001/101] Implementation of the Firebase Emulator DevService --- bom/pom.xml | 10 + docs/modules/ROOT/pages/firebase.adoc | 129 +++++ .../quarkus-google-cloud-firebase.adoc | 303 ++++++++++++ ...-google-cloud-firebase_quarkus.google.adoc | 303 ++++++++++++ firebase-admin/deployment/pom.xml | 8 + firebase-admin/runtime/pom.xml | 4 + .../admin/runtime/FirebaseAdminProducer.java | 9 +- .../admin/runtime/FirebaseAuthConfig.java | 27 ++ firebase/README.md | 5 + firebase/deployment/pom.xml | 50 ++ .../deployment/FirebaseBuildSteps.java | 14 + .../deployment/FirebaseDevServiceConfig.java | 204 ++++++++ .../FirebaseDevServiceProcessor.java | 445 ++++++++++++++++++ firebase/pom.xml | 20 + firebase/runtime/pom.xml | 60 +++ .../resources/META-INF/quarkus-extension.yaml | 16 + integration-tests/firebase-admin/pom.xml | 4 - .../src/main/resources/application.properties | 3 +- .../it/firebaseadmin/FirebaseAuthTest.java | 10 +- pom.xml | 1 + 20 files changed, 1617 insertions(+), 8 deletions(-) create mode 100644 docs/modules/ROOT/pages/firebase.adoc create mode 100644 docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc create mode 100644 docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc create mode 100644 firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java create mode 100644 firebase/README.md create mode 100644 firebase/deployment/pom.xml create mode 100644 firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseBuildSteps.java create mode 100644 firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java create mode 100644 firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java create mode 100644 firebase/pom.xml create mode 100644 firebase/runtime/pom.xml create mode 100644 firebase/runtime/src/main/resources/META-INF/quarkus-extension.yaml diff --git a/bom/pom.xml b/bom/pom.xml index a22baf18..62b7f197 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -138,6 +138,16 @@ quarkus-google-cloud-firebase-admin-deployment ${project.version} + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-firebase + ${project.version} + + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-firebase-deployment + ${project.version} + io.quarkiverse.googlecloudservices quarkus-google-cloud-firestore diff --git a/docs/modules/ROOT/pages/firebase.adoc b/docs/modules/ROOT/pages/firebase.adoc new file mode 100644 index 00000000..ede16284 --- /dev/null +++ b/docs/modules/ROOT/pages/firebase.adoc @@ -0,0 +1,129 @@ += Google Cloud Services - Firebase + +This extension implements DevServices for applications developed on with the Google Firebase platform. The DevService runs the appropriate emulators of the Firebase platform based on your configuration. + +Be sure to have read the https://quarkiverse.github.io/quarkiverse-docs/quarkus-google-cloud-services/main/index.html[Google Cloud Services extension pack global documentation] before this one, it contains general configuration and information. + +== Current status + +The following emulators have been verified to work: +* Firebase Auth +* Firebase Firestore +* Firebase Emulator UI + +The following emulators need additional work: +* Firebase Hosting +* Realtime Database +* Functions +* PubSub + +The following emulators are currently not supported: +* EventArc +* Cloud Storage + +== Bootstrapping the project + +First, we need a new project. Create a new project with the following command (replace the version placeholder with the correct one): + +[source, shell script] +---- +mvn io.quarkus:quarkus-maven-plugin:${quarkusVersion}:create \ + -DprojectGroupId=org.acme \ + -DprojectArtifactId=firebase-admin-quickstart \ + -Dextensions="quarkus-google-cloud-firebase" +cd firebase-admin-quickstart +---- + +This command generates a Maven project, importing the Google Cloud Firebase extension. + +If you already have your Quarkus project configured, you can add the `quarkus-google-cloud-firebase` extension to your project by running the following command in your project base directory: + +[source, shell script] +---- +./mvnw quarkus:add-extension -Dextensions="quarkus-google-cloud-firebase" +---- + +This will add the following to your pom.xml: + +[source, xml] +---- + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-firebase + +---- + +== Configuration + +* `quarkus.google.cloud.project-id` - The project ID is mandatory for projects using Firebase Auth (Firebase Admin). +* `quarkus.google.cloud.firebase.devservice.image-name` - The base image name to use (see Custom Docker images below) +* `quarkus.google.cloud.firebase.devservice.firebase-version` - The version of the firebase tools to use. Default is to use the latest available version. +* `quarkus.google.cloud.firebase.devservice.token` - The firebase token to use. This is mandatory when using Hosting. This token can be generated using the firebase CLI. +* `quarkus.google.cloud.firebase.devservice.custom-firebase-json` - The path to a custom `firebase.json` file to use instead of the auto generated one (see Custom Firebase.json) +* `quarkus.google.cloud.firebase.devservice.java-tool-options` - Java tool options to pass to the Java based emulators (like -Xmx) +* `quarkus.google.cloud.firebase.devservice.emulator-data` - Path to a directory where to import and export (on exit) the emulator data. +* `quarkus.google.cloud.firebase.devservice.ui.enabled` - Whether to enable the Emulator UI. The default is true. + +*Firebase auth emulator* + +* `quarkus.google.cloud.firebase.auth.devservice.enabled` - Enable the Firebase Auth emulator. The default is false. +* `quarkus.google.cloud.firebase.auth.devservice.emulatorPort` - The port on which to expose the emulator from the Docker container. The default is to expose the service on a random port. + +*Hosting emulator* + +* `quarkus.google.cloud.firebase.hosting.devservice.enabled` - Enable the Hosting emulator. The default is false. +* `quarkus.google.cloud.firebase.hosting.devservice.emulatorPort` - The port on which to expose the emulator from the Docker container. The default is to expose the service on a random port. + +*Realtime database emulator* + +* `quarkus.google.cloud.database.devservice.enabled` - Enable the Realtime database emulator. The default is false. +* `quarkus.google.cloud.database.devservice.emulatorPort` - The port on which to expose the emulator from the Docker container. The default is to expose the service on a random port. + +*Firestore emulator* + +* `quarkus.google.cloud.firestore.devservice.enabled` - Enable the Firestore emulator. The default is false. +* `quarkus.google.cloud.firestore.devservice.emulatorPort` - The port on which to expose the emulator from the Docker container. The default is to expose the service on a random port. + +*Functions emulator* + +* `quarkus.google.cloud.functions.devservice.enabled` - Enable the Firestore emulator. The default is false. +* `quarkus.google.cloud.functions.devservice.emulatorPort` - The port on which to expose the emulator from the Docker container. The default is to expose the service on a random port. + +*PubSub emulator* + +* `quarkus.google.cloud.pubsub.devservice.enabled` - Enable the Firestore emulator. The default is false. +* `quarkus.google.cloud.pubsub.devservice.emulatorPort` - The port on which to expose the emulator from the Docker container. The default is to expose the service on a random port. + +== Custom Docker image + +To run the emulators, a custom Docker image is build on the fly to run the Firebase emulators. This image is based on a NodeJS based image (refer to the configuration of the default value of `quarkus.google.cloud.firebase.devservice.image-name` to see the base image). + +You can configure a custom image if needed as base image to run the Firebase Emulators in. This image has the following requirements: + +* The image must support NodeJS in a version compatible with the required Firebase Tools +* The image must be `alpine` based (or at least able to install the following packages using `apk`: ) +** openjdk11-jre +** bash +** curl +** openssl +** gettext +** nano +** nginx +** sudo + +== Custom Firebase JSON + +By default a `firebase.json` file is generated inside the image to configure the various emulators. You can configure the DevService to use your own custom firebase.json file (e.g generated using the Firebase tools CLI). The following requirements are defined for this file: + +* Each of the emulators must be exposed on `0.0.0.0` as host as described https://firebase.google.com/docs/emulator-suite/use_hosting#emulators-no-local-host[here]. If this is not done, the Emulators will not be reachable from the Docker host. +* Emulators need to be configured to use the default ports. Customizing the ports on which they run is currently not supported (this might change in a future version). + +== Interaction with other other extensions + +The following extensions support a DevService which conflicts with the DevService exposed by the Firebase Emulators. + +* Firestore +* PubSub +* TODO: Verify Storage + +When including this module, these DevServices will automatically be disabled, as the Firebase emulator should feature wise be on-par or more extensive than the individual emulators. \ No newline at end of file diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc new file mode 100644 index 00000000..b97d517b --- /dev/null +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc @@ -0,0 +1,303 @@ +:summaryTableId: quarkus-google-cloud-firebase_quarkus-google +[.configuration-legend] +icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime +[.configuration-reference.searchable, cols="80,.^10,.^10"] +|=== + +h|[.header-title]##Configuration property## +h|Type +h|Default + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-image-name]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.image-name`## + +[.description] +-- +Sets the Docker image name for the Google Cloud SDK. This image is used to emulate the Pub/Sub service in the development environment. The default value is 'gcr.io/google.com/cloudsdktool/google-cloud-cli'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_IMAGE_NAME+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`node:23-alpine` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-firebase-version]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.firebase-version`## + +[.description] +-- +Sets the firebase version to use. Defaults to the latest version. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`latest` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-token]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.token`## + +[.description] +-- +The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This option is mandatory if you use firebase hosting. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_TOKEN+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_TOKEN+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-ui-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.ui.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-ui-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.ui.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-auth-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.auth.devservice.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-auth-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.auth.devservice.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-hosting-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.hosting.devservice.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-hosting-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.hosting.devservice.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-database-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.database.devservice.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-database-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.database.devservice.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firestore-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firestore.devservice.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firestore-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firestore.devservice.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-functions-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.functions.devservice.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-functions-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.functions.devservice.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-pub-sub-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.pub-sub.devservice.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-pub-sub-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.pub-sub.devservice.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +|=== + + +:!summaryTableId: \ No newline at end of file diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc new file mode 100644 index 00000000..b97d517b --- /dev/null +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc @@ -0,0 +1,303 @@ +:summaryTableId: quarkus-google-cloud-firebase_quarkus-google +[.configuration-legend] +icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime +[.configuration-reference.searchable, cols="80,.^10,.^10"] +|=== + +h|[.header-title]##Configuration property## +h|Type +h|Default + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-image-name]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.image-name`## + +[.description] +-- +Sets the Docker image name for the Google Cloud SDK. This image is used to emulate the Pub/Sub service in the development environment. The default value is 'gcr.io/google.com/cloudsdktool/google-cloud-cli'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_IMAGE_NAME+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`node:23-alpine` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-firebase-version]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.firebase-version`## + +[.description] +-- +Sets the firebase version to use. Defaults to the latest version. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`latest` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-token]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.token`## + +[.description] +-- +The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This option is mandatory if you use firebase hosting. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_TOKEN+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_TOKEN+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-ui-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.ui.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-ui-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.ui.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-auth-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.auth.devservice.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-auth-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.auth.devservice.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-hosting-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.hosting.devservice.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-hosting-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.hosting.devservice.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-database-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.database.devservice.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-database-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.database.devservice.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firestore-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firestore.devservice.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firestore-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firestore.devservice.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-functions-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.functions.devservice.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-functions-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.functions.devservice.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-pub-sub-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.pub-sub.devservice.enabled`## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-pub-sub-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.pub-sub.devservice.emulator-port`## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +|=== + + +:!summaryTableId: \ No newline at end of file diff --git a/firebase-admin/deployment/pom.xml b/firebase-admin/deployment/pom.xml index 16f290b8..c9889549 100644 --- a/firebase-admin/deployment/pom.xml +++ b/firebase-admin/deployment/pom.xml @@ -38,10 +38,18 @@ io.quarkiverse.googlecloudservices quarkus-google-cloud-common-deployment + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-firebase-deployment + io.quarkiverse.googlecloudservices quarkus-google-cloud-firebase-admin + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-firebase + diff --git a/firebase-admin/runtime/pom.xml b/firebase-admin/runtime/pom.xml index fa12c5e3..8f074e07 100644 --- a/firebase-admin/runtime/pom.xml +++ b/firebase-admin/runtime/pom.xml @@ -47,6 +47,10 @@ quarkus-google-cloud-common-grpc and Quarkus includes the netty library --> io.quarkus quarkus-security + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-firebase + org.eclipse.microprofile.jwt microprofile-jwt-auth-api diff --git a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java index bb95956d..a00fd623 100644 --- a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java +++ b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java @@ -11,9 +11,12 @@ import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.internal.Utils; +import com.google.firebase.internal.FirebaseProcessEnvironment; import io.quarkiverse.googlecloudservices.common.GcpBootstrapConfiguration; import io.quarkiverse.googlecloudservices.common.GcpConfigHolder; +import io.smallrye.config.ConfigMapping; @ApplicationScoped public class FirebaseAdminProducer { @@ -27,7 +30,11 @@ public class FirebaseAdminProducer { @Produces @Singleton @Default - public FirebaseAuth firestoreAuth(FirebaseApp firebaseApp) { + public FirebaseAuth firestoreAuth(@ConfigMapping FirebaseAuthConfig firebaseAuthConfig, FirebaseApp firebaseApp) { + + // Configure the Firebase emulator to use. + firebaseAuthConfig.emulatorHost().ifPresent(host -> FirebaseProcessEnvironment.setenv(Utils.AUTH_EMULATOR_HOST, host)); + return FirebaseAuth.getInstance(firebaseApp); } diff --git a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java new file mode 100644 index 00000000..6e202300 --- /dev/null +++ b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java @@ -0,0 +1,27 @@ +package io.quarkiverse.googlecloudservices.firebase.admin.runtime; + +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigPhase; +import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; + +/** + * Root configuration class for Google Cloud Firebase Auth setup. + * This interface provides a nested structure for configuration, including + * a separate group for the development service configuration. + *

+ * This interface mostly provides access to validate whether the Firebase Auth + * Emulator is running. + * + */ +@ConfigMapping(prefix = "quarkus.google.cloud.firebase.auth") +@ConfigRoot(phase = ConfigPhase.RUN_TIME) +public interface FirebaseAuthConfig { + + /** + * Sets the emulator host to use. + */ + Optional emulatorHost(); + +} diff --git a/firebase/README.md b/firebase/README.md new file mode 100644 index 00000000..369f0c96 --- /dev/null +++ b/firebase/README.md @@ -0,0 +1,5 @@ +# Quarkus - Google Cloud Services - Firebase + +This extension allows start a DevService for the Firebase Emulator Suite. + +You can find the documentation in the [Firebase Quarkiverse documentation site](https://quarkiverse.github.io/quarkiverse-docs/quarkus-google-cloud-services/main/firebase.html). diff --git a/firebase/deployment/pom.xml b/firebase/deployment/pom.xml new file mode 100644 index 00000000..4806d2a6 --- /dev/null +++ b/firebase/deployment/pom.xml @@ -0,0 +1,50 @@ + + + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-firebase-parent + 2.13.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + quarkus-google-cloud-firebase-deployment + Quarkus - Google Cloud Services - Firebase - Deployment + + + + io.quarkus + quarkus-core-deployment + + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-common-deployment + + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-firebase + + + org.testcontainers + testcontainers + + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${quarkus.version} + + + + + + + + \ No newline at end of file diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseBuildSteps.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseBuildSteps.java new file mode 100644 index 00000000..96bbc13c --- /dev/null +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseBuildSteps.java @@ -0,0 +1,14 @@ +package io.quarkiverse.googlecloudservices.firebase.deployment; + +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.builditem.FeatureBuildItem; + +public class FirebaseBuildSteps { + + protected static final String FEATURE = "google-cloud-firebase"; + + @BuildStep + public FeatureBuildItem feature() { + return new FeatureBuildItem(FEATURE); + } +} diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java new file mode 100644 index 00000000..0eff2548 --- /dev/null +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -0,0 +1,204 @@ +package io.quarkiverse.googlecloudservices.firebase.deployment; + +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithDefault; + +/** + * Root configuration class for Google Cloud Firebase that operates at build time. + * This class provides a nested structure for configuration, including + * a separate group for the development service configuration. + *

+ * Here is an example of how to configure these properties: + *

+ * + *

+ * quarkus.google.cloud.firebase.devservice.enabled = true
+ * quarkus.google.cloud.pubsub.devservice.image-name = gcr.io/google.com/cloudsdktool/google-cloud-cli # optional
+ * quarkus.google.cloud.pubsub.devservice.emulatorPort = 8085 # optional
+ * 
+ */ +@ConfigMapping(prefix = "quarkus.google.cloud") +@ConfigRoot +public interface FirebaseDevServiceConfig { + + /** + * Google Cloud project ID. The project is required to be set if you use the Firebase Auth Dev service. + */ + Optional projectId(); + + /** + * Configure the generic Firebase settings + */ + Firebase firebase(); + + /** + * Configure the realtime database + */ + Database database(); + + /** + * Configure the firestore + */ + Firestore firestore(); + + /** + * Configure google cloud functions + */ + Functions functions(); + + /** + * Configure Google Cloud Pub/Sub + */ + PubSub pubSub(); + + interface Firebase { + + /** + * Configuration for the firebase emulator devservice. This is the generic configuration for the firebase + * emulator. THe specifics are handled in each of the other dev services. + */ + DevService devservice(); + + /** + * Configure the firebase auth settings + */ + Auth auth(); + + /** + * Configure Firebase Hosting + */ + Hosting hosting(); + + interface DevService { + + /** + * Sets the Docker image name for the Google Cloud SDK. + * This image is used to emulate the Pub/Sub service in the development environment. + * The default value is 'gcr.io/google.com/cloudsdktool/google-cloud-cli'. + */ + @WithDefault("node:23-alpine") + String imageName(); + + /** + * Sets the firebase version to use. Defaults to the latest version. + */ + @WithDefault("latest") + String firebaseVersion(); + + /** + * The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This + * option is mandatory if you use firebase hosting. + */ + Optional token(); + + /** + * Indicate to use a custom firebase.json file instead of the automatically generated one. The custom + * firebase.json file MUST include a setting of
"host" : "0.0.0.0"
to ensure the ports of the + * emulator are exposed correctly at the docker container level. + */ + Optional customFirebaseJson(); + + /** + * Sets the JAVA tool options for emulators based on the Java runtime environment. + * See also here + */ + Optional javaToolOptions(); + + /** + * Allow to import and export data. Specify a path relative to the current working directory of the executable + * (for most unit tests, this is the root of the build directory) to be used for import and export of emulator + * data. + * See also here + */ + Optional emulatorData(); + + /** + * Settings for the emulator UI + */ + UI ui(); + + interface UI extends GenericDevService { + + /** + * Indicates whether the service should be enabled or not. + * The default value is 'false'. + */ + @WithDefault("true") + @Override + boolean enabled(); + } + + } + } + + interface Auth { + + /** + * Configuration for the firebase auth emulator + */ + GenericDevService devservice(); + } + + interface Database { + + /** + * Configuration for the realtime database emulator + */ + GenericDevService devservice(); + } + + interface Firestore { + + /** + * Configuration for the Firestore emulator + */ + GenericDevService devservice(); + } + + interface Functions { + + /** + * Configuration for the Functions emulator + */ + GenericDevService devservice(); + } + + interface Hosting { + + /** + * Configuration for the hosting emulator + */ + GenericDevService devservice(); + } + + interface PubSub { + + /** + * Configuration for the pubsub emulator + */ + GenericDevService devservice(); + } + + /** + * Internal interface representing a dev service for each of the different emulators part of the Firebase + * platform. + */ + interface GenericDevService { + + /** + * Indicates whether the service should be enabled or not. + * The default value is 'false'. + */ + @WithDefault("false") + boolean enabled(); + + /** + * Specifies the emulatorPort on which the service should run in the development environment. + */ + Optional emulatorPort(); + } + +} diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java new file mode 100644 index 00000000..49804be8 --- /dev/null +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java @@ -0,0 +1,445 @@ +package io.quarkiverse.googlecloudservices.firebase.deployment; + +import java.io.File; +import java.time.Duration; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.jboss.logging.Logger; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.images.builder.ImageFromDockerfile; +import org.testcontainers.images.builder.dockerfile.DockerfileBuilder; + +import io.quarkus.deployment.IsNormal; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.BuildSteps; +import io.quarkus.deployment.builditem.*; +import io.quarkus.deployment.console.ConsoleInstalledBuildItem; +import io.quarkus.deployment.console.StartupLogCompressor; +import io.quarkus.deployment.dev.devservices.GlobalDevServicesConfig; +import io.quarkus.deployment.logging.LoggingSetupBuildItem; + +/** + * Processor responsible for managing Firebase Dev Services. + *

+ * The processor starts the Firebase service in case it's not running. + */ +@BuildSteps(onlyIfNot = IsNormal.class, onlyIf = GlobalDevServicesConfig.Enabled.class) +public class FirebaseDevServiceProcessor { + + private static final Logger LOGGER = Logger.getLogger(FirebaseDevServiceProcessor.class.getName()); + + // Running dev service instance + private static volatile DevServicesResultBuildItem.RunningDevService devService; + // Configuration for the Firebase Dev service + private static volatile FirebaseDevServiceConfig config; + + @BuildStep + public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildItem, + FirebaseDevServiceConfig firebaseBuildTimeConfig, + List devServicesSharedNetworkBuildItem, + Optional consoleInstalledBuildItem, + CuratedApplicationShutdownBuildItem closeBuildItem, + LaunchModeBuildItem launchMode, + LoggingSetupBuildItem loggingSetupBuildItem, + GlobalDevServicesConfig globalDevServicesConfig) { + // If dev service is running and config has changed, stop the service + if (devService != null && !firebaseBuildTimeConfig.equals(config)) { + stopContainer(); + } else if (devService != null) { + return devService.toBuildItem(); + } + + // Set up log compressor for startup logs + StartupLogCompressor compressor = new StartupLogCompressor( + (launchMode.isTest() ? "(test) " : "") + "Google Cloud Firebase Dev Services Starting:", + consoleInstalledBuildItem, + loggingSetupBuildItem); + + // Try starting the container if conditions are met + try { + devService = startContainerIfAvailable(dockerStatusBuildItem, firebaseBuildTimeConfig, + globalDevServicesConfig.timeout); + } catch (Throwable t) { + LOGGER.warn("Unable to start Firebase dev service", t); + // Dump captured logs in case of an error + compressor.closeAndDumpCaptured(); + return null; + } finally { + compressor.close(); + } + + return devService == null ? null : devService.toBuildItem(); + } + + /** + * Start the container if conditions are met. + * + * @param dockerStatusBuildItem, Docker status + * @param config, Configuration for the Firebase service + * @param timeout, Optional timeout for starting the service + * @return Running service item, or null if the service couldn't be started + */ + private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(DockerStatusBuildItem dockerStatusBuildItem, + FirebaseDevServiceConfig config, + Optional timeout) { + if (!isEnabled(config)) { + // Firebase service explicitly disabled + LOGGER.error("Not starting Dev Services for Firebase as it has been disabled in the config"); + return null; + } + + if (!dockerStatusBuildItem.isContainerRuntimeAvailable()) { + LOGGER.error("Not starting devservice because docker is not available"); + return null; + } + + return startContainer(dockerStatusBuildItem, config, timeout); + } + + private boolean isEnabled(FirebaseDevServiceConfig config) { + return devServices(config) + .values() + .stream() + .map(FirebaseDevServiceConfig.GenericDevService::enabled) + .reduce(Boolean.FALSE, Boolean::logicalOr); + } + + private Map devServices( + FirebaseDevServiceConfig config) { + return Map.of( + FirebaseEmulatorContainer.Emulators.AUTHENTICATION, config.firebase().auth().devservice(), + FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI, config.firebase().devservice().ui(), + FirebaseEmulatorContainer.Emulators.REALTIME_DATABASE, config.database().devservice(), + FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE, config.firestore().devservice(), + FirebaseEmulatorContainer.Emulators.CLOUD_FUNCTIONS, config.functions().devservice(), + FirebaseEmulatorContainer.Emulators.FIREBASE_HOSTING, config.firebase().hosting().devservice(), + FirebaseEmulatorContainer.Emulators.PUB_SUB, config.pubSub().devservice()); + } + + /** + * Starts the Pub/Sub emulator container with provided configuration. + * + * @param dockerStatusBuildItem, Docker status + * @param config, Configuration for the PubSub service + * @param timeout, Optional timeout for starting the service + * @return Running service item, or null if the service couldn't be started + */ + private DevServicesResultBuildItem.RunningDevService startContainer(DockerStatusBuildItem dockerStatusBuildItem, + FirebaseDevServiceConfig config, + Optional timeout) { + + var devServices = devServices(config); + + // Create and configure Pub/Sub emulator container + FirebaseEmulatorContainer emulatorContainer = new FirebaseEmulatorContainer( + config.firebase().devservice(), + devServices, + config.projectId()); + + // Set container startup timeout if provided + timeout.ifPresent(emulatorContainer::withStartupTimeout); + emulatorContainer.start(); + + // Set the config for the started container + FirebaseDevServiceProcessor.config = config; + + var emulatorContainerConfig = emulatorContainer.config(); + + if (LOGGER.isInfoEnabled()) { + var runningPorts = emulatorContainer.emulatorPorts(); + runningPorts.forEach((e, p) -> { + LOGGER.info("Google Cloude Emulator " + e + " reachable on port " + p); + }); + + emulatorContainerConfig.forEach((e, h) -> { + LOGGER.info("Google Cloud emulator config property " + e + " set to " + h); + }); + } + + // Return running service item with container details + return new DevServicesResultBuildItem.RunningDevService(FirebaseBuildSteps.FEATURE, + emulatorContainer.getContainerId(), + emulatorContainer::close, + emulatorContainerConfig); + } + + /** + * Stops the running Firebase emulator container. + */ + private void stopContainer() { + if (devService != null && devService.isOwner()) { + try { + // Try closing the running dev service + devService.close(); + } catch (Throwable e) { + LOGGER.error("Failed to stop firebase container", e); + } finally { + devService = null; + } + } + } + + public static class FirebaseEmulatorContainer extends GenericContainer { + + public enum Emulators { + AUTHENTICATION( + 9099, + "quarkus.google.cloud.firebase.auth.emulator-host", + "auth"), + EMULATOR_SUITE_UI( + 4000, + "quarkus.google.cloud.firebase.emulator-host", + "ui"), + CLOUD_FUNCTIONS( + 5001, + "quarkus.google.cloud.functions.emulator-host", + "functions"), + EVENT_ARC( + 9299, + "quarkus.google.cloud.eventarc.emulator-host", + "eventarc"), + REALTIME_DATABASE( + 9000, + "quarkus.google.cloud.realtimedb.emulator-host", + "database"), + CLOUD_FIRESTORE( + 8080, + "quarkus.google.cloud.firestore.emulator-host", + "firestore"), + CLOUD_STORAGE( + 9199, + "quarkus.google.cloud.storage.emulator-host", + "storage"), + FIREBASE_HOSTING( + 5000, + "quarkus.google.cloud.firebase.hosting.emulator-host", + "hosting"), + PUB_SUB( + 8085, + "quarkus.google.cloud.pubsub.emulator-host", + "pubsub"); + + final int internalPort; + final String configProperty; + final String emulatorName; + + Emulators(int internalPort, String configProperty, String onlyArgument) { + this.internalPort = internalPort; + this.configProperty = configProperty; + this.emulatorName = onlyArgument; + } + + public String getConfigProperty() { + return configProperty; + } + + public String getEmulatorName() { + return emulatorName; + } + } + + private final Map devServices; + + public FirebaseEmulatorContainer(FirebaseDevServiceConfig.Firebase.DevService firebaseConfig, + Map devServices, + Optional projectId) { + super(new FirebaseDockerBuilder( + firebaseConfig, + devServices, + projectId).build()); + + firebaseConfig.emulatorData().ifPresent(path -> { + // TODO: https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data + // Mount the volume to the specified path + }); + + this.devServices = devServices; + } + + private static class FirebaseDockerBuilder { + + private final ImageFromDockerfile result; + + private final FirebaseDevServiceConfig.Firebase.DevService firebaseConfig; + private final Map devServices; + private final Optional projectId; + + private DockerfileBuilder dockerBuilder; + + public FirebaseDockerBuilder(FirebaseDevServiceConfig.Firebase.DevService firebaseConfig, + Map devServices, + Optional projectId) { + this.projectId = projectId; + this.devServices = devServices; + this.firebaseConfig = firebaseConfig; + + this.result = new ImageFromDockerfile() + .withDockerfileFromBuilder(builder -> { + this.dockerBuilder = builder; + }); + } + + public ImageFromDockerfile build() { + this.validateConfiguration(); + this.configureBaseImage(); + this.installNeededSoftware(); + this.authenticateToFirebase(); + this.setupJavaToolOptions(); + this.addFirebaseJson(); + this.setupDataImportExport(); + this.runExecutable(); + + return result; + } + + private void validateConfiguration() { + if (isEmulatorEnabled(devServices, Emulators.AUTHENTICATION) && projectId.isEmpty()) { + throw new IllegalStateException("Can't create Firebase Auth emulator. Google Project id is required"); + } + + // TODO: Validate if a custom firebase.json is defined, that the hosts are defined as 0.0.0.0 + } + + private void configureBaseImage() { + dockerBuilder.from(firebaseConfig.imageName()); + } + + private void installNeededSoftware() { + dockerBuilder + .run("apk --no-cache add openjdk11-jre bash curl openssl gettext nano nginx sudo") + .run("npm cache clean --force") + .run("npm i -g firebase-tools@" + firebaseConfig.firebaseVersion()); + } + + private void authenticateToFirebase() { + firebaseConfig.token().ifPresent(token -> + dockerBuilder.env("FIREBASE_TOKEN", token)); + } + + private void setupJavaToolOptions() { + firebaseConfig.javaToolOptions().ifPresent( toolOptions -> + dockerBuilder.env("JAVA_TOOL_OPTIONS", toolOptions)); + } + + private void addFirebaseJson() { + dockerBuilder.workDir("/srv/firebase"); + + firebaseConfig.customFirebaseJson().ifPresentOrElse( + this::includeCustomFirebaseJson, + this::generateFirebaseJson + ); + + this.dockerBuilder.add("firebase.json", "/srv/firebase/firebase.json"); + } + + private void includeCustomFirebaseJson(String customFilePath) { + this.result.withFileFromPath( + "firebase.json", + new File(customFilePath).toPath() + ); + } + + private void generateFirebaseJson() { + StringBuilder firebaseJson = new StringBuilder(); + + firebaseJson.append("{\n"); + firebaseJson.append("\t\"emulators\": {\n"); + + var emulatorsJson = this.devServices + .keySet() + .stream() + .filter(e -> isEmulatorEnabled(devServices, e)) + .map((emulator -> + "\t\t\"" + emulator.emulatorName + "\": {\n" + + "\t\t\t\"port\": " + emulator.internalPort + ",\n" + + "\t\t\t\"host\": \"0.0.0.0\"\n" + + "\t\t}")) + .collect(Collectors.joining(",\n")); + firebaseJson.append(emulatorsJson).append("\n"); + + firebaseJson.append("\t}\n"); + firebaseJson.append("}\n"); + + this.result.withFileFromString("firebase.json", firebaseJson.toString()); + } + + private void setupDataImportExport() { + firebaseConfig.emulatorData().ifPresent(emulator -> { + this.dockerBuilder.run("mkdir -p /srv/firebase/data"); + this.dockerBuilder.volume("/srv/firebase/data"); + }); + } + + private void runExecutable() { + var projectArgument = projectId + .map(id -> " --project " + id) + .orElse(""); + + var importArgument = firebaseConfig + .emulatorData() + .map( path -> " --import=/srv/firebase/data --export-on-exit") + .orElse(""); + + dockerBuilder + .cmd("firebase emulators:start" + projectArgument + importArgument); + } + } + + /** + * Configures the Pub/Sub emulator container. + */ + @Override + public void configure() { + super.configure(); + + enabledEmulators() + .forEach(emulator -> { + var fixedExposedPort = devServices.get(emulator).emulatorPort(); + // Expose emulatorPort + if (fixedExposedPort.isPresent()) { + addFixedExposedPort(fixedExposedPort.get(), emulator.internalPort); + } else { + addExposedPort(emulator.internalPort); + } + }); + } + + public Map config() { + return enabledEmulators() + .collect(Collectors.toMap( + Emulators::getConfigProperty, + this::getEmulatorEndpoint)); + + } + + public Map emulatorPorts() { + return enabledEmulators() + .collect(Collectors.toMap( + e -> e, + e -> this.getMappedPort(e.internalPort))); + } + + private Stream enabledEmulators() { + return Arrays.stream(Emulators.values()) + .filter(this::isEmulatorEnabled); + } + + private boolean isEmulatorEnabled(Emulators emulator) { + return isEmulatorEnabled(this.devServices, emulator); + } + + private static boolean isEmulatorEnabled(Map devServices, + Emulators emulator) { + return Optional.ofNullable(devServices.get(emulator)) + .map(FirebaseDevServiceConfig.GenericDevService::enabled) + .orElse(false); + } + + private String getEmulatorEndpoint(Emulators emulator) { + return this.getHost() + ":" + this.getMappedPort(emulator.internalPort); + } + } + +} diff --git a/firebase/pom.xml b/firebase/pom.xml new file mode 100644 index 00000000..6a7a61d8 --- /dev/null +++ b/firebase/pom.xml @@ -0,0 +1,20 @@ + + + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-services-parent + 2.13.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + quarkus-google-cloud-firebase-parent + Quarkus - Google Cloud Services - Firebase + pom + + + runtime + deployment + + + \ No newline at end of file diff --git a/firebase/runtime/pom.xml b/firebase/runtime/pom.xml new file mode 100644 index 00000000..871f5cdb --- /dev/null +++ b/firebase/runtime/pom.xml @@ -0,0 +1,60 @@ + + + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-firebase-parent + 2.13.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + quarkus-google-cloud-firebase + Quarkus - Google Cloud Services - Firebase - Runtime + Use Google Cloud Firebase + + + 9.4.0 + 2.1 + + + + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-common + + + + + + + io.quarkus + quarkus-extension-maven-plugin + ${quarkus.version} + + + + extension-descriptor + + compile + + ${project.groupId}:${project.artifactId}-deployment:${project.version} + + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${quarkus.version} + + + + + + + \ No newline at end of file diff --git a/firebase/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/firebase/runtime/src/main/resources/META-INF/quarkus-extension.yaml new file mode 100644 index 00000000..f0adf31d --- /dev/null +++ b/firebase/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -0,0 +1,16 @@ +--- +name: "Google Cloud Firebase" +artifact: ${project.groupId}:${project.artifactId}:${project.version} +metadata: + keywords: + - "firebase" + - "google cloud" + - "gcloud" + - "gcp" + categories: + - "cloud" + - "data" + guide: "https://quarkiverse.github.io/quarkiverse-docs/quarkus-google-cloud-services/main/firebase-admin.html" + status: "experimental" + config: + - "quarkus.google.cloud.firebase." diff --git a/integration-tests/firebase-admin/pom.xml b/integration-tests/firebase-admin/pom.xml index 190566d7..58ed0c9b 100644 --- a/integration-tests/firebase-admin/pom.xml +++ b/integration-tests/firebase-admin/pom.xml @@ -62,14 +62,10 @@ org.jboss.logmanager.LogManager - true maven-failsafe-plugin - - true - diff --git a/integration-tests/firebase-admin/src/main/resources/application.properties b/integration-tests/firebase-admin/src/main/resources/application.properties index f9b81cc0..04f83286 100644 --- a/integration-tests/firebase-admin/src/main/resources/application.properties +++ b/integration-tests/firebase-admin/src/main/resources/application.properties @@ -1,4 +1,5 @@ # Set the project ID with the demo- prefix to use an emulated service. # When the emulator is started with this project ID, non-emulated services access will fail. quarkus.google.cloud.project-id=demo-test-project-id -quarkus.google.cloud.firebase.auth.enabled=true \ No newline at end of file +quarkus.google.cloud.firebase.auth.enabled=true +quarkus.google.cloud.firebase.auth.devservice.enabled=true diff --git a/integration-tests/firebase-admin/src/test/java/io/quarkiverse/googlecloudservices/it/firebaseadmin/FirebaseAuthTest.java b/integration-tests/firebase-admin/src/test/java/io/quarkiverse/googlecloudservices/it/firebaseadmin/FirebaseAuthTest.java index 431f3d9b..72d300ca 100644 --- a/integration-tests/firebase-admin/src/test/java/io/quarkiverse/googlecloudservices/it/firebaseadmin/FirebaseAuthTest.java +++ b/integration-tests/firebase-admin/src/test/java/io/quarkiverse/googlecloudservices/it/firebaseadmin/FirebaseAuthTest.java @@ -10,13 +10,19 @@ public abstract class FirebaseAuthTest { @ConfigProperty(name = "quarkus.google.cloud.project-id") String projectId; + @ConfigProperty(name = "quarkus.google.cloud.firebase.auth.emulator-host") + String emulatorHost; + @BeforeEach public void deleteAllAccounts() { + var emulatorHostParts = emulatorHost.split(":"); + var port = emulatorHostParts.length == 2 ? Integer.parseInt(emulatorHostParts[1]) : 9099; + given() - .port(9099) + .port(port) .auth() .oauth2("owner") - .delete("http://localhost:9099/emulator/v1/projects/{projectId}/accounts", projectId) + .delete("/emulator/v1/projects/{projectId}/accounts", projectId) .then() .statusCode(200); } diff --git a/pom.xml b/pom.xml index 2ba41812..983cfdd8 100644 --- a/pom.xml +++ b/pom.xml @@ -30,6 +30,7 @@ pubsub spanner storage + firebase firebase-admin firestore bigtable From c8e670a720bcb2eb55b54c94e5c144bed2242398 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 1 Nov 2024 20:34:59 +0100 Subject: [PATCH 002/101] Added firebase integration testing --- .../FirebaseDevServiceProcessor.java | 2 +- integration-tests/firebase/.firebaserc | 1 + integration-tests/firebase/.gitignore | 66 +++++++++++++++ integration-tests/firebase/README.md | 28 +++++++ integration-tests/firebase/firebase.json | 11 +++ integration-tests/firebase/pom.xml | 81 +++++++++++++++++++ .../it/firebase/FirebaseResource.java | 76 +++++++++++++++++ .../src/main/resources/application.properties | 7 ++ .../it/firebase/FirebaseResourceTest.java | 34 ++++++++ integration-tests/pom.xml | 1 + 10 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 integration-tests/firebase/.firebaserc create mode 100644 integration-tests/firebase/.gitignore create mode 100755 integration-tests/firebase/README.md create mode 100644 integration-tests/firebase/firebase.json create mode 100644 integration-tests/firebase/pom.xml create mode 100644 integration-tests/firebase/src/main/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResource.java create mode 100644 integration-tests/firebase/src/main/resources/application.properties create mode 100644 integration-tests/firebase/src/test/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResourceTest.java diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java index 49804be8..05444f77 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java @@ -91,7 +91,7 @@ private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(D } if (!dockerStatusBuildItem.isContainerRuntimeAvailable()) { - LOGGER.error("Not starting devservice because docker is not available"); + LOGGER.info("Not starting devservice because docker is not available"); return null; } diff --git a/integration-tests/firebase/.firebaserc b/integration-tests/firebase/.firebaserc new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/integration-tests/firebase/.firebaserc @@ -0,0 +1 @@ +{} diff --git a/integration-tests/firebase/.gitignore b/integration-tests/firebase/.gitignore new file mode 100644 index 00000000..dbb58ffb --- /dev/null +++ b/integration-tests/firebase/.gitignore @@ -0,0 +1,66 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +firebase-debug.log* +firebase-debug.*.log* + +# Firebase cache +.firebase/ + +# Firebase config + +# Uncomment this if you'd like others to create their own Firebase project. +# For a team working on the same Firebase project(s), it is recommended to leave +# it commented so all members can deploy to the same project(s) in .firebaserc. +# .firebaserc + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env diff --git a/integration-tests/firebase/README.md b/integration-tests/firebase/README.md new file mode 100755 index 00000000..0d44d417 --- /dev/null +++ b/integration-tests/firebase/README.md @@ -0,0 +1,28 @@ +# Quarkus - Google Cloud Services - Integration Tests - Firebase Admin + +This integration test show how to integrate with Firebase Admin SDK. + +**WARNING**: It is disabled by default as it needs the emulator authenticated with a valid account to run. + +## Installing gcloud CLI and Emulator Suite + +1. Install the gcloud CLI following [this](https://cloud.google.com/sdk/docs/install) guide +2. Authenticate with your Google Account +```shell +$ gcloud auth login +``` +3. Install the Local Emulator Suite using [this](https://firebase.google.com/docs/emulator-suite/install_and_configure#install_the_local_emulator_suite) instructions + +## Running + +1. Before running the integration tests, start the Local Emulator Suite using the following command: +```shell +$ firebase emulators:start --project demo-test-project-id +``` + +_After that, the emulator will start in the default port, which the application is configured to connect to. Since it is configured using the `demo-` prefix, all operations will be performed in the emulator environment only, without affecting any real projects. If needed, you will be able to use the Emulator UI at http://localhost:4000/auth._ + +2. In order to have the Admin SDK connecting to the emulator, set the following environment variable: +```shell +$ export FIREBASE_AUTH_EMULATOR_HOST="localhost:9099" +``` \ No newline at end of file diff --git a/integration-tests/firebase/firebase.json b/integration-tests/firebase/firebase.json new file mode 100644 index 00000000..2fb2a16b --- /dev/null +++ b/integration-tests/firebase/firebase.json @@ -0,0 +1,11 @@ +{ + "emulators": { + "auth": { + "port": 9099 + }, + "ui": { + "enabled": true + }, + "singleProjectMode": true + } +} diff --git a/integration-tests/firebase/pom.xml b/integration-tests/firebase/pom.xml new file mode 100644 index 00000000..95283e5e --- /dev/null +++ b/integration-tests/firebase/pom.xml @@ -0,0 +1,81 @@ + + + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-services-integration-tests-parent + 2.13.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + quarkus-google-cloud-services-firebase-it + Quarkus - Google Cloud Services - Integration Tests - Firebase + + + true + true + ${skipTests} + + + + + io.quarkus + quarkus-resteasy-reactive-jackson + + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-firebase + + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-firestore + + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-pubsub + + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + + + + + io.quarkus + quarkus-maven-plugin + ${quarkus.version} + + + + build + + + + + ${graalvmHome} + + + + maven-surefire-plugin + + + org.jboss.logmanager.LogManager + + + + + maven-failsafe-plugin + + + + + diff --git a/integration-tests/firebase/src/main/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResource.java b/integration-tests/firebase/src/main/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResource.java new file mode 100644 index 00000000..dbcfbe0f --- /dev/null +++ b/integration-tests/firebase/src/main/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResource.java @@ -0,0 +1,76 @@ +package io.quarkiverse.googlecloudservices.it.firebase; + +import com.google.cloud.firestore.Firestore; +import com.google.cloud.pubsub.v1.Publisher; +import com.google.pubsub.v1.PubsubMessage; +import io.quarkiverse.googlecloudservices.pubsub.QuarkusPubSub; +import io.quarkus.runtime.StartupEvent; +import jakarta.enterprise.event.Observes; +import jakarta.inject.Inject; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.core.Response; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +@Path("/app") +public class FirebaseResource { + + @Inject + Firestore firestore; + + @Inject + QuarkusPubSub quarkusPubSub; + + Publisher publisher; + + public void init(@Observes StartupEvent event) throws IOException { + quarkusPubSub.createTopic("test"); + quarkusPubSub.createSubscription("test", "test"); + publisher = quarkusPubSub.publisher("test"); + } + + @POST + public void createData() throws InterruptedException { + Object monitor = new Object(); + + quarkusPubSub.subscriber("test", (message, consumer) -> { + try { + var col = firestore.collection("test"); + col.document("test").create(Map.of("test", "test")).get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + + consumer.ack(); + + synchronized (monitor) { + monitor.notify(); + } + }); + + publisher.publish(PubsubMessage.newBuilder().build()); + synchronized (monitor) { + monitor.wait(5000); + } + } + + @GET + public Response getData() throws ExecutionException, InterruptedException { + var col = firestore.collection("test"); + var docs = col.listDocuments(); + var iter = docs.iterator(); + + if (iter.hasNext()) { + var docRef = iter.next(); + var snapshot = docRef.get().get(); + return Response.ok(snapshot.getString("test")).build(); + } else { + return Response.status(Response.Status.NOT_FOUND).build(); + } + + } +} diff --git a/integration-tests/firebase/src/main/resources/application.properties b/integration-tests/firebase/src/main/resources/application.properties new file mode 100644 index 00000000..a59d0f2e --- /dev/null +++ b/integration-tests/firebase/src/main/resources/application.properties @@ -0,0 +1,7 @@ +# Set the project ID with the demo- prefix to use an emulated service. +# When the emulator is started with this project ID, non-emulated services access will fail. +quarkus.google.cloud.project-id=demo-test-project-id +quarkus.google.cloud.firebase.auth.enabled=true +quarkus.google.cloud.firebase.auth.devservice.enabled=true +quarkus.google.cloud.pubsub.devservice.enabled=true +quarkus.google.cloud.firestore.devservice.enabled=true diff --git a/integration-tests/firebase/src/test/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResourceTest.java b/integration-tests/firebase/src/test/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResourceTest.java new file mode 100644 index 00000000..0b88ab40 --- /dev/null +++ b/integration-tests/firebase/src/test/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResourceTest.java @@ -0,0 +1,34 @@ +package io.quarkiverse.googlecloudservices.it.firebase; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.*; + +@QuarkusTest +public class FirebaseResourceTest { + + @Test + void shouldCreateUser() { + given() + .contentType(ContentType.JSON) + .post("/app") + .then() + .log().ifValidationFails() + .statusCode(204); + + given() + .contentType(ContentType.JSON) + .get("/app") + .then() + .log().ifValidationFails() + .statusCode(200) + .assertThat() + .body(is("test")); + } + + + +} diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index e606889a..4bf2de68 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -34,6 +34,7 @@ google-cloud-functions app-engine firebase-admin + firebase From 0a9e223450226d5b18d62913e01ec8657362c145 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 1 Nov 2024 20:35:57 +0100 Subject: [PATCH 003/101] Switch on or off the Firestore and Pubsub dev services based on a config property set by the firebase dev service config. --- .../deployment/FirebaseDevServiceConfig.java | 8 +++++++ .../FirebaseDevServiceProcessor.java | 11 +++++++-- .../deployment/FirebaseDevServiceConfig.java | 22 ++++++++++++++++++ .../FirestoreDevServiceProcessor.java | 9 +++++++- .../deployment/FirebaseDevServiceConfig.java | 23 +++++++++++++++++++ .../deployment/PubSubDevServiceProcessor.java | 9 +++++++- 6 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirebaseDevServiceConfig.java create mode 100644 pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/FirebaseDevServiceConfig.java diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index 0eff2548..c9647fa6 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -74,6 +74,14 @@ interface Firebase { interface DevService { + /** + * Indicates to use the dev service for Firebase. The default value is true. This indicator is used + * to detect the Firebase DevService and disable the DevServices for extensions which conflict with the + * Firebase DevService. + */ + @WithDefault("true") + boolean preferFirebaseDevServices(); + /** * Sets the Docker image name for the Google Cloud SDK. * This image is used to emulate the Pub/Sub service in the development environment. diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java index 05444f77..664fdef7 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java @@ -84,9 +84,16 @@ public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildI private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(DockerStatusBuildItem dockerStatusBuildItem, FirebaseDevServiceConfig config, Optional timeout) { - if (!isEnabled(config)) { + + if (!config.firebase().devservice().preferFirebaseDevServices()) { // Firebase service explicitly disabled - LOGGER.error("Not starting Dev Services for Firebase as it has been disabled in the config"); + LOGGER.info("Not starting Dev Services for Firebase as it has been disabled in the config."); + return null; + } + + if (!isEnabled(config)) { + // Firebase service implicitly disabled, no emulators enabled. + LOGGER.info("Not starting Dev Services for Firebase as no emulators are enabled."); return null; } diff --git a/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirebaseDevServiceConfig.java b/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirebaseDevServiceConfig.java new file mode 100644 index 00000000..3abe4c70 --- /dev/null +++ b/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirebaseDevServiceConfig.java @@ -0,0 +1,22 @@ +package io.quarkiverse.googlecloudservices.firestore.deployment; + +import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; +import java.util.Optional; + +/** + * Config mapping to detect if the Firebase Dev Services are running, in which case the PubSub dev service + * will be disabled by default as these two Devservice are in conflict with each other. + */ +@ConfigMapping(prefix = "quarkus.google.cloud.firebase.devservice") +@ConfigRoot +public interface FirebaseDevServiceConfig { + + /** + * Indicates to use the dev service for Firebase. The default value is not setup unless the firebase module + * is included. In that case, the Firebase devservices will by default be preferred and the DevService for + * PubSub will be disabled. + */ + Optional preferFirebaseDevServices(); + +} diff --git a/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirestoreDevServiceProcessor.java b/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirestoreDevServiceProcessor.java index aebcab1f..a13f038e 100644 --- a/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirestoreDevServiceProcessor.java +++ b/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirestoreDevServiceProcessor.java @@ -35,6 +35,7 @@ public class FirestoreDevServiceProcessor { @BuildStep public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildItem, FirestoreBuildTimeConfig buildTimeConfig, + FirebaseDevServiceConfig firebaseConfig, List devServicesSharedNetworkBuildItem, Optional consoleInstalledBuildItem, CuratedApplicationShutdownBuildItem closeBuildItem, @@ -56,7 +57,7 @@ public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildI // Try starting the container if conditions are met try { - devService = startContainerIfAvailable(dockerStatusBuildItem, buildTimeConfig.devservice(), + devService = startContainerIfAvailable(dockerStatusBuildItem, buildTimeConfig.devservice(), firebaseConfig, globalDevServicesConfig.timeout); } catch (Throwable t) { LOGGER.warn("Unable to start Firestore dev service", t); @@ -80,6 +81,7 @@ public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildI */ private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(DockerStatusBuildItem dockerStatusBuildItem, FirestoreDevServiceConfig config, + FirebaseDevServiceConfig firebaseConfig, Optional timeout) { if (!config.enabled()) { // Firestore service explicitly disabled @@ -87,6 +89,11 @@ private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(D return null; } + if (firebaseConfig.preferFirebaseDevServices().orElse(false)) { + // Firebase DevServices are included, use them instead + LOGGER.debug("Not starting Dev Services for Firestore as the Firebase DevServices are preferred"); + } + if (!dockerStatusBuildItem.isContainerRuntimeAvailable()) { LOGGER.warn("Not starting devservice because docker is not available"); return null; diff --git a/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/FirebaseDevServiceConfig.java b/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/FirebaseDevServiceConfig.java new file mode 100644 index 00000000..c3e2041a --- /dev/null +++ b/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/FirebaseDevServiceConfig.java @@ -0,0 +1,23 @@ +package io.quarkiverse.googlecloudservices.pubsub.deployment; + +import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; + +import java.util.Optional; + +/** + * Config mapping to detect if the Firebase Dev Services are running, in which case the PubSub dev service + * will be disabled by default as these two Devservice are in conflict with each other. + */ +@ConfigMapping(prefix = "quarkus.google.cloud.firebase.devservice") +@ConfigRoot +public interface FirebaseDevServiceConfig { + + /** + * Indicates to use the dev service for Firebase. The default value is not setup unless the firebase module + * is included. In that case, the Firebase devservices will by default be preferred and the DevService for + * PubSub will be disabled. + */ + Optional preferFirebaseDevServices(); + +} diff --git a/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/PubSubDevServiceProcessor.java b/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/PubSubDevServiceProcessor.java index 096914f4..cf4251a3 100644 --- a/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/PubSubDevServiceProcessor.java +++ b/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/PubSubDevServiceProcessor.java @@ -35,6 +35,7 @@ public class PubSubDevServiceProcessor { @BuildStep public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildItem, PubSubBuildTimeConfig pubSubBuildTimeConfig, + FirebaseDevServiceConfig firebaseConfig, List devServicesSharedNetworkBuildItem, Optional consoleInstalledBuildItem, CuratedApplicationShutdownBuildItem closeBuildItem, @@ -57,7 +58,7 @@ public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildI // Try starting the container if conditions are met try { devService = startContainerIfAvailable(dockerStatusBuildItem, pubSubBuildTimeConfig.devservice(), - globalDevServicesConfig.timeout); + firebaseConfig, globalDevServicesConfig.timeout); } catch (Throwable t) { LOGGER.warn("Unable to start PubSub dev service", t); // Dump captured logs in case of an error @@ -80,6 +81,7 @@ public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildI */ private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(DockerStatusBuildItem dockerStatusBuildItem, PubSubDevServiceConfig config, + FirebaseDevServiceConfig firebaseConfig, Optional timeout) { if (!config.enabled()) { // PubSub service explicitly disabled @@ -87,6 +89,11 @@ private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(D return null; } + if (firebaseConfig.preferFirebaseDevServices().orElse(false)) { + // Firebase DevServices are included, use them instead + LOGGER.debug("Not starting Dev Services for Firestore as the Firebase DevServices are preferred"); + } + if (!dockerStatusBuildItem.isContainerRuntimeAvailable()) { LOGGER.warn("Not starting devservice because docker is not available"); return null; From 3e34037aed0296b9aeb8129b020fd86596bc4185 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 1 Nov 2024 21:24:34 +0100 Subject: [PATCH 004/101] Create test to use both Firestore and pubsub --- .../it/firebase/FirebaseResource.java | 20 +++++++++++++++---- .../src/main/resources/application.properties | 1 + .../it/firebase/FirebaseResourceTest.java | 7 +++---- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/integration-tests/firebase/src/main/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResource.java b/integration-tests/firebase/src/main/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResource.java index dbcfbe0f..a04f76dd 100644 --- a/integration-tests/firebase/src/main/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResource.java +++ b/integration-tests/firebase/src/main/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResource.java @@ -2,6 +2,7 @@ import com.google.cloud.firestore.Firestore; import com.google.cloud.pubsub.v1.Publisher; +import com.google.protobuf.ByteString; import com.google.pubsub.v1.PubsubMessage; import io.quarkiverse.googlecloudservices.pubsub.QuarkusPubSub; import io.quarkus.runtime.StartupEvent; @@ -13,6 +14,8 @@ import jakarta.ws.rs.core.Response; import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.Map; import java.util.concurrent.ExecutionException; @@ -34,13 +37,16 @@ public void init(@Observes StartupEvent event) throws IOException { } @POST - public void createData() throws InterruptedException { + public void createData(String data) throws InterruptedException, ExecutionException { Object monitor = new Object(); - quarkusPubSub.subscriber("test", (message, consumer) -> { + var subscriber = quarkusPubSub.subscriber("test", (message, consumer) -> { try { var col = firestore.collection("test"); - col.document("test").create(Map.of("test", "test")).get(); + var msgData = message.getData().toString(StandardCharsets.UTF_8); + var fields = Map.of("test", msgData); + + col.document("test").create(fields).get(); } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } @@ -51,11 +57,17 @@ public void createData() throws InterruptedException { monitor.notify(); } }); + subscriber.startAsync().awaitRunning(); - publisher.publish(PubsubMessage.newBuilder().build()); + publisher.publish(PubsubMessage + .newBuilder() + .setData(ByteString.copyFrom(data, StandardCharsets.UTF_8)) + .build()).get(); synchronized (monitor) { monitor.wait(5000); } + + subscriber.stopAsync().awaitTerminated(); } @GET diff --git a/integration-tests/firebase/src/main/resources/application.properties b/integration-tests/firebase/src/main/resources/application.properties index a59d0f2e..6e885816 100644 --- a/integration-tests/firebase/src/main/resources/application.properties +++ b/integration-tests/firebase/src/main/resources/application.properties @@ -1,6 +1,7 @@ # Set the project ID with the demo- prefix to use an emulated service. # When the emulator is started with this project ID, non-emulated services access will fail. quarkus.google.cloud.project-id=demo-test-project-id +quarkus.google.cloud.access-token-enabled=false quarkus.google.cloud.firebase.auth.enabled=true quarkus.google.cloud.firebase.auth.devservice.enabled=true quarkus.google.cloud.pubsub.devservice.enabled=true diff --git a/integration-tests/firebase/src/test/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResourceTest.java b/integration-tests/firebase/src/test/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResourceTest.java index 0b88ab40..eaa7797b 100644 --- a/integration-tests/firebase/src/test/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResourceTest.java +++ b/integration-tests/firebase/src/test/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResourceTest.java @@ -11,22 +11,21 @@ public class FirebaseResourceTest { @Test - void shouldCreateUser() { + void shouldCreateDataUsingPubsubInFirestore() { given() - .contentType(ContentType.JSON) + .body("some test string") .post("/app") .then() .log().ifValidationFails() .statusCode(204); given() - .contentType(ContentType.JSON) .get("/app") .then() .log().ifValidationFails() .statusCode(200) .assertThat() - .body(is("test")); + .body(is("some test string")); } From 70f9eb865453dde014558a18ab07bec79cb6f7ce Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sat, 2 Nov 2024 12:41:12 +0100 Subject: [PATCH 005/101] Formatting fixes --- .../deployment/FirebaseDevServiceConfig.java | 14 ++++++++--- .../FirebaseDevServiceProcessor.java | 17 +++++--------- .../it/firebase/FirebaseResource.java | 23 ++++++++++--------- .../it/firebase/FirebaseResourceTest.java | 10 ++++---- 4 files changed, 33 insertions(+), 31 deletions(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index 0eff2548..ab844c64 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -96,14 +96,21 @@ interface DevService { /** * Indicate to use a custom firebase.json file instead of the automatically generated one. The custom - * firebase.json file MUST include a setting of

"host" : "0.0.0.0"
to ensure the ports of the + * firebase.json file MUST include a setting of + * + *
+             * "host" : "0.0.0.0"
+             * 
+ * + * to ensure the ports of the * emulator are exposed correctly at the docker container level. */ Optional customFirebaseJson(); /** * Sets the JAVA tool options for emulators based on the Java runtime environment. - * See also here + * See also + * here */ Optional javaToolOptions(); @@ -111,7 +118,8 @@ interface DevService { * Allow to import and export data. Specify a path relative to the current working directory of the executable * (for most unit tests, this is the root of the build directory) to be used for import and export of emulator * data. - * See also here + * See also here */ Optional emulatorData(); diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java index 05444f77..3b8bf1f4 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java @@ -314,13 +314,11 @@ private void installNeededSoftware() { } private void authenticateToFirebase() { - firebaseConfig.token().ifPresent(token -> - dockerBuilder.env("FIREBASE_TOKEN", token)); + firebaseConfig.token().ifPresent(token -> dockerBuilder.env("FIREBASE_TOKEN", token)); } private void setupJavaToolOptions() { - firebaseConfig.javaToolOptions().ifPresent( toolOptions -> - dockerBuilder.env("JAVA_TOOL_OPTIONS", toolOptions)); + firebaseConfig.javaToolOptions().ifPresent(toolOptions -> dockerBuilder.env("JAVA_TOOL_OPTIONS", toolOptions)); } private void addFirebaseJson() { @@ -328,8 +326,7 @@ private void addFirebaseJson() { firebaseConfig.customFirebaseJson().ifPresentOrElse( this::includeCustomFirebaseJson, - this::generateFirebaseJson - ); + this::generateFirebaseJson); this.dockerBuilder.add("firebase.json", "/srv/firebase/firebase.json"); } @@ -337,8 +334,7 @@ private void addFirebaseJson() { private void includeCustomFirebaseJson(String customFilePath) { this.result.withFileFromPath( "firebase.json", - new File(customFilePath).toPath() - ); + new File(customFilePath).toPath()); } private void generateFirebaseJson() { @@ -351,8 +347,7 @@ private void generateFirebaseJson() { .keySet() .stream() .filter(e -> isEmulatorEnabled(devServices, e)) - .map((emulator -> - "\t\t\"" + emulator.emulatorName + "\": {\n" + + .map((emulator -> "\t\t\"" + emulator.emulatorName + "\": {\n" + "\t\t\t\"port\": " + emulator.internalPort + ",\n" + "\t\t\t\"host\": \"0.0.0.0\"\n" + "\t\t}")) @@ -379,7 +374,7 @@ private void runExecutable() { var importArgument = firebaseConfig .emulatorData() - .map( path -> " --import=/srv/firebase/data --export-on-exit") + .map(path -> " --import=/srv/firebase/data --export-on-exit") .orElse(""); dockerBuilder diff --git a/integration-tests/firebase/src/main/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResource.java b/integration-tests/firebase/src/main/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResource.java index a04f76dd..3d084f66 100644 --- a/integration-tests/firebase/src/main/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResource.java +++ b/integration-tests/firebase/src/main/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResource.java @@ -1,11 +1,10 @@ package io.quarkiverse.googlecloudservices.it.firebase; -import com.google.cloud.firestore.Firestore; -import com.google.cloud.pubsub.v1.Publisher; -import com.google.protobuf.ByteString; -import com.google.pubsub.v1.PubsubMessage; -import io.quarkiverse.googlecloudservices.pubsub.QuarkusPubSub; -import io.quarkus.runtime.StartupEvent; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.concurrent.ExecutionException; + import jakarta.enterprise.event.Observes; import jakarta.inject.Inject; import jakarta.ws.rs.GET; @@ -13,11 +12,13 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.core.Response; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Map; -import java.util.concurrent.ExecutionException; +import com.google.cloud.firestore.Firestore; +import com.google.cloud.pubsub.v1.Publisher; +import com.google.protobuf.ByteString; +import com.google.pubsub.v1.PubsubMessage; + +import io.quarkiverse.googlecloudservices.pubsub.QuarkusPubSub; +import io.quarkus.runtime.StartupEvent; @Path("/app") public class FirebaseResource { diff --git a/integration-tests/firebase/src/test/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResourceTest.java b/integration-tests/firebase/src/test/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResourceTest.java index eaa7797b..0ef5470f 100644 --- a/integration-tests/firebase/src/test/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResourceTest.java +++ b/integration-tests/firebase/src/test/java/io/quarkiverse/googlecloudservices/it/firebase/FirebaseResourceTest.java @@ -1,12 +1,12 @@ package io.quarkiverse.googlecloudservices.it.firebase; -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.http.ContentType; -import org.junit.jupiter.api.Test; - import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.*; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; + @QuarkusTest public class FirebaseResourceTest { @@ -28,6 +28,4 @@ void shouldCreateDataUsingPubsubInFirestore() { .body(is("some test string")); } - - } From 81841f8c48f92ccf15ae1b5cf9ff72ff3071e239 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sat, 2 Nov 2024 12:41:15 +0100 Subject: [PATCH 006/101] Formatting fixes --- .../quarkiverse/googlecloudservices/pubsub/QuarkusPubSub.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubsub/runtime/src/main/java/io/quarkiverse/googlecloudservices/pubsub/QuarkusPubSub.java b/pubsub/runtime/src/main/java/io/quarkiverse/googlecloudservices/pubsub/QuarkusPubSub.java index 50b2f31e..225439a7 100644 --- a/pubsub/runtime/src/main/java/io/quarkiverse/googlecloudservices/pubsub/QuarkusPubSub.java +++ b/pubsub/runtime/src/main/java/io/quarkiverse/googlecloudservices/pubsub/QuarkusPubSub.java @@ -4,7 +4,6 @@ import java.util.Optional; import java.util.stream.StreamSupport; -import com.google.api.gax.core.NoCredentialsProvider; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.ApplicationScoped; @@ -12,6 +11,7 @@ import jakarta.inject.Inject; import com.google.api.gax.core.CredentialsProvider; +import com.google.api.gax.core.NoCredentialsProvider; import com.google.api.gax.grpc.GrpcTransportChannel; import com.google.api.gax.rpc.FixedTransportChannelProvider; import com.google.api.gax.rpc.TransportChannelProvider; From 62122cc5c3e8af145e3aaea7a4d58b9f578aca5e Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sat, 2 Nov 2024 12:41:25 +0100 Subject: [PATCH 007/101] Version bump for new modules --- firebase/deployment/pom.xml | 2 +- firebase/pom.xml | 2 +- firebase/runtime/pom.xml | 2 +- integration-tests/firebase/pom.xml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/firebase/deployment/pom.xml b/firebase/deployment/pom.xml index 4806d2a6..968fb44c 100644 --- a/firebase/deployment/pom.xml +++ b/firebase/deployment/pom.xml @@ -3,7 +3,7 @@ io.quarkiverse.googlecloudservices quarkus-google-cloud-firebase-parent - 2.13.0-SNAPSHOT + 2.14.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/firebase/pom.xml b/firebase/pom.xml index 6a7a61d8..c5b871e2 100644 --- a/firebase/pom.xml +++ b/firebase/pom.xml @@ -3,7 +3,7 @@ io.quarkiverse.googlecloudservices quarkus-google-cloud-services-parent - 2.13.0-SNAPSHOT + 2.14.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/firebase/runtime/pom.xml b/firebase/runtime/pom.xml index 871f5cdb..969f6248 100644 --- a/firebase/runtime/pom.xml +++ b/firebase/runtime/pom.xml @@ -3,7 +3,7 @@ io.quarkiverse.googlecloudservices quarkus-google-cloud-firebase-parent - 2.13.0-SNAPSHOT + 2.14.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/integration-tests/firebase/pom.xml b/integration-tests/firebase/pom.xml index 95283e5e..c0799bb1 100644 --- a/integration-tests/firebase/pom.xml +++ b/integration-tests/firebase/pom.xml @@ -3,7 +3,7 @@ io.quarkiverse.googlecloudservices quarkus-google-cloud-services-integration-tests-parent - 2.13.0-SNAPSHOT + 2.14.0-SNAPSHOT ../pom.xml 4.0.0 @@ -20,7 +20,7 @@ io.quarkus - quarkus-resteasy-reactive-jackson + quarkus-rest-jackson io.quarkiverse.googlecloudservices From e2222dd046133ae3b1df9872dcc90a0d5d5f531a Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sat, 2 Nov 2024 13:07:20 +0100 Subject: [PATCH 008/101] Docs regenerated --- .../quarkus-google-cloud-firebase-admin.adoc | 17 ++ ...e-cloud-firebase-admin_quarkus.google.adoc | 17 ++ .../quarkus-google-cloud-firebase.adoc | 181 ++++++++++++------ ...-google-cloud-firebase_quarkus.google.adoc | 181 ++++++++++++------ .../includes/quarkus-google-cloud-pubsub.adoc | 20 ++ ...us-google-cloud-pubsub_quarkus.google.adoc | 20 ++ 6 files changed, 326 insertions(+), 110 deletions(-) diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin.adoc index 9cb12f85..b40a10be 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin.adoc @@ -24,5 +24,22 @@ endif::add-copy-button-to-env-var[] |boolean |`false` +a| [[quarkus-google-cloud-firebase-admin_quarkus-google-cloud-firebase-auth-emulator-host]] [.property-path]##link:#quarkus-google-cloud-firebase-admin_quarkus-google-cloud-firebase-auth-emulator-host[`quarkus.google.cloud.firebase.auth.emulator-host`]## + +[.description] +-- +Sets the emulator host to use. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_EMULATOR_HOST+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_EMULATOR_HOST+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + |=== diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin_quarkus.google.adoc index 9cb12f85..b40a10be 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin_quarkus.google.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin_quarkus.google.adoc @@ -24,5 +24,22 @@ endif::add-copy-button-to-env-var[] |boolean |`false` +a| [[quarkus-google-cloud-firebase-admin_quarkus-google-cloud-firebase-auth-emulator-host]] [.property-path]##link:#quarkus-google-cloud-firebase-admin_quarkus-google-cloud-firebase-auth-emulator-host[`quarkus.google.cloud.firebase.auth.emulator-host`]## + +[.description] +-- +Sets the emulator host to use. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_EMULATOR_HOST+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_EMULATOR_HOST+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + |=== diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc index b97d517b..93aa7666 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc @@ -1,4 +1,3 @@ -:summaryTableId: quarkus-google-cloud-firebase_quarkus-google [.configuration-legend] icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime [.configuration-reference.searchable, cols="80,.^10,.^10"] @@ -8,7 +7,24 @@ h|[.header-title]##Configuration property## h|Type h|Default -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-image-name]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.image-name`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-project-id]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-project-id[`quarkus.google.cloud.project-id`]## + +[.description] +-- +Google Cloud project ID. The project is required to be set if you use the Firebase Auth Dev service. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PROJECT_ID+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PROJECT_ID+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-image-name]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-image-name[`quarkus.google.cloud.firebase.devservice.image-name`]## [.description] -- @@ -16,16 +32,16 @@ Sets the Docker image name for the Google Cloud SDK. This image is used to emula ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_IMAGE_NAME+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++` endif::add-copy-button-to-env-var[] -- |string |`node:23-alpine` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-firebase-version]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.firebase-version`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-version]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-version[`quarkus.google.cloud.firebase.devservice.firebase-version`]## [.description] -- @@ -33,16 +49,16 @@ Sets the firebase version to use. Defaults to the latest version. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++` endif::add-copy-button-to-env-var[] -- |string |`latest` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-token]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.token`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-token]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-token[`quarkus.google.cloud.firebase.devservice.token`]## [.description] -- @@ -50,16 +66,73 @@ The token to use for firebase authentication. Run `firebase login:ci` locally to ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_TOKEN+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-custom-firebase-json]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-custom-firebase-json[`quarkus.google.cloud.firebase.devservice.custom-firebase-json`]## + +[.description] +-- +Indicate to use a custom firebase.json file instead of the automatically generated one. The custom firebase.json file MUST include a setting of + +``` +"host" : "0.0.0.0" +``` + +to ensure the ports of the emulator are exposed correctly at the docker container level. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_TOKEN+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-ui-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.ui.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-java-tool-options]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-java-tool-options[`quarkus.google.cloud.firebase.devservice.java-tool-options`]## + +[.description] +-- +Sets the JAVA tool options for emulators based on the Java runtime environment. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#specifying_java_options[here] + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-emulator-data]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-emulator-data[`quarkus.google.cloud.firebase.devservice.emulator-data`]## + +[.description] +-- +Allow to import and export data. Specify a path relative to the current working directory of the executable (for most unit tests, this is the root of the build directory) to be used for import and export of emulator data. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data[here] + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-enabled[`quarkus.google.cloud.firebase.devservice.ui.enabled`]## [.description] -- @@ -67,16 +140,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean -|`false` +|`true` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-ui-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.ui.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-emulator-port[`quarkus.google.cloud.firebase.devservice.ui.emulator-port`]## [.description] -- @@ -84,16 +157,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-auth-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.auth.devservice.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-enabled[`quarkus.google.cloud.firebase.auth.devservice.enabled`]## [.description] -- @@ -101,16 +174,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-auth-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.auth.devservice.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-emulator-port[`quarkus.google.cloud.firebase.auth.devservice.emulator-port`]## [.description] -- @@ -118,16 +191,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-hosting-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.hosting.devservice.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-enabled[`quarkus.google.cloud.firebase.hosting.devservice.enabled`]## [.description] -- @@ -135,16 +208,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-hosting-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.hosting.devservice.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-emulator-port[`quarkus.google.cloud.firebase.hosting.devservice.emulator-port`]## [.description] -- @@ -152,16 +225,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-database-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.database.devservice.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-enabled[`quarkus.google.cloud.database.devservice.enabled`]## [.description] -- @@ -169,16 +242,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-database-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.database.devservice.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-emulator-port[`quarkus.google.cloud.database.devservice.emulator-port`]## [.description] -- @@ -186,16 +259,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firestore-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firestore.devservice.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-enabled[`quarkus.google.cloud.firestore.devservice.enabled`]## [.description] -- @@ -203,16 +276,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firestore-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firestore.devservice.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-emulator-port[`quarkus.google.cloud.firestore.devservice.emulator-port`]## [.description] -- @@ -220,16 +293,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-functions-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.functions.devservice.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-enabled[`quarkus.google.cloud.functions.devservice.enabled`]## [.description] -- @@ -237,16 +310,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-functions-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.functions.devservice.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-emulator-port[`quarkus.google.cloud.functions.devservice.emulator-port`]## [.description] -- @@ -254,16 +327,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-pub-sub-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.pub-sub.devservice.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-enabled[`quarkus.google.cloud.pub-sub.devservice.enabled`]## [.description] -- @@ -271,16 +344,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-pub-sub-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.pub-sub.devservice.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-emulator-port[`quarkus.google.cloud.pub-sub.devservice.emulator-port`]## [.description] -- @@ -288,10 +361,10 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int @@ -299,5 +372,3 @@ endif::add-copy-button-to-env-var[] |=== - -:!summaryTableId: \ No newline at end of file diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc index b97d517b..93aa7666 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc @@ -1,4 +1,3 @@ -:summaryTableId: quarkus-google-cloud-firebase_quarkus-google [.configuration-legend] icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime [.configuration-reference.searchable, cols="80,.^10,.^10"] @@ -8,7 +7,24 @@ h|[.header-title]##Configuration property## h|Type h|Default -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-image-name]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.image-name`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-project-id]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-project-id[`quarkus.google.cloud.project-id`]## + +[.description] +-- +Google Cloud project ID. The project is required to be set if you use the Firebase Auth Dev service. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PROJECT_ID+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PROJECT_ID+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-image-name]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-image-name[`quarkus.google.cloud.firebase.devservice.image-name`]## [.description] -- @@ -16,16 +32,16 @@ Sets the Docker image name for the Google Cloud SDK. This image is used to emula ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_IMAGE_NAME+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++` endif::add-copy-button-to-env-var[] -- |string |`node:23-alpine` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-firebase-version]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.firebase-version`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-version]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-version[`quarkus.google.cloud.firebase.devservice.firebase-version`]## [.description] -- @@ -33,16 +49,16 @@ Sets the firebase version to use. Defaults to the latest version. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++` endif::add-copy-button-to-env-var[] -- |string |`latest` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-token]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.token`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-token]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-token[`quarkus.google.cloud.firebase.devservice.token`]## [.description] -- @@ -50,16 +66,73 @@ The token to use for firebase authentication. Run `firebase login:ci` locally to ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_TOKEN+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-custom-firebase-json]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-custom-firebase-json[`quarkus.google.cloud.firebase.devservice.custom-firebase-json`]## + +[.description] +-- +Indicate to use a custom firebase.json file instead of the automatically generated one. The custom firebase.json file MUST include a setting of + +``` +"host" : "0.0.0.0" +``` + +to ensure the ports of the emulator are exposed correctly at the docker container level. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_TOKEN+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-ui-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.ui.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-java-tool-options]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-java-tool-options[`quarkus.google.cloud.firebase.devservice.java-tool-options`]## + +[.description] +-- +Sets the JAVA tool options for emulators based on the Java runtime environment. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#specifying_java_options[here] + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-emulator-data]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-emulator-data[`quarkus.google.cloud.firebase.devservice.emulator-data`]## + +[.description] +-- +Allow to import and export data. Specify a path relative to the current working directory of the executable (for most unit tests, this is the root of the build directory) to be used for import and export of emulator data. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data[here] + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-enabled[`quarkus.google.cloud.firebase.devservice.ui.enabled`]## [.description] -- @@ -67,16 +140,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean -|`false` +|`true` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-devservice-ui-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.devservice.ui.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-emulator-port[`quarkus.google.cloud.firebase.devservice.ui.emulator-port`]## [.description] -- @@ -84,16 +157,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-auth-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.auth.devservice.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-enabled[`quarkus.google.cloud.firebase.auth.devservice.enabled`]## [.description] -- @@ -101,16 +174,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-auth-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.auth.devservice.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-emulator-port[`quarkus.google.cloud.firebase.auth.devservice.emulator-port`]## [.description] -- @@ -118,16 +191,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-hosting-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.hosting.devservice.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-enabled[`quarkus.google.cloud.firebase.hosting.devservice.enabled`]## [.description] -- @@ -135,16 +208,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-hosting-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firebase.hosting.devservice.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-emulator-port[`quarkus.google.cloud.firebase.hosting.devservice.emulator-port`]## [.description] -- @@ -152,16 +225,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-database-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.database.devservice.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-enabled[`quarkus.google.cloud.database.devservice.enabled`]## [.description] -- @@ -169,16 +242,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-database-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.database.devservice.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-emulator-port[`quarkus.google.cloud.database.devservice.emulator-port`]## [.description] -- @@ -186,16 +259,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DATABASE_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firestore-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firestore.devservice.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-enabled[`quarkus.google.cloud.firestore.devservice.enabled`]## [.description] -- @@ -203,16 +276,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firestore-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.firestore.devservice.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-emulator-port[`quarkus.google.cloud.firestore.devservice.emulator-port`]## [.description] -- @@ -220,16 +293,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-functions-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.functions.devservice.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-enabled[`quarkus.google.cloud.functions.devservice.enabled`]## [.description] -- @@ -237,16 +310,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-functions-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.functions.devservice.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-emulator-port[`quarkus.google.cloud.functions.devservice.emulator-port`]## [.description] -- @@ -254,16 +327,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-pub-sub-devservice-enabled]] [.property-path]##`quarkus.google.cloud.firebase.devservice.pub-sub.devservice.enabled`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-enabled[`quarkus.google.cloud.pub-sub.devservice.enabled`]## [.description] -- @@ -271,16 +344,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-pub-sub-devservice-emulator-port]] [.property-path]##`quarkus.google.cloud.firebase.devservice.pub-sub.devservice.emulator-port`## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-emulator-port[`quarkus.google.cloud.pub-sub.devservice.emulator-port`]## [.description] -- @@ -288,10 +361,10 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int @@ -299,5 +372,3 @@ endif::add-copy-button-to-env-var[] |=== - -:!summaryTableId: \ No newline at end of file diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub.adoc index 5cdc8d91..fe0e1300 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub.adoc @@ -75,5 +75,25 @@ endif::add-copy-button-to-env-var[] |string | +a| [[quarkus-google-cloud-pubsub_quarkus-google-cloud-pubsub-use-emulator-credentials]] [.property-path]##link:#quarkus-google-cloud-pubsub_quarkus-google-cloud-pubsub-use-emulator-credentials[`quarkus.google.cloud.pubsub.use-emulator-credentials`]## + +[.description] +-- +Forces the usage of emulator credentials. The logic automatically uses emulator credentials in case the emulatorHost is set. + + - If true: force usage of emulator credentials + - If false: force not using emulator credentials + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_USE_EMULATOR_CREDENTIALS+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_USE_EMULATOR_CREDENTIALS+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + |=== diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub_quarkus.google.adoc index 5cdc8d91..fe0e1300 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub_quarkus.google.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub_quarkus.google.adoc @@ -75,5 +75,25 @@ endif::add-copy-button-to-env-var[] |string | +a| [[quarkus-google-cloud-pubsub_quarkus-google-cloud-pubsub-use-emulator-credentials]] [.property-path]##link:#quarkus-google-cloud-pubsub_quarkus-google-cloud-pubsub-use-emulator-credentials[`quarkus.google.cloud.pubsub.use-emulator-credentials`]## + +[.description] +-- +Forces the usage of emulator credentials. The logic automatically uses emulator credentials in case the emulatorHost is set. + + - If true: force usage of emulator credentials + - If false: force not using emulator credentials + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_USE_EMULATOR_CREDENTIALS+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_USE_EMULATOR_CREDENTIALS+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + |=== From 06726adba1330609c2618074c22dd2be56397d9a Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sat, 2 Nov 2024 13:15:27 +0100 Subject: [PATCH 009/101] Docs regenerated --- .../includes/quarkus-google-cloud-firebase.adoc | 17 +++++++++++++++++ ...us-google-cloud-firebase_quarkus.google.adoc | 17 +++++++++++++++++ .../quarkus-google-cloud-firestore.adoc | 17 +++++++++++++++++ ...s-google-cloud-firestore_quarkus.google.adoc | 17 +++++++++++++++++ .../includes/quarkus-google-cloud-pubsub.adoc | 17 +++++++++++++++++ ...rkus-google-cloud-pubsub_quarkus.google.adoc | 17 +++++++++++++++++ 6 files changed, 102 insertions(+) diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc index 93aa7666..bad05ae9 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc @@ -24,6 +24,23 @@ endif::add-copy-button-to-env-var[] |string | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services[`quarkus.google.cloud.firebase.devservice.prefer-firebase-dev-services`]## + +[.description] +-- +Indicates to use the dev service for Firebase. The default value is true. This indicator is used to detect the Firebase DevService and disable the DevServices for extensions which conflict with the Firebase DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-image-name]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-image-name[`quarkus.google.cloud.firebase.devservice.image-name`]## [.description] diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc index 93aa7666..bad05ae9 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc @@ -24,6 +24,23 @@ endif::add-copy-button-to-env-var[] |string | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services[`quarkus.google.cloud.firebase.devservice.prefer-firebase-dev-services`]## + +[.description] +-- +Indicates to use the dev service for Firebase. The default value is true. This indicator is used to detect the Firebase DevService and disable the DevServices for extensions which conflict with the Firebase DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-image-name]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-image-name[`quarkus.google.cloud.firebase.devservice.image-name`]## [.description] diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firestore.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firestore.adoc index f64c005f..99003066 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firestore.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firestore.adoc @@ -7,6 +7,23 @@ h|[.header-title]##Configuration property## h|Type h|Default +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firestore_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-firestore_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services[`quarkus.google.cloud.firebase.devservice.prefer-firebase-dev-services`]## + +[.description] +-- +Indicates to use the dev service for Firebase. The default value is not setup unless the firebase module is included. In that case, the Firebase devservices will by default be preferred and the DevService for PubSub will be disabled. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firestore_quarkus-google-cloud-firestore-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firestore_quarkus-google-cloud-firestore-devservice-enabled[`quarkus.google.cloud.firestore.devservice.enabled`]## [.description] diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firestore_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firestore_quarkus.google.adoc index f64c005f..99003066 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firestore_quarkus.google.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firestore_quarkus.google.adoc @@ -7,6 +7,23 @@ h|[.header-title]##Configuration property## h|Type h|Default +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firestore_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-firestore_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services[`quarkus.google.cloud.firebase.devservice.prefer-firebase-dev-services`]## + +[.description] +-- +Indicates to use the dev service for Firebase. The default value is not setup unless the firebase module is included. In that case, the Firebase devservices will by default be preferred and the DevService for PubSub will be disabled. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firestore_quarkus-google-cloud-firestore-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firestore_quarkus-google-cloud-firestore-devservice-enabled[`quarkus.google.cloud.firestore.devservice.enabled`]## [.description] diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub.adoc index fe0e1300..22dae261 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub.adoc @@ -58,6 +58,23 @@ endif::add-copy-button-to-env-var[] |int | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-pubsub_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-pubsub_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services[`quarkus.google.cloud.firebase.devservice.prefer-firebase-dev-services`]## + +[.description] +-- +Indicates to use the dev service for Firebase. The default value is not setup unless the firebase module is included. In that case, the Firebase devservices will by default be preferred and the DevService for PubSub will be disabled. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| + a| [[quarkus-google-cloud-pubsub_quarkus-google-cloud-pubsub-emulator-host]] [.property-path]##link:#quarkus-google-cloud-pubsub_quarkus-google-cloud-pubsub-emulator-host[`quarkus.google.cloud.pubsub.emulator-host`]## [.description] diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub_quarkus.google.adoc index fe0e1300..22dae261 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub_quarkus.google.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-pubsub_quarkus.google.adoc @@ -58,6 +58,23 @@ endif::add-copy-button-to-env-var[] |int | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-pubsub_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-pubsub_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services[`quarkus.google.cloud.firebase.devservice.prefer-firebase-dev-services`]## + +[.description] +-- +Indicates to use the dev service for Firebase. The default value is not setup unless the firebase module is included. In that case, the Firebase devservices will by default be preferred and the DevService for PubSub will be disabled. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| + a| [[quarkus-google-cloud-pubsub_quarkus-google-cloud-pubsub-emulator-host]] [.property-path]##link:#quarkus-google-cloud-pubsub_quarkus-google-cloud-pubsub-emulator-host[`quarkus.google.cloud.pubsub.emulator-host`]## [.description] From 81f4d9936a08e3cb5f9e29b491b313156ae52d8d Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sat, 2 Nov 2024 13:15:35 +0100 Subject: [PATCH 010/101] Formatting fixes --- .../firestore/deployment/FirebaseDevServiceConfig.java | 3 ++- .../pubsub/deployment/FirebaseDevServiceConfig.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirebaseDevServiceConfig.java b/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirebaseDevServiceConfig.java index 3abe4c70..418a634d 100644 --- a/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirebaseDevServiceConfig.java +++ b/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirebaseDevServiceConfig.java @@ -1,8 +1,9 @@ package io.quarkiverse.googlecloudservices.firestore.deployment; +import java.util.Optional; + import io.quarkus.runtime.annotations.ConfigRoot; import io.smallrye.config.ConfigMapping; -import java.util.Optional; /** * Config mapping to detect if the Firebase Dev Services are running, in which case the PubSub dev service diff --git a/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/FirebaseDevServiceConfig.java b/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/FirebaseDevServiceConfig.java index c3e2041a..ecd17733 100644 --- a/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/FirebaseDevServiceConfig.java +++ b/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/FirebaseDevServiceConfig.java @@ -1,10 +1,10 @@ package io.quarkiverse.googlecloudservices.pubsub.deployment; +import java.util.Optional; + import io.quarkus.runtime.annotations.ConfigRoot; import io.smallrye.config.ConfigMapping; -import java.util.Optional; - /** * Config mapping to detect if the Firebase Dev Services are running, in which case the PubSub dev service * will be disabled by default as these two Devservice are in conflict with each other. From ba22251ed28851a309e9aee6aff7a7059a3ddef6 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sat, 2 Nov 2024 17:45:08 +0100 Subject: [PATCH 011/101] Use emulator credentials by default in case the config property is set. --- .../admin/runtime/FirebaseAdminProducer.java | 17 +++++++++++++++-- .../admin/runtime/FirebaseAuthConfig.java | 12 ++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java index a00fd623..e55da165 100644 --- a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java +++ b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java @@ -1,7 +1,9 @@ package io.quarkiverse.googlecloudservices.firebase.admin.runtime; +import com.google.firebase.internal.EmulatorCredentials; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Default; +import jakarta.enterprise.inject.Instance; import jakarta.enterprise.inject.Produces; import jakarta.inject.Inject; import jakarta.inject.Singleton; @@ -22,11 +24,14 @@ public class FirebaseAdminProducer { @Inject - Credentials googleCredentials; + Instance googleCredentials; @Inject GcpConfigHolder gcpConfigHolder; + @Inject + FirebaseAuthConfig firebaseAuthConfig; + @Produces @Singleton @Default @@ -45,7 +50,7 @@ public FirebaseApp getFirebaseApp() { GcpBootstrapConfiguration gcpConfiguration = gcpConfigHolder.getBootstrapConfig(); FirebaseOptions firebaseOptions = FirebaseOptions.builder() - .setCredentials((GoogleCredentials) googleCredentials) + .setCredentials(googleCredentials()) .setProjectId(gcpConfiguration.projectId().orElse(null)) .build(); @@ -55,6 +60,14 @@ public FirebaseApp getFirebaseApp() { .orElseGet(() -> initializeFirebaseApp(gcpConfiguration, firebaseOptions)); } + private GoogleCredentials googleCredentials() { + if (firebaseAuthConfig.emulatorHost().isPresent() && firebaseAuthConfig.useEmulatorCredentials()) { + return new EmulatorCredentials(); + } else { + return (GoogleCredentials) googleCredentials.get(); + } + } + private FirebaseApp initializeFirebaseApp(GcpBootstrapConfiguration gcpBootstrapConfiguration, FirebaseOptions firebaseOptions) { return gcpBootstrapConfiguration.projectId() diff --git a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java index 6e202300..89adc8b2 100644 --- a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java +++ b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java @@ -5,6 +5,7 @@ import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithDefault; /** * Root configuration class for Google Cloud Firebase Auth setup. @@ -24,4 +25,15 @@ public interface FirebaseAuthConfig { */ Optional emulatorHost(); + /** + * Forces the usage of emulator credentials. The logic automatically uses emulator credentials in case + * the emulatorHost is set. + *
    + *
  • If true: force usage of emulator credentials
  • + *
  • If false: force not using emulator credentials
  • + *
+ */ + @WithDefault("true") + boolean useEmulatorCredentials(); + } From 530dce00e9bdacb48b6f7cb6eca6f0f28c167c58 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sat, 2 Nov 2024 18:05:26 +0100 Subject: [PATCH 012/101] Generated docs and formatted sources --- .../quarkus-google-cloud-firebase-admin.adoc | 20 +++++++++++++++++++ ...e-cloud-firebase-admin_quarkus.google.adoc | 20 +++++++++++++++++++ .../admin/runtime/FirebaseAdminProducer.java | 2 +- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin.adoc index b40a10be..6d062718 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin.adoc @@ -41,5 +41,25 @@ endif::add-copy-button-to-env-var[] |string | +a| [[quarkus-google-cloud-firebase-admin_quarkus-google-cloud-firebase-auth-use-emulator-credentials]] [.property-path]##link:#quarkus-google-cloud-firebase-admin_quarkus-google-cloud-firebase-auth-use-emulator-credentials[`quarkus.google.cloud.firebase.auth.use-emulator-credentials`]## + +[.description] +-- +Forces the usage of emulator credentials. The logic automatically uses emulator credentials in case the emulatorHost is set. + + - If true: force usage of emulator credentials + - If false: force not using emulator credentials + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_USE_EMULATOR_CREDENTIALS+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_USE_EMULATOR_CREDENTIALS+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + |=== diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin_quarkus.google.adoc index b40a10be..6d062718 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin_quarkus.google.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-admin_quarkus.google.adoc @@ -41,5 +41,25 @@ endif::add-copy-button-to-env-var[] |string | +a| [[quarkus-google-cloud-firebase-admin_quarkus-google-cloud-firebase-auth-use-emulator-credentials]] [.property-path]##link:#quarkus-google-cloud-firebase-admin_quarkus-google-cloud-firebase-auth-use-emulator-credentials[`quarkus.google.cloud.firebase.auth.use-emulator-credentials`]## + +[.description] +-- +Forces the usage of emulator credentials. The logic automatically uses emulator credentials in case the emulatorHost is set. + + - If true: force usage of emulator credentials + - If false: force not using emulator credentials + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_USE_EMULATOR_CREDENTIALS+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_USE_EMULATOR_CREDENTIALS+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + |=== diff --git a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java index e55da165..4d160977 100644 --- a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java +++ b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java @@ -1,6 +1,5 @@ package io.quarkiverse.googlecloudservices.firebase.admin.runtime; -import com.google.firebase.internal.EmulatorCredentials; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Instance; @@ -14,6 +13,7 @@ import com.google.firebase.FirebaseOptions; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.internal.Utils; +import com.google.firebase.internal.EmulatorCredentials; import com.google.firebase.internal.FirebaseProcessEnvironment; import io.quarkiverse.googlecloudservices.common.GcpBootstrapConfiguration; From e1db024a6c7c64970dbb29b73e74177f4b01fb8a Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sat, 2 Nov 2024 19:22:08 +0100 Subject: [PATCH 013/101] Dont start pubsub and firestore container if disabled --- .../firestore/deployment/FirestoreDevServiceProcessor.java | 1 + .../pubsub/deployment/PubSubDevServiceProcessor.java | 1 + 2 files changed, 2 insertions(+) diff --git a/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirestoreDevServiceProcessor.java b/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirestoreDevServiceProcessor.java index a13f038e..86cd3f11 100644 --- a/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirestoreDevServiceProcessor.java +++ b/firestore/deployment/src/main/java/io/quarkiverse/googlecloudservices/firestore/deployment/FirestoreDevServiceProcessor.java @@ -92,6 +92,7 @@ private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(D if (firebaseConfig.preferFirebaseDevServices().orElse(false)) { // Firebase DevServices are included, use them instead LOGGER.debug("Not starting Dev Services for Firestore as the Firebase DevServices are preferred"); + return null; } if (!dockerStatusBuildItem.isContainerRuntimeAvailable()) { diff --git a/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/PubSubDevServiceProcessor.java b/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/PubSubDevServiceProcessor.java index cf4251a3..3e2d0460 100644 --- a/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/PubSubDevServiceProcessor.java +++ b/pubsub/deployment/src/main/java/io/quarkiverse/googlecloudservices/pubsub/deployment/PubSubDevServiceProcessor.java @@ -92,6 +92,7 @@ private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(D if (firebaseConfig.preferFirebaseDevServices().orElse(false)) { // Firebase DevServices are included, use them instead LOGGER.debug("Not starting Dev Services for Firestore as the Firebase DevServices are preferred"); + return null; } if (!dockerStatusBuildItem.isContainerRuntimeAvailable()) { From 5c1dc541ecaf5b69b9ccbfa49a54759808c02c82 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Wed, 13 Nov 2024 17:38:46 +0100 Subject: [PATCH 014/101] Moved firebase library versions to bom (as it is shared with the new Firebase module) --- bom/pom.xml | 6 ++++++ firebase-admin/runtime/pom.xml | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index f6aabbfc..efd07690 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -19,6 +19,7 @@ UTF-8 26.45.0 + 9.4.1 0.31.1 @@ -37,6 +38,11 @@ pom import
+ + com.google.firebase + firebase-admin + ${firebase-admin-sdk.version} + diff --git a/firebase-admin/runtime/pom.xml b/firebase-admin/runtime/pom.xml index 1c887c07..11a87119 100644 --- a/firebase-admin/runtime/pom.xml +++ b/firebase-admin/runtime/pom.xml @@ -13,7 +13,6 @@ Use Google Cloud Firebase Admin to perform privileged actions - 9.4.1 2.1 @@ -25,7 +24,6 @@ com.google.firebase firebase-admin - ${firebase-admin-sdk.version} From 58d8693151cb9b19627945ba891b39cb7008fea7 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Wed, 13 Nov 2024 17:40:22 +0100 Subject: [PATCH 015/101] Moved firebase emulator container to separate class, which is totally separated from the quarkus logic. Added support for - UI Logging port - UI Hub endpoint - Firestore websocket port - Cloud Storage --- firebase/deployment/pom.xml | 88 ++++ .../deployment/FirebaseDevServiceConfig.java | 46 +- .../FirebaseDevServiceProcessor.java | 378 ++++----------- .../deployment/FirebaseEmulatorContainer.java | 458 ++++++++++++++++++ ...ebaseEmulatorContainerIntegrationTest.java | 362 ++++++++++++++ 5 files changed, 1054 insertions(+), 278 deletions(-) create mode 100644 firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java create mode 100644 firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java diff --git a/firebase/deployment/pom.xml b/firebase/deployment/pom.xml index 968fb44c..71b8f7b8 100644 --- a/firebase/deployment/pom.xml +++ b/firebase/deployment/pom.xml @@ -28,6 +28,94 @@ org.testcontainers testcontainers + + + + + org.testcontainers + junit-jupiter + test + + + com.google.firebase + firebase-admin + test + + + + io.grpc + grpc-netty-shaded + + + + + io.quarkus + quarkus-grpc-common + test + + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-common-grpc + test + + + com.google.cloud + google-cloud-firestore + test + + + commons-logging + commons-logging + + + javax.annotation + javax.annotation-api + + + org.checkerframework + checker-qual + + + + io.grpc + grpc-netty-shaded + + + org.codehaus.mojo + animal-sniffer-annotations + + + + + com.google.cloud + google-cloud-pubsub + + + commons-logging + commons-logging + + + javax.annotation + javax.annotation-api + + + org.checkerframework + checker-qual + + + + io.grpc + grpc-netty-shaded + + + org.codehaus.mojo + animal-sniffer-annotations + + +
diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index 765ba8ab..cf28deb1 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -52,7 +52,12 @@ public interface FirebaseDevServiceConfig { /** * Configure Google Cloud Pub/Sub */ - PubSub pubSub(); + PubSub pubsub(); + + /** + * Configure Google Cloud Storage + */ + Storage storage(); interface Firebase { @@ -145,6 +150,18 @@ interface UI extends GenericDevService { @WithDefault("true") @Override boolean enabled(); + + /** + * Port on which to expose the logging endpoint port. This is needed in case you want to view the logging + * via the Emulator UI. + */ + Optional loggingPort(); + + /** + * Port on which to expose the hub endpoint port. This is needed if you want to use the hub API of + * the Emulator UI. + */ + Optional hubPort(); } } @@ -171,7 +188,19 @@ interface Firestore { /** * Configuration for the Firestore emulator */ - GenericDevService devservice(); + FirestoreDevService devservice(); + + /** + * Extension for the Firestore dev service. This service can also configure the websocket port. + */ + interface FirestoreDevService extends GenericDevService { + + /** + * Port on which to expose the websocket port. This is needed in case the Firestore Emulator UI needs is + * used. + */ + Optional websocketPort(); + } } interface Functions { @@ -188,6 +217,11 @@ interface Hosting { * Configuration for the hosting emulator */ GenericDevService devservice(); + + /** + * Path to the hosting files. + */ + Optional hostingPath(); } interface PubSub { @@ -198,6 +232,14 @@ interface PubSub { GenericDevService devservice(); } + interface Storage { + + /** + * Configuration for the storage emulator + */ + GenericDevService devservice(); + } + /** * Internal interface representing a dev service for each of the different emulators part of the Firebase * platform. diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java index a1b9bce1..644dd56b 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java @@ -4,12 +4,8 @@ import java.time.Duration; import java.util.*; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.jboss.logging.Logger; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.images.builder.ImageFromDockerfile; -import org.testcontainers.images.builder.dockerfile.DockerfileBuilder; import io.quarkus.deployment.IsNormal; import io.quarkus.deployment.annotations.BuildStep; @@ -35,6 +31,18 @@ public class FirebaseDevServiceProcessor { // Configuration for the Firebase Dev service private static volatile FirebaseDevServiceConfig config; + private static final Map CONFIG_PROPERTIES = Map.of( + FirebaseEmulatorContainer.Emulators.AUTHENTICATION, "quarkus.google.cloud.firebase.auth.emulator-host", + FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI, "quarkus.google.cloud.firebase.emulator-host", + FirebaseEmulatorContainer.Emulators.FIREBASE_HOSTING, "quarkus.google.cloud.firebase.hosting.emulator-host", + FirebaseEmulatorContainer.Emulators.CLOUD_FUNCTIONS, "quarkus.google.cloud.functions.emulator-host", + FirebaseEmulatorContainer.Emulators.EVENT_ARC, "quarkus.google.cloud.eventarc.emulator-host", + FirebaseEmulatorContainer.Emulators.REALTIME_DATABASE, "quarkus.google.cloud.database.emulator-host", + FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE, "quarkus.google.cloud.firestore.emulator-host", + FirebaseEmulatorContainer.Emulators.CLOUD_STORAGE, "quarkus.google.cloud.storage.host-override", + FirebaseEmulatorContainer.Emulators.PUB_SUB, "quarkus.google.cloud.pubsub.emulator-host" + ); + @BuildStep public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildItem, FirebaseDevServiceConfig firebaseBuildTimeConfig, @@ -98,7 +106,7 @@ private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(D } if (!dockerStatusBuildItem.isContainerRuntimeAvailable()) { - LOGGER.info("Not starting devservice because docker is not available"); + LOGGER.info("Not starting DevService because docker is not available"); return null; } @@ -121,29 +129,86 @@ private Map exposedEmulators( + Map devServices) { + var emulators = devServices + .entrySet() + .stream() + .filter(e -> e.getValue().enabled()) + .map(e -> Map.entry(e.getKey(), portForService(e.getValue()))) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + var uiService = (FirebaseDevServiceConfig.Firebase.DevService.UI) devServices + .get(FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI); + + uiService.hubPort().ifPresent(port -> emulators.put( + FirebaseEmulatorContainer.Emulators.EMULATOR_HUB, + new FirebaseEmulatorContainer.ExposedPort(port)) + ); + + uiService.loggingPort().ifPresent(port -> emulators.put( + FirebaseEmulatorContainer.Emulators.LOGGING, + new FirebaseEmulatorContainer.ExposedPort(port)) + ); + + var firestoreService = (FirebaseDevServiceConfig.Firestore.FirestoreDevService) devServices + .get(FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE); + + firestoreService.websocketPort().ifPresent(port -> + emulators.put( + FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE_WS, + new FirebaseEmulatorContainer.ExposedPort(port)) + ); + + // TODO: Event arc? + + return emulators; + } + + private static FirebaseEmulatorContainer.ExposedPort portForService(FirebaseDevServiceConfig.GenericDevService devService) { + var port = devService.emulatorPort().orElse(null); + return new FirebaseEmulatorContainer.ExposedPort(port); + } + + private FirebaseEmulatorContainer.EmulatorConfig emulatorConfig(FirebaseDevServiceConfig config) { + var devService = config.firebase().devservice(); + + return new FirebaseEmulatorContainer.EmulatorConfig( + devService.imageName(), + devService.firebaseVersion(), + config.projectId(), + devService.token(), + devService.customFirebaseJson().map(File::new).map(File::toPath), + devService.javaToolOptions(), + devService.emulatorData().map(File::new).map(File::toPath), + config.firebase().hosting().hostingPath().map(File::new).map(File::toPath) + ); } /** * Starts the Pub/Sub emulator container with provided configuration. * * @param dockerStatusBuildItem, Docker status - * @param config, Configuration for the PubSub service - * @param timeout, Optional timeout for starting the service + * @param config, Configuration for the Firebase service + * @param timeout, Optional timeout for starting the service * @return Running service item, or null if the service couldn't be started */ private DevServicesResultBuildItem.RunningDevService startContainer(DockerStatusBuildItem dockerStatusBuildItem, - FirebaseDevServiceConfig config, - Optional timeout) { + FirebaseDevServiceConfig config, + Optional timeout) { var devServices = devServices(config); + var emulatorConfig = emulatorConfig(config); // Create and configure Pub/Sub emulator container FirebaseEmulatorContainer emulatorContainer = new FirebaseEmulatorContainer( - config.firebase().devservice(), - devServices, - config.projectId()); + emulatorConfig, + exposedEmulators(devServices)); // Set container startup timeout if provided timeout.ifPresent(emulatorContainer::withStartupTimeout); @@ -152,17 +217,17 @@ private DevServicesResultBuildItem.RunningDevService startContainer(DockerStatus // Set the config for the started container FirebaseDevServiceProcessor.config = config; - var emulatorContainerConfig = emulatorContainer.config(); + var emulatorContainerConfig = emulatorContainerConfig(emulatorContainer); if (LOGGER.isInfoEnabled()) { var runningPorts = emulatorContainer.emulatorPorts(); - runningPorts.forEach((e, p) -> { - LOGGER.info("Google Cloude Emulator " + e + " reachable on port " + p); - }); + runningPorts.forEach((e, p) -> + LOGGER.info("Google Cloud Emulator " + e + " reachable on port " + p) + ); - emulatorContainerConfig.forEach((e, h) -> { - LOGGER.info("Google Cloud emulator config property " + e + " set to " + h); - }); + emulatorContainerConfig.forEach((e, h) -> + LOGGER.info("Google Cloud emulator config property " + e + " set to " + h) + ); } // Return running service item with container details @@ -172,6 +237,23 @@ private DevServicesResultBuildItem.RunningDevService startContainer(DockerStatus emulatorContainerConfig); } + private Map emulatorContainerConfig(FirebaseEmulatorContainer emulatorContainer ) { + return emulatorContainer.emulatorEndpoints() + .entrySet() + .stream() + .filter(e -> CONFIG_PROPERTIES.containsKey(e.getKey())) + .collect( + Collectors.toMap( + e -> configPropertyForEmulator(e.getKey()), + Map.Entry::getValue + ) + ); + } + + private String configPropertyForEmulator(FirebaseEmulatorContainer.Emulators emulator) { + return CONFIG_PROPERTIES.get(emulator); + } + /** * Stops the running Firebase emulator container. */ @@ -188,260 +270,4 @@ private void stopContainer() { } } - public static class FirebaseEmulatorContainer extends GenericContainer { - - public enum Emulators { - AUTHENTICATION( - 9099, - "quarkus.google.cloud.firebase.auth.emulator-host", - "auth"), - EMULATOR_SUITE_UI( - 4000, - "quarkus.google.cloud.firebase.emulator-host", - "ui"), - CLOUD_FUNCTIONS( - 5001, - "quarkus.google.cloud.functions.emulator-host", - "functions"), - EVENT_ARC( - 9299, - "quarkus.google.cloud.eventarc.emulator-host", - "eventarc"), - REALTIME_DATABASE( - 9000, - "quarkus.google.cloud.realtimedb.emulator-host", - "database"), - CLOUD_FIRESTORE( - 8080, - "quarkus.google.cloud.firestore.emulator-host", - "firestore"), - CLOUD_STORAGE( - 9199, - "quarkus.google.cloud.storage.emulator-host", - "storage"), - FIREBASE_HOSTING( - 5000, - "quarkus.google.cloud.firebase.hosting.emulator-host", - "hosting"), - PUB_SUB( - 8085, - "quarkus.google.cloud.pubsub.emulator-host", - "pubsub"); - - final int internalPort; - final String configProperty; - final String emulatorName; - - Emulators(int internalPort, String configProperty, String onlyArgument) { - this.internalPort = internalPort; - this.configProperty = configProperty; - this.emulatorName = onlyArgument; - } - - public String getConfigProperty() { - return configProperty; - } - - public String getEmulatorName() { - return emulatorName; - } - } - - private final Map devServices; - - public FirebaseEmulatorContainer(FirebaseDevServiceConfig.Firebase.DevService firebaseConfig, - Map devServices, - Optional projectId) { - super(new FirebaseDockerBuilder( - firebaseConfig, - devServices, - projectId).build()); - - firebaseConfig.emulatorData().ifPresent(path -> { - // TODO: https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data - // Mount the volume to the specified path - }); - - this.devServices = devServices; - } - - private static class FirebaseDockerBuilder { - - private final ImageFromDockerfile result; - - private final FirebaseDevServiceConfig.Firebase.DevService firebaseConfig; - private final Map devServices; - private final Optional projectId; - - private DockerfileBuilder dockerBuilder; - - public FirebaseDockerBuilder(FirebaseDevServiceConfig.Firebase.DevService firebaseConfig, - Map devServices, - Optional projectId) { - this.projectId = projectId; - this.devServices = devServices; - this.firebaseConfig = firebaseConfig; - - this.result = new ImageFromDockerfile() - .withDockerfileFromBuilder(builder -> { - this.dockerBuilder = builder; - }); - } - - public ImageFromDockerfile build() { - this.validateConfiguration(); - this.configureBaseImage(); - this.installNeededSoftware(); - this.authenticateToFirebase(); - this.setupJavaToolOptions(); - this.addFirebaseJson(); - this.setupDataImportExport(); - this.runExecutable(); - - return result; - } - - private void validateConfiguration() { - if (isEmulatorEnabled(devServices, Emulators.AUTHENTICATION) && projectId.isEmpty()) { - throw new IllegalStateException("Can't create Firebase Auth emulator. Google Project id is required"); - } - - // TODO: Validate if a custom firebase.json is defined, that the hosts are defined as 0.0.0.0 - } - - private void configureBaseImage() { - dockerBuilder.from(firebaseConfig.imageName()); - } - - private void installNeededSoftware() { - dockerBuilder - .run("apk --no-cache add openjdk11-jre bash curl openssl gettext nano nginx sudo") - .run("npm cache clean --force") - .run("npm i -g firebase-tools@" + firebaseConfig.firebaseVersion()); - } - - private void authenticateToFirebase() { - firebaseConfig.token().ifPresent(token -> dockerBuilder.env("FIREBASE_TOKEN", token)); - } - - private void setupJavaToolOptions() { - firebaseConfig.javaToolOptions().ifPresent(toolOptions -> dockerBuilder.env("JAVA_TOOL_OPTIONS", toolOptions)); - } - - private void addFirebaseJson() { - dockerBuilder.workDir("/srv/firebase"); - - firebaseConfig.customFirebaseJson().ifPresentOrElse( - this::includeCustomFirebaseJson, - this::generateFirebaseJson); - - this.dockerBuilder.add("firebase.json", "/srv/firebase/firebase.json"); - } - - private void includeCustomFirebaseJson(String customFilePath) { - this.result.withFileFromPath( - "firebase.json", - new File(customFilePath).toPath()); - } - - private void generateFirebaseJson() { - StringBuilder firebaseJson = new StringBuilder(); - - firebaseJson.append("{\n"); - firebaseJson.append("\t\"emulators\": {\n"); - - var emulatorsJson = this.devServices - .keySet() - .stream() - .filter(e -> isEmulatorEnabled(devServices, e)) - .map((emulator -> "\t\t\"" + emulator.emulatorName + "\": {\n" + - "\t\t\t\"port\": " + emulator.internalPort + ",\n" + - "\t\t\t\"host\": \"0.0.0.0\"\n" + - "\t\t}")) - .collect(Collectors.joining(",\n")); - firebaseJson.append(emulatorsJson).append("\n"); - - firebaseJson.append("\t}\n"); - firebaseJson.append("}\n"); - - this.result.withFileFromString("firebase.json", firebaseJson.toString()); - } - - private void setupDataImportExport() { - firebaseConfig.emulatorData().ifPresent(emulator -> { - this.dockerBuilder.run("mkdir -p /srv/firebase/data"); - this.dockerBuilder.volume("/srv/firebase/data"); - }); - } - - private void runExecutable() { - var projectArgument = projectId - .map(id -> " --project " + id) - .orElse(""); - - var importArgument = firebaseConfig - .emulatorData() - .map(path -> " --import=/srv/firebase/data --export-on-exit") - .orElse(""); - - dockerBuilder - .cmd("firebase emulators:start" + projectArgument + importArgument); - } - } - - /** - * Configures the Pub/Sub emulator container. - */ - @Override - public void configure() { - super.configure(); - - enabledEmulators() - .forEach(emulator -> { - var fixedExposedPort = devServices.get(emulator).emulatorPort(); - // Expose emulatorPort - if (fixedExposedPort.isPresent()) { - addFixedExposedPort(fixedExposedPort.get(), emulator.internalPort); - } else { - addExposedPort(emulator.internalPort); - } - }); - } - - public Map config() { - return enabledEmulators() - .collect(Collectors.toMap( - Emulators::getConfigProperty, - this::getEmulatorEndpoint)); - - } - - public Map emulatorPorts() { - return enabledEmulators() - .collect(Collectors.toMap( - e -> e, - e -> this.getMappedPort(e.internalPort))); - } - - private Stream enabledEmulators() { - return Arrays.stream(Emulators.values()) - .filter(this::isEmulatorEnabled); - } - - private boolean isEmulatorEnabled(Emulators emulator) { - return isEmulatorEnabled(this.devServices, emulator); - } - - private static boolean isEmulatorEnabled(Map devServices, - Emulators emulator) { - return Optional.ofNullable(devServices.get(emulator)) - .map(FirebaseDevServiceConfig.GenericDevService::enabled) - .orElse(false); - } - - private String getEmulatorEndpoint(Emulators emulator) { - return this.getHost() + ":" + this.getMappedPort(emulator.internalPort); - } - } - } diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java new file mode 100644 index 00000000..ed22720d --- /dev/null +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java @@ -0,0 +1,458 @@ +package io.quarkiverse.googlecloudservices.firebase.deployment; + +import org.jboss.logging.Logger; +import org.testcontainers.containers.BindMode; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.images.builder.ImageFromDockerfile; +import org.testcontainers.images.builder.dockerfile.DockerfileBuilder; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * Testcontainers container to run Firebase emulators from Docker. + */ +public class FirebaseEmulatorContainer extends GenericContainer { + + private static final Logger LOGGER = Logger.getLogger(FirebaseEmulatorContainer.class.getName()); + + public static final String FIREBASE_ROOT = "/srv/firebase"; + public static final String FIREBASE_HOSTING_PATH = FIREBASE_ROOT + "/public"; + public static final String EMULATOR_DATA_PATH = FIREBASE_ROOT + "/data"; + + public enum Emulators { + /** + * Firebase Auth emulator + */ + AUTHENTICATION( + 9099, + "auth", + "auth"), + /** + * Emulator UI, not a real emulator, but allows exposing the UI on a predefined port + */ + EMULATOR_SUITE_UI( + 4000, + "ui", + "ui"), + /** + * Emulator Hub API port + */ + EMULATOR_HUB( + 4400, + "hub", + null), + /** + * Emulator UI Logging endpoint + */ + LOGGING( + 4500, + "logging", + null + ), + /** + * CLoud functions emulator + */ + CLOUD_FUNCTIONS( + 5001, + "functions", + "functions"), + /** + * Event Arc emulator + */ + EVENT_ARC( + 9299, + "eventarc", + "eventarc"), + /** + * Realtime database emulator + */ + REALTIME_DATABASE( + 9000, + "database", + "database"), + /** + * Firestore emulator + */ + CLOUD_FIRESTORE( + 8080, + "firestore", + "firestore"), + /** + * Firestore websocket port, This emulator always need to be specified in conjunction with CLOUD_FIRESTORE. + */ + CLOUD_FIRESTORE_WS( + 9150, + null, + null), + /** + * Cloud storage emulator + */ + CLOUD_STORAGE( + 9199, + "storage", + "storage"), + /** + * Firebase hosting emulator + */ + FIREBASE_HOSTING( + 5000, + "hosting", + "hosting"), + /** + * Pub/sub emulator + */ + PUB_SUB( + 8085, + "pubsub", + "pubsub"); + + final int internalPort; + final String configProperty; + final String emulatorName; + + Emulators(int internalPort, String configProperty, String onlyArgument) { + this.internalPort = internalPort; + this.configProperty = configProperty; + this.emulatorName = onlyArgument; + } + + } + + /** + * Record to hold an exposed port of an emulator. + * @param fixedPort The exposed port or null in case it is a random port + */ + public record ExposedPort(Integer fixedPort) { + + public boolean isFixed() { + return fixedPort != null; + } + } + + /** + * Describes the Firebase emulator configuration. + * + * @param imageName The name of the image to use + * @param firebaseVersion The firebase version to use + * @param projectId The project ID, needed when running with the auth emulator + * @param token The Google Cloud CLI token to use for authentication. Needed for firebase hosting + * @param customFirebaseJson The path to a custom firebase + * @param javaToolOptions The options to pass to the java based emulators + * @param emulatorData The path to the directory where to store the emulator data + * @param hostingContentDir The path to the directory containing the hosting content + */ + public record EmulatorConfig( + String imageName, + String firebaseVersion, + Optional projectId, + Optional token, + Optional customFirebaseJson, + Optional javaToolOptions, + Optional emulatorData, + Optional hostingContentDir + ) {} + + private final Map services; + + /** + * Creates a new Firebase Emulator container + * @param firebaseConfig The generic configuration of the firebase emulators + * @param services The various firebase services which are exposed. + */ + public FirebaseEmulatorContainer(EmulatorConfig firebaseConfig, + Map services) { + super(new FirebaseDockerBuilder( + firebaseConfig, + services).build()); + + firebaseConfig.emulatorData().ifPresent(path -> { + // https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data + // Mount the volume to the specified path + this.withFileSystemBind(path.toString(), EMULATOR_DATA_PATH, BindMode.READ_WRITE); + }); + + firebaseConfig.hostingContentDir().ifPresent(hostingPath -> { + // Mount volume for static hosting content + this.withFileSystemBind(hostingPath.toString(), FIREBASE_HOSTING_PATH, BindMode.READ_ONLY); + }); + + this.services = services; + } + + private static class FirebaseDockerBuilder { + + private final ImageFromDockerfile result; + + private final EmulatorConfig firebaseConfig; + private final Map devServices; + + private DockerfileBuilder dockerBuilder; + + public FirebaseDockerBuilder(EmulatorConfig firebaseConfig, + Map devServices) { + this.devServices = devServices; + this.firebaseConfig = firebaseConfig; + + this.result = new ImageFromDockerfile("localhost/testcontainers/firebase", false) + .withDockerfileFromBuilder(builder -> this.dockerBuilder = builder); + } + + public ImageFromDockerfile build() { + this.validateConfiguration(); + this.configureBaseImage(); + this.installNeededSoftware(); + this.downloadEmulators(); + this.authenticateToFirebase(); + this.setupJavaToolOptions(); + this.addFirebaseJson(); + this.setupDataImportExport(); + this.setupHosting(); + this.runExecutable(); + + return result; + } + + private void validateConfiguration() { + if (isEmulatorEnabled(Emulators.AUTHENTICATION) && firebaseConfig.projectId().isEmpty()) { + throw new IllegalStateException("Can't create Firebase Auth emulator. Google Project id is required"); + } + + if (isEmulatorEnabled(Emulators.CLOUD_FIRESTORE) && isEmulatorEnabled(Emulators.EMULATOR_SUITE_UI)) { + if (!isEmulatorEnabled(Emulators.CLOUD_FIRESTORE_WS)) { + throw new IllegalStateException("The Cloud Firestore WebSocket port needs to be configured "); + } + } + + if (isEmulatorEnabled(Emulators.EMULATOR_SUITE_UI)) { + if (!isEmulatorEnabled(Emulators.EMULATOR_HUB)) { + LOGGER.info("Firebase Emulator UI is enabled, but no Hub port is specified. You will not be able to use the Hub API "); + } + + if (!isEmulatorEnabled(Emulators.LOGGING)) { + LOGGER.info("Firebase Emulator UI is enabled, but no Logging port is specified. You will not be able to see the logging "); + } + + if (isEmulatorEnabled(Emulators.CLOUD_FIRESTORE)) { + if (!isEmulatorEnabled(Emulators.CLOUD_FIRESTORE_WS)) { + LOGGER.warn("Firebase Firestore Emulator and Emulator UI are enabled but no Firestore Websocket " + + "port is specified. You will not be able to use the Firestore UI"); + } + } + } + + // TODO: Validate if a custom firebase.json is defined, that the hosts are defined as 0.0.0.0 + } + + private void configureBaseImage() { + dockerBuilder.from(firebaseConfig.imageName()); + } + + private void installNeededSoftware() { + dockerBuilder + .run("apk --no-cache add openjdk11-jre bash curl openssl gettext nano nginx sudo") + .run("npm cache clean --force") + .run("npm i -g firebase-tools@" + firebaseConfig.firebaseVersion()); + } + + private void downloadEmulators() { + downloadEmulator(Emulators.REALTIME_DATABASE, "database"); + downloadEmulator(Emulators.CLOUD_FIRESTORE, "firestore"); + downloadEmulator(Emulators.PUB_SUB, "pubsub"); + downloadEmulator(Emulators.CLOUD_STORAGE, "storage"); + downloadEmulator(Emulators.EMULATOR_SUITE_UI, "ui"); + } + + private void downloadEmulator(Emulators emulator, String downloadId) { + if (isEmulatorEnabled(emulator)) { + dockerBuilder.run("firebase setup:emulators:" + downloadId); + } + } + + private void authenticateToFirebase() { + firebaseConfig.token().ifPresent(token -> dockerBuilder.env("FIREBASE_TOKEN", token)); + } + + private void setupJavaToolOptions() { + firebaseConfig.javaToolOptions().ifPresent(toolOptions -> dockerBuilder.env("JAVA_TOOL_OPTIONS", toolOptions)); + } + + private void addFirebaseJson() { + dockerBuilder.workDir(FIREBASE_ROOT); + + firebaseConfig.customFirebaseJson().ifPresentOrElse( + this::includeCustomFirebaseJson, + this::generateFirebaseJson); + + this.dockerBuilder.add("firebase.json", FIREBASE_ROOT + "/firebase.json"); + } + + private void includeCustomFirebaseJson(Path customFilePath) { + this.result.withFileFromPath( + "firebase.json", + customFilePath); + } + + private void generateFirebaseJson() { + StringBuilder firebaseJson = new StringBuilder(); + + firebaseJson.append("{\n"); + firebaseJson.append("\t\"emulators\": {\n"); + + var emulatorsJson = this.devServices + .entrySet() + .stream() + .filter(service -> service.getKey().configProperty != null) + .map((service -> { + var emulator = service.getKey(); + + var port = Optional.ofNullable(service.getValue().fixedPort()) + .orElse(emulator.internalPort); + + String additionalConfig = ""; + if (emulator.equals(Emulators.CLOUD_FIRESTORE)) { + var wsService = this.devServices.get(Emulators.CLOUD_FIRESTORE_WS); + if (wsService != null) { + var wsPort = Optional.ofNullable(wsService.fixedPort).orElse(Emulators.CLOUD_FIRESTORE.internalPort); + additionalConfig = "\t\t\t\"websocketPort\": " + wsPort + ",\n"; + } + } + + return "\t\t\"" + emulator.configProperty + "\": {\n" + + "\t\t\t\"port\": " + port + ",\n" + + additionalConfig + + "\t\t\t\"host\": \"0.0.0.0\"\n" + + "\t\t}"; + })) + .collect(Collectors.joining(",\n")); + firebaseJson.append(emulatorsJson).append("\n"); + firebaseJson.append("\t}\n"); + + if (isEmulatorEnabled(Emulators.CLOUD_FIRESTORE)) { + var firestoreJson = ",\"firestore\": {}\n"; + firebaseJson.append(firestoreJson); + } + + firebaseJson.append("}\n"); + + this.result.withFileFromString("firebase.json", firebaseJson.toString()); + } + + private void setupDataImportExport() { + firebaseConfig.emulatorData().ifPresent(emulator -> { + this.dockerBuilder.run("mkdir -p " + EMULATOR_DATA_PATH); + this.dockerBuilder.volume(EMULATOR_DATA_PATH); + }); + } + + private void setupHosting() { + // Specify public directory if hosting is enabled + if (firebaseConfig.hostingContentDir().isPresent()) { + dockerBuilder.run("mkdir -p " + FIREBASE_HOSTING_PATH); + } + } + + private void runExecutable() { + List arguments = new ArrayList<>(); + + arguments.add("emulators:start"); + + firebaseConfig.projectId() + .map(id -> "--project") + .ifPresent(arguments::add); + + firebaseConfig.projectId() + .ifPresent(arguments::add); + + firebaseConfig + .emulatorData() + .map(path -> "--import") + .ifPresent(arguments::add); + + firebaseConfig + .emulatorData() + .map(path -> EMULATOR_DATA_PATH) + .ifPresent(arguments::add); + + firebaseConfig + .emulatorData() + .map(path -> "--export-on-exit") + .ifPresent(arguments::add); + + dockerBuilder.entryPoint(new String[] {"/usr/local/bin/firebase"}); + dockerBuilder.cmd(arguments.toArray(new String[0])); + } + + private boolean isEmulatorEnabled(Emulators emulator) { + return this.devServices.containsKey(emulator); + } + } + + @Override + public void stop() { + /* + * We override the way test containers stops the container. By default, test containers will send a + * kill (SIGKILL) command instead of a stop (SIGTERM) command. This will kill the container instantly + * and prevent firebase from writing the "--export-on-exit" data to the mounted directory. + */ + this.getDockerClient().stopContainerCmd(this.getContainerId()).exec(); + + super.stop(); + } + + /** + * Configures the Pub/Sub emulator container. + */ + @Override + public void configure() { + super.configure(); + + services.keySet() + .forEach(emulator -> { + var exposedPort = services.get(emulator); + // Expose emulatorPort + if (exposedPort.isFixed()) { + addFixedExposedPort(exposedPort.fixedPort(), exposedPort.fixedPort()); + } else { + addExposedPort(emulator.internalPort); + } + }); + + waitingFor(Wait.forLogMessage(".*Emulator Hub running at.*", 1)); + } + + public Map emulatorEndpoints() { + return services.keySet() + .stream() + .collect(Collectors.toMap( + e -> e, + this::getEmulatorEndpoint + )); + } + + public Integer emulatorPort(Emulators emulator) { + var exposedPort = services.get(emulator); + if (exposedPort.isFixed()) { + return exposedPort.fixedPort(); + } else { + return getMappedPort(emulator.internalPort); + } + } + + public Map emulatorPorts() { + return services.keySet() + .stream() + .collect(Collectors.toMap( + e -> e, + this::emulatorPort)); + } + + private String getEmulatorEndpoint(Emulators emulator) { + return this.getHost() + ":" + emulatorPort(emulator); + } +} diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java new file mode 100644 index 00000000..66367586 --- /dev/null +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -0,0 +1,362 @@ +package io.quarkiverse.googlecloudservices.firebase.deployment; + +import com.google.api.core.ApiFuture; +import com.google.api.gax.core.NoCredentialsProvider; +import com.google.api.gax.grpc.GrpcTransportChannel; +import com.google.api.gax.rpc.FixedTransportChannelProvider; +import com.google.cloud.NoCredentials; +import com.google.cloud.firestore.*; +import com.google.cloud.pubsub.v1.TopicAdminClient; +import com.google.cloud.pubsub.v1.TopicAdminSettings; +import com.google.cloud.storage.*; +import com.google.cloud.storage.Blob; +import com.google.firebase.auth.FirebaseAuthException; +import com.google.firebase.database.*; +import com.google.firebase.internal.EmulatorCredentials; +import com.google.firebase.internal.FirebaseProcessEnvironment; +import com.google.protobuf.ByteString; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.EmulatorConfig; +import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.Emulators; +import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.ExposedPort; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.UserRecord; +import com.google.cloud.pubsub.v1.Publisher; +import com.google.pubsub.v1.PubsubMessage; + +import static org.junit.jupiter.api.Assertions.*; + +@Testcontainers +public class FirebaseEmulatorContainerIntegrationTest { + + @Container + private static final FirebaseEmulatorContainer firebaseContainer; + private static final File tempEmulatorDataDir; + private static final File tempHostingContentDir; + + private static final String emulatorHost; + private static final FirebaseApp app; + + private static final Map SERVICES = Map.of( + Emulators.AUTHENTICATION, new ExposedPort(6000), + Emulators.REALTIME_DATABASE, new ExposedPort(6001), + Emulators.CLOUD_FIRESTORE, new ExposedPort(6002), + Emulators.CLOUD_FIRESTORE_WS, new ExposedPort(6003), + Emulators.PUB_SUB, new ExposedPort(6004), + Emulators.CLOUD_STORAGE, new ExposedPort(6005), +// Emulators.FIREBASE_HOSTING, new ExposedPort(6006), +// Emulators.CLOUD_FUNCTIONS, new ExposedPort(6007), +// Emulators.EVENT_ARC, new ExposedPort(6008), + Emulators.EMULATOR_SUITE_UI, new ExposedPort(6009), + Emulators.EMULATOR_HUB, new ExposedPort(6010), + Emulators.LOGGING, new ExposedPort(6011) + ); + + static { + try { + // Create a temporary directory for emulator data + tempEmulatorDataDir = Files.createTempDirectory("firebase-emulator-data").toFile(); + tempHostingContentDir = Files.createTempDirectory("firebase-hosting-content").toFile(); + + // Create a static HTML file in the hosting directory + File indexFile = new File(tempHostingContentDir, "index.html"); + try (FileWriter writer = new FileWriter(indexFile)) { + writer.write("

Hello, Firebase Hosting!

"); + } + + EmulatorConfig config = new EmulatorConfig( + "node:23-alpine", // Default image + "latest", // Firebase version + Optional.of("demo-test-project"), + Optional.empty(), + Optional.empty(), + Optional.empty(), + Optional.of(tempEmulatorDataDir.toPath()), + Optional.of(tempHostingContentDir.toPath()) + ); + + firebaseContainer = new FirebaseEmulatorContainer(config, SERVICES); + firebaseContainer.start(); + + emulatorHost = firebaseContainer.getHost(); + + int dbPort = firebaseContainer.emulatorPort(Emulators.REALTIME_DATABASE); + + var firebaseBuilder = FirebaseOptions.builder() + .setProjectId("demo-test-project") + .setCredentials(new EmulatorCredentials()) + .setDatabaseUrl("http://" + emulatorHost + ":" + dbPort + "?ns=demo-test-project"); + + FirebaseOptions options = firebaseBuilder.build(); + app = FirebaseApp.initializeApp(options); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + @AfterAll + public static void tearDown() { + if (firebaseContainer != null) { + firebaseContainer.stop(); + } + + validateEmulatorDataWritten(); + + // Recursively delete the contents of the directories and then delete the directories + deleteDirectoryRecursively(tempEmulatorDataDir); + deleteDirectoryRecursively(tempHostingContentDir); + } + + // Helper method to recursively delete all files and directories + private static void deleteDirectoryRecursively(File directory) { + if (directory.exists()) { + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + deleteDirectoryRecursively(file); + } else { + assertTrue(file.delete()); + } + } + } + assertTrue(directory.delete()); + } + } + + private static void validateEmulatorDataWritten() { + // Verify that files were written to the emulator data directory + File[] files = tempEmulatorDataDir.listFiles(); + assertNotNull(files); + assertTrue(files.length > 0, "Expected files to be present in the emulator data directory"); + } + + @Test + @Disabled + public void testFirebaseHostingEmulatorConnection() throws Exception { + // Validate that the static HTML file is accessible via HTTP + int hostingPort = firebaseContainer.emulatorPort(Emulators.FIREBASE_HOSTING); + + // Construct URL for the hosted file + URL url = new URL("http://" + emulatorHost + ":" + hostingPort + "/index.html"); + + // Fetch content from the URL + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + int responseCode = connection.getResponseCode(); + + assertEquals(200, responseCode, "Expected HTTP status 200 for index.html"); + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + String line = reader.readLine(); + assertTrue(line.contains("Hello, Firebase Hosting!"), "Expected content in index.html"); + } + } + + @Test + public void testFirebaseAuthenticationEmulatorConnection() throws FirebaseAuthException { + // Retrieve the host and port for the Authentication emulator + int authPort = firebaseContainer.emulatorPort(Emulators.AUTHENTICATION); + + // Set the environment variable for the Firebase Authentication emulator + FirebaseProcessEnvironment.setenv("FIREBASE_AUTH_EMULATOR_HOST", emulatorHost + ":" + authPort); + + // Initialize FirebaseOptions without setting the auth emulator host directly + FirebaseAuth auth = FirebaseAuth.getInstance(app); + + // Create a test user and verify it + UserRecord.CreateRequest request = new UserRecord.CreateRequest() + .setEmail("user@example.com") + .setPassword("password"); + UserRecord userRecord = auth.createUser(request); + + assertNotNull(userRecord); + assertEquals("user@example.com", userRecord.getEmail()); + + // Clean up by deleting the test user + auth.deleteUser(userRecord.getUid()); + } + + @Test + public void testFirestoreEmulatorConnection() throws ExecutionException, InterruptedException { + int firestorePort = firebaseContainer.emulatorPort(Emulators.CLOUD_FIRESTORE); + + FirestoreOptions options = FirestoreOptions.newBuilder() + .setProjectId("demo-test-project") + .setEmulatorHost(emulatorHost + ":" + firestorePort) + .setCredentials(new EmulatorCredentials()) + .build(); + Firestore firestore = options.getService(); + + DocumentReference docRef = firestore.collection("testCollection").document("testDoc"); + ApiFuture result = docRef.set(Map.of("field", "value")); + + assertNotNull(result.get()); + DocumentSnapshot snapshot = docRef.get().get(); + assertEquals("value", snapshot.getString("field")); + } + + @Test + public void testRealtimeDatabaseEmulatorConnection() throws ExecutionException, InterruptedException { + DatabaseReference ref = FirebaseDatabase.getInstance(app).getReference("testData"); + + // Write data to the database + ref.setValueAsync("testValue").get(); + + // Set up a listener and latch for asynchronous reading + CountDownLatch latch = new CountDownLatch(1); + final String[] value = {null}; + + ref.addListenerForSingleValueEvent(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot snapshot) { + value[0] = snapshot.getValue(String.class); + latch.countDown(); + } + + @Override + public void onCancelled(DatabaseError error) { + latch.countDown(); + } + }); + + // Wait for the listener to retrieve data + assertTrue(latch.await(5, TimeUnit.SECONDS)); + assertEquals("testValue", value[0], "Expected to retrieve 'testValue' from Realtime Database"); + } + + @Test + public void testPubSubEmulatorConnection() throws Exception { + // Retrieve the host and port for the Pub/Sub emulator + int pubSubPort = firebaseContainer.emulatorPort(Emulators.PUB_SUB); + + // Set up a gRPC channel to the Pub/Sub emulator + ManagedChannel channel = ManagedChannelBuilder.forAddress(emulatorHost, pubSubPort) + .usePlaintext() + .build(); + + // Set the channel provider for Pub/Sub client + FixedTransportChannelProvider channelProvider = FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel)); + + TopicAdminSettings topicAdminSettings = TopicAdminSettings.newBuilder() + .setCredentialsProvider(new NoCredentialsProvider()) + .setTransportChannelProvider(channelProvider) + .build(); + + try (TopicAdminClient topicAdminClient = TopicAdminClient.create(topicAdminSettings)) { + topicAdminClient.createTopic("projects/demo-test-project/topics/testTopic"); + } + + // Create a publisher with the channel provider + Publisher publisher = Publisher.newBuilder("projects/demo-test-project/topics/testTopic") + .setChannelProvider(channelProvider) + .setCredentialsProvider(new NoCredentialsProvider()) + .build(); + + // Publish a message to the Pub/Sub emulator + PubsubMessage message = PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8("Test message")).build(); + ApiFuture messageIdFuture = publisher.publish(message); + assertNotNull(messageIdFuture.get(), "Expected message to be published successfully"); + + // Shutdown the channel + channel.shutdownNow(); + } + + @Test + @Disabled + public void testStorageEmulatorConnection() { + int storagePort = firebaseContainer.emulatorPort(Emulators.CLOUD_STORAGE); + + Storage storage = StorageOptions.newBuilder() + .setHost("http://" + emulatorHost + ":" + storagePort) + .setProjectId("demo-test-project") + .setCredentials(NoCredentials.getInstance()) + .build().getService(); + + var bucketName = "quarkus-hello"; + + Bucket bucket = storage.get(bucketName); + if (bucket == null) { + bucket = storage.create(BucketInfo.newBuilder(bucketName).build()); + } + bucket.create("hello.txt", "{\"success\": true}".getBytes(StandardCharsets.UTF_8)); + + BlobInfo blobInfo = BlobInfo.newBuilder(bucketName, "test-upload").build(); + storage.create(blobInfo, "test".getBytes()); + + // Verify the content of the uploaded file + Blob blob = bucket.get("hello.txt"); + assertEquals("{\"success\": true}", new String(blob.getContent()), "Expected blob content to match"); + } + + @Test + public void testEmulatorUIReachable() throws Exception { + // Get the host and port for the Emulator UI + int uiPort = firebaseContainer.emulatorPort(Emulators.EMULATOR_SUITE_UI); + + // Construct the URL for the Emulator UI root (where index.html would be served) + URL url = new URL("http://" + emulatorHost + ":" + uiPort + "/"); + + // Open a connection and send an HTTP GET request + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + // Get the response code to confirm the UI is reachable + int responseCode = connection.getResponseCode(); + assertEquals(200, responseCode, "Expected HTTP status 200 for Emulator UI index.html"); + + // Close the connection + connection.disconnect(); + } + + @Test + public void testEmulatorHub() throws Exception { + // Get the host and port for the Emulator UI + int uiPort = firebaseContainer.emulatorPort(Emulators.EMULATOR_HUB); + + // Construct the URL for the Emulator UI root (where index.html would be served) + URL url = new URL("http://" + emulatorHost + ":" + uiPort + "/emulators"); + + // Open a connection and send an HTTP GET request + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + // Get the response code to confirm the UI is reachable + int responseCode = connection.getResponseCode(); + assertEquals(200, responseCode, "Expected HTTP status 200 for Emulator Hub API"); + + // Close the connection + connection.disconnect(); + } + + /* + CLOUD_FUNCTIONS( + 5001, + "quarkus.google.cloud.functions.emulator-host", + "functions"), + EVENT_ARC( + 9299, + "quarkus.google.cloud.eventarc.emulator-host", + "eventarc"), + */ +} From 771e9a7930a7401b1719e9cbed9470167664b095 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Wed, 13 Nov 2024 22:10:57 +0100 Subject: [PATCH 016/101] Documentation fixes, using the generated configuration table. --- docs/modules/ROOT/pages/firebase.adoc | 59 +++++-------------- .../deployment/FirebaseDevServiceConfig.java | 15 +++-- 2 files changed, 24 insertions(+), 50 deletions(-) diff --git a/docs/modules/ROOT/pages/firebase.adoc b/docs/modules/ROOT/pages/firebase.adoc index ede16284..ff736604 100644 --- a/docs/modules/ROOT/pages/firebase.adoc +++ b/docs/modules/ROOT/pages/firebase.adoc @@ -7,19 +7,25 @@ Be sure to have read the https://quarkiverse.github.io/quarkiverse-docs/quarkus- == Current status The following emulators have been verified to work: + * Firebase Auth * Firebase Firestore * Firebase Emulator UI +* Realtime Database +* PubSub +* Cloud Storage The following emulators need additional work: + * Firebase Hosting -* Realtime Database * Functions -* PubSub The following emulators are currently not supported: * EventArc -* Cloud Storage + +Currently you can specify a custom `firebase.json` file but suport for this is limited. A +future version will support reading the configuration from the `firebase.json` file +instead of from the Quarkus configuration. == Bootstrapping the project @@ -53,47 +59,6 @@ This will add the following to your pom.xml:
---- -== Configuration - -* `quarkus.google.cloud.project-id` - The project ID is mandatory for projects using Firebase Auth (Firebase Admin). -* `quarkus.google.cloud.firebase.devservice.image-name` - The base image name to use (see Custom Docker images below) -* `quarkus.google.cloud.firebase.devservice.firebase-version` - The version of the firebase tools to use. Default is to use the latest available version. -* `quarkus.google.cloud.firebase.devservice.token` - The firebase token to use. This is mandatory when using Hosting. This token can be generated using the firebase CLI. -* `quarkus.google.cloud.firebase.devservice.custom-firebase-json` - The path to a custom `firebase.json` file to use instead of the auto generated one (see Custom Firebase.json) -* `quarkus.google.cloud.firebase.devservice.java-tool-options` - Java tool options to pass to the Java based emulators (like -Xmx) -* `quarkus.google.cloud.firebase.devservice.emulator-data` - Path to a directory where to import and export (on exit) the emulator data. -* `quarkus.google.cloud.firebase.devservice.ui.enabled` - Whether to enable the Emulator UI. The default is true. - -*Firebase auth emulator* - -* `quarkus.google.cloud.firebase.auth.devservice.enabled` - Enable the Firebase Auth emulator. The default is false. -* `quarkus.google.cloud.firebase.auth.devservice.emulatorPort` - The port on which to expose the emulator from the Docker container. The default is to expose the service on a random port. - -*Hosting emulator* - -* `quarkus.google.cloud.firebase.hosting.devservice.enabled` - Enable the Hosting emulator. The default is false. -* `quarkus.google.cloud.firebase.hosting.devservice.emulatorPort` - The port on which to expose the emulator from the Docker container. The default is to expose the service on a random port. - -*Realtime database emulator* - -* `quarkus.google.cloud.database.devservice.enabled` - Enable the Realtime database emulator. The default is false. -* `quarkus.google.cloud.database.devservice.emulatorPort` - The port on which to expose the emulator from the Docker container. The default is to expose the service on a random port. - -*Firestore emulator* - -* `quarkus.google.cloud.firestore.devservice.enabled` - Enable the Firestore emulator. The default is false. -* `quarkus.google.cloud.firestore.devservice.emulatorPort` - The port on which to expose the emulator from the Docker container. The default is to expose the service on a random port. - -*Functions emulator* - -* `quarkus.google.cloud.functions.devservice.enabled` - Enable the Firestore emulator. The default is false. -* `quarkus.google.cloud.functions.devservice.emulatorPort` - The port on which to expose the emulator from the Docker container. The default is to expose the service on a random port. - -*PubSub emulator* - -* `quarkus.google.cloud.pubsub.devservice.enabled` - Enable the Firestore emulator. The default is false. -* `quarkus.google.cloud.pubsub.devservice.emulatorPort` - The port on which to expose the emulator from the Docker container. The default is to expose the service on a random port. - == Custom Docker image To run the emulators, a custom Docker image is build on the fly to run the Firebase emulators. This image is based on a NodeJS based image (refer to the configuration of the default value of `quarkus.google.cloud.firebase.devservice.image-name` to see the base image). @@ -126,4 +91,8 @@ The following extensions support a DevService which conflicts with the DevServic * PubSub * TODO: Verify Storage -When including this module, these DevServices will automatically be disabled, as the Firebase emulator should feature wise be on-par or more extensive than the individual emulators. \ No newline at end of file +When including this module, these DevServices will automatically be disabled, as the Firebase emulator should feature wise be on-par or more extensive than the individual emulators. + +== Configuration Reference + +include::./includes/quarkus-google-cloud-firebase.adoc[] \ No newline at end of file diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index cf28deb1..2105e28f 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -91,12 +91,14 @@ interface DevService { * Sets the Docker image name for the Google Cloud SDK. * This image is used to emulate the Pub/Sub service in the development environment. * The default value is 'gcr.io/google.com/cloudsdktool/google-cloud-cli'. + *

+ * See also the documentation on Custom Docker images for more info about this image. */ @WithDefault("node:23-alpine") String imageName(); /** - * Sets the firebase version to use. Defaults to the latest version. + * The version of the firebase tools to use. Default is to use the latest available version. */ @WithDefault("latest") String firebaseVersion(); @@ -117,11 +119,13 @@ interface DevService { * * to ensure the ports of the * emulator are exposed correctly at the docker container level. + *

+ * See the section on Custom Firebase Json in the docs for more info. */ Optional customFirebaseJson(); /** - * Sets the JAVA tool options for emulators based on the Java runtime environment. + * Sets the JAVA tool options for emulators based on the Java runtime environment like -Xmx. * See also * here */ @@ -130,7 +134,7 @@ interface DevService { /** * Allow to import and export data. Specify a path relative to the current working directory of the executable * (for most unit tests, this is the root of the build directory) to be used for import and export of emulator - * data. + * data. The data will be written to a subdirectory called "emulator-data" of this directory. * See also here */ @@ -247,14 +251,15 @@ interface Storage { interface GenericDevService { /** - * Indicates whether the service should be enabled or not. + * Indicates whether the DevService should be enabled or not. * The default value is 'false'. */ @WithDefault("false") boolean enabled(); /** - * Specifies the emulatorPort on which the service should run in the development environment. + * Specifies the emulatorPort on which the service should run in the development environment. The default + * is to expose the service on a random port. */ Optional emulatorPort(); } From d039a2d74c927fe87b7469ee554498b4e4e25c9f Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Wed, 13 Nov 2024 22:11:31 +0100 Subject: [PATCH 017/101] Fix writing the emulator data on exit --- .../firebase/deployment/FirebaseEmulatorContainer.java | 6 +++++- .../FirebaseEmulatorContainerIntegrationTest.java | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java index ed22720d..493e0ee4 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java @@ -374,9 +374,13 @@ private void runExecutable() { .map(path -> "--import") .ifPresent(arguments::add); + /* + * We write the data to a subdirectory of the mount point. The firebase emulator tries to remove and + * recreate the mount-point directory, which will obviously fail. By using a subdirectory, export succeeds. + */ firebaseConfig .emulatorData() - .map(path -> EMULATOR_DATA_PATH) + .map(path -> EMULATOR_DATA_PATH + "/emulator-data") .ifPresent(arguments::add); firebaseConfig diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index 66367586..45e03442 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -49,7 +49,6 @@ @Testcontainers public class FirebaseEmulatorContainerIntegrationTest { - @Container private static final FirebaseEmulatorContainer firebaseContainer; private static final File tempEmulatorDataDir; private static final File tempHostingContentDir; @@ -145,8 +144,10 @@ private static void deleteDirectoryRecursively(File directory) { } private static void validateEmulatorDataWritten() { + var emulatorDataDir = new File(tempEmulatorDataDir, "emulator-data"); + // Verify that files were written to the emulator data directory - File[] files = tempEmulatorDataDir.listFiles(); + File[] files = emulatorDataDir.listFiles(); assertNotNull(files); assertTrue(files.length > 0, "Expected files to be present in the emulator data directory"); } From 36a6ccc9751d6a4a02c0b2c00604e1224fcbdb58 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Wed, 13 Nov 2024 23:07:58 +0100 Subject: [PATCH 018/101] Split the logic to build the FirebaseEmulatorContainer configuration based on the Quarkus configuration into a separate class Moved the exposed ports to be part of the container configuration. --- .../FirebaseDevServiceProcessor.java | 77 +------ .../FirebaseEmulatorConfigBuilder.java | 89 ++++++++ .../deployment/FirebaseEmulatorContainer.java | 18 +- .../FirebaseEmulatorConfigBuilderTest.java | 197 ++++++++++++++++++ ...ebaseEmulatorContainerIntegrationTest.java | 5 +- 5 files changed, 299 insertions(+), 87 deletions(-) create mode 100644 firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java create mode 100644 firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java index 644dd56b..e6b8fef8 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java @@ -1,6 +1,5 @@ package io.quarkiverse.googlecloudservices.firebase.deployment; -import java.io.File; import java.time.Duration; import java.util.*; import java.util.stream.Collectors; @@ -114,81 +113,14 @@ private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(D } private boolean isEnabled(FirebaseDevServiceConfig config) { - return devServices(config) + return FirebaseEmulatorConfigBuilder.devServices(config) .values() .stream() .map(FirebaseDevServiceConfig.GenericDevService::enabled) .reduce(Boolean.FALSE, Boolean::logicalOr); } - private Map devServices( - FirebaseDevServiceConfig config) { - return Map.of( - FirebaseEmulatorContainer.Emulators.AUTHENTICATION, config.firebase().auth().devservice(), - FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI, config.firebase().devservice().ui(), - FirebaseEmulatorContainer.Emulators.REALTIME_DATABASE, config.database().devservice(), - FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE, config.firestore().devservice(), - FirebaseEmulatorContainer.Emulators.CLOUD_FUNCTIONS, config.functions().devservice(), - FirebaseEmulatorContainer.Emulators.CLOUD_STORAGE, config.storage().devservice(), - FirebaseEmulatorContainer.Emulators.FIREBASE_HOSTING, config.firebase().hosting().devservice(), - FirebaseEmulatorContainer.Emulators.PUB_SUB, config.pubsub().devservice()); - } - - private Map exposedEmulators( - Map devServices) { - var emulators = devServices - .entrySet() - .stream() - .filter(e -> e.getValue().enabled()) - .map(e -> Map.entry(e.getKey(), portForService(e.getValue()))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - - var uiService = (FirebaseDevServiceConfig.Firebase.DevService.UI) devServices - .get(FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI); - - uiService.hubPort().ifPresent(port -> emulators.put( - FirebaseEmulatorContainer.Emulators.EMULATOR_HUB, - new FirebaseEmulatorContainer.ExposedPort(port)) - ); - - uiService.loggingPort().ifPresent(port -> emulators.put( - FirebaseEmulatorContainer.Emulators.LOGGING, - new FirebaseEmulatorContainer.ExposedPort(port)) - ); - - var firestoreService = (FirebaseDevServiceConfig.Firestore.FirestoreDevService) devServices - .get(FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE); - firestoreService.websocketPort().ifPresent(port -> - emulators.put( - FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE_WS, - new FirebaseEmulatorContainer.ExposedPort(port)) - ); - - // TODO: Event arc? - - return emulators; - } - - private static FirebaseEmulatorContainer.ExposedPort portForService(FirebaseDevServiceConfig.GenericDevService devService) { - var port = devService.emulatorPort().orElse(null); - return new FirebaseEmulatorContainer.ExposedPort(port); - } - - private FirebaseEmulatorContainer.EmulatorConfig emulatorConfig(FirebaseDevServiceConfig config) { - var devService = config.firebase().devservice(); - - return new FirebaseEmulatorContainer.EmulatorConfig( - devService.imageName(), - devService.firebaseVersion(), - config.projectId(), - devService.token(), - devService.customFirebaseJson().map(File::new).map(File::toPath), - devService.javaToolOptions(), - devService.emulatorData().map(File::new).map(File::toPath), - config.firebase().hosting().hostingPath().map(File::new).map(File::toPath) - ); - } /** * Starts the Pub/Sub emulator container with provided configuration. @@ -202,13 +134,10 @@ private DevServicesResultBuildItem.RunningDevService startContainer(DockerStatus FirebaseDevServiceConfig config, Optional timeout) { - var devServices = devServices(config); - var emulatorConfig = emulatorConfig(config); + var emulatorConfig = new FirebaseEmulatorConfigBuilder(config).build(); // Create and configure Pub/Sub emulator container - FirebaseEmulatorContainer emulatorContainer = new FirebaseEmulatorContainer( - emulatorConfig, - exposedEmulators(devServices)); + FirebaseEmulatorContainer emulatorContainer = new FirebaseEmulatorContainer(emulatorConfig); // Set container startup timeout if provided timeout.ifPresent(emulatorContainer::withStartupTimeout); diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java new file mode 100644 index 00000000..ada656c8 --- /dev/null +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java @@ -0,0 +1,89 @@ +package io.quarkiverse.googlecloudservices.firebase.deployment; + +import java.io.File; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * This class translates the Quarkus Firebase extension configuration to the {@link FirebaseEmulatorContainer} + * configuration. + */ +public class FirebaseEmulatorConfigBuilder { + + private final FirebaseDevServiceConfig config; + + public FirebaseEmulatorConfigBuilder(FirebaseDevServiceConfig config) { + this.config = config; + } + + public FirebaseEmulatorContainer.EmulatorConfig build() { + var devService = config.firebase().devservice(); + + return new FirebaseEmulatorContainer.EmulatorConfig( + devService.imageName(), + devService.firebaseVersion(), + config.projectId(), + devService.token(), + devService.customFirebaseJson().map(File::new).map(File::toPath), + devService.javaToolOptions(), + devService.emulatorData().map(File::new).map(File::toPath), + config.firebase().hosting().hostingPath().map(File::new).map(File::toPath), + exposedEmulators(devServices(config)) + ); + } + + public static Map devServices(FirebaseDevServiceConfig config) { + return Map.of( + FirebaseEmulatorContainer.Emulators.AUTHENTICATION, config.firebase().auth().devservice(), + FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI, config.firebase().devservice().ui(), + FirebaseEmulatorContainer.Emulators.REALTIME_DATABASE, config.database().devservice(), + FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE, config.firestore().devservice(), + FirebaseEmulatorContainer.Emulators.CLOUD_FUNCTIONS, config.functions().devservice(), + FirebaseEmulatorContainer.Emulators.CLOUD_STORAGE, config.storage().devservice(), + FirebaseEmulatorContainer.Emulators.FIREBASE_HOSTING, config.firebase().hosting().devservice(), + FirebaseEmulatorContainer.Emulators.PUB_SUB, config.pubsub().devservice()); + } + + private Map exposedEmulators( + Map devServices) { + var emulators = devServices + .entrySet() + .stream() + .filter(e -> e.getValue().enabled()) + .map(e -> Map.entry(e.getKey(), portForService(e.getValue()))) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + var uiService = (FirebaseDevServiceConfig.Firebase.DevService.UI) devServices + .get(FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI); + + uiService.hubPort().ifPresent(port -> emulators.put( + FirebaseEmulatorContainer.Emulators.EMULATOR_HUB, + new FirebaseEmulatorContainer.ExposedPort(port)) + ); + + uiService.loggingPort().ifPresent(port -> emulators.put( + FirebaseEmulatorContainer.Emulators.LOGGING, + new FirebaseEmulatorContainer.ExposedPort(port)) + ); + + var firestoreService = (FirebaseDevServiceConfig.Firestore.FirestoreDevService) devServices + .get(FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE); + + firestoreService.websocketPort().ifPresent(port -> + emulators.put( + FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE_WS, + new FirebaseEmulatorContainer.ExposedPort(port)) + ); + + // TODO: Event arc? + + return emulators; + } + + private static FirebaseEmulatorContainer.ExposedPort portForService(FirebaseDevServiceConfig.GenericDevService devService) { + var port = devService.emulatorPort().orElse(null); + return new FirebaseEmulatorContainer.ExposedPort(port); + } + + +} diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java index 493e0ee4..07260147 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java @@ -155,7 +155,8 @@ public record EmulatorConfig( Optional customFirebaseJson, Optional javaToolOptions, Optional emulatorData, - Optional hostingContentDir + Optional hostingContentDir, + Map services ) {} private final Map services; @@ -163,13 +164,9 @@ public record EmulatorConfig( /** * Creates a new Firebase Emulator container * @param firebaseConfig The generic configuration of the firebase emulators - * @param services The various firebase services which are exposed. */ - public FirebaseEmulatorContainer(EmulatorConfig firebaseConfig, - Map services) { - super(new FirebaseDockerBuilder( - firebaseConfig, - services).build()); + public FirebaseEmulatorContainer(EmulatorConfig firebaseConfig) { + super(new FirebaseDockerBuilder(firebaseConfig).build()); firebaseConfig.emulatorData().ifPresent(path -> { // https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data @@ -182,7 +179,7 @@ public FirebaseEmulatorContainer(EmulatorConfig firebaseConfig, this.withFileSystemBind(hostingPath.toString(), FIREBASE_HOSTING_PATH, BindMode.READ_ONLY); }); - this.services = services; + this.services = firebaseConfig.services; } private static class FirebaseDockerBuilder { @@ -194,9 +191,8 @@ private static class FirebaseDockerBuilder { private DockerfileBuilder dockerBuilder; - public FirebaseDockerBuilder(EmulatorConfig firebaseConfig, - Map devServices) { - this.devServices = devServices; + public FirebaseDockerBuilder(EmulatorConfig firebaseConfig) { + this.devServices = firebaseConfig.services; this.firebaseConfig = firebaseConfig; this.result = new ImageFromDockerfile("localhost/testcontainers/firebase", false) diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java new file mode 100644 index 00000000..bf8afabe --- /dev/null +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java @@ -0,0 +1,197 @@ +package io.quarkiverse.googlecloudservices.firebase.deployment; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.nio.file.Path; +import java.util.Map; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +class FirebaseEmulatorConfigBuilderTest { + + private FirebaseEmulatorConfigBuilder configBuilder; + + @BeforeEach + void setUp() { + // Storage + FirebaseDevServiceConfig config = new TestFirebaseDevServiceConfig( + Optional.of("my-project-id"), + new TestFirebase( + new TestFirebaseDevService( + true, + "node:21-alpine", + "11.0.0", + Optional.of("MY_TOKEN"), + Optional.of("firebase.json"), + Optional.of("-Xmx"), + Optional.of("data"), + new TestUI( + true, + Optional.of(6000), + Optional.of(6001), + Optional.of(6002) + ) + ), + new TestAuth( + new TestGenericDevService(true, Optional.of(6003)) + ), + new TestHosting( + new TestGenericDevService(true, Optional.of(6004)), + Optional.of("public") + ) + ), + new TestDatabase( + new TestGenericDevService( + false, + Optional.of(6005) + ) + ), + new TestFirestore( + new TestFirestoreDevService( + true, + Optional.of(6006), + Optional.of(6007) + ) + ), + new TestFunctions( + new TestGenericDevService( + true, + Optional.of(6008) + ) + ), + new TestPubSub( + new TestGenericDevService( + true, + Optional.of(6009) + ) + ), + new TestStorage( + new TestGenericDevService( + true, + Optional.empty() + ) // Storage + ) + ); + configBuilder = new FirebaseEmulatorConfigBuilder(config); + } + + @Test + void testBuild() { + FirebaseEmulatorContainer.EmulatorConfig emulatorConfig = configBuilder.build(); + + assertNotNull(emulatorConfig); + assertEquals("node:21-alpine", emulatorConfig.imageName()); + assertEquals("11.0.0", emulatorConfig.firebaseVersion()); + assertEquals("my-project-id", emulatorConfig.projectId().orElse(null)); + assertEquals("MY_TOKEN", emulatorConfig.token().orElse(null)); + assertPathEndsWith("firebase.json", emulatorConfig.customFirebaseJson().orElse(null)); + assertEquals("-Xmx", emulatorConfig.javaToolOptions().orElse(null)); + assertPathEndsWith("data", emulatorConfig.emulatorData().orElse(null)); + assertPathEndsWith("public", emulatorConfig.hostingContentDir().orElse(null)); + } + + private void assertPathEndsWith(String expected, Path path) { + assertNotNull(path); + assertTrue(path.toString().endsWith(expected)); + } + + @Test + void testExposedEmulators() { + FirebaseEmulatorContainer.EmulatorConfig emulatorConfig = configBuilder.build(); + + Map exposedPorts = + emulatorConfig.services(); + + assertEquals(10, exposedPorts.size()); + assertEquals(6000, exposedPorts.get(FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI).fixedPort()); + assertEquals(6001, exposedPorts.get(FirebaseEmulatorContainer.Emulators.LOGGING).fixedPort()); + assertEquals(6002, exposedPorts.get(FirebaseEmulatorContainer.Emulators.EMULATOR_HUB).fixedPort()); + assertEquals(6003, exposedPorts.get(FirebaseEmulatorContainer.Emulators.AUTHENTICATION).fixedPort()); + assertEquals(6004, exposedPorts.get(FirebaseEmulatorContainer.Emulators.FIREBASE_HOSTING).fixedPort()); + assertEquals(6006, exposedPorts.get(FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE).fixedPort()); + assertEquals(6007, exposedPorts.get(FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE_WS).fixedPort()); + assertEquals(6008, exposedPorts.get(FirebaseEmulatorContainer.Emulators.CLOUD_FUNCTIONS).fixedPort()); + assertEquals(6009, exposedPorts.get(FirebaseEmulatorContainer.Emulators.PUB_SUB).fixedPort()); + assertNull(exposedPorts.get(FirebaseEmulatorContainer.Emulators.CLOUD_STORAGE).fixedPort()); + + assertNull(exposedPorts.get(FirebaseEmulatorContainer.Emulators.REALTIME_DATABASE)); + } + + // Record implementations for interfaces + record TestFirebaseDevServiceConfig( + Optional projectId, + Firebase firebase, + Database database, + Firestore firestore, + Functions functions, + PubSub pubsub, + Storage storage + ) implements FirebaseDevServiceConfig { } + + record TestFirebase( + DevService devservice, + FirebaseDevServiceConfig.Auth auth, + FirebaseDevServiceConfig.Hosting hosting + ) implements FirebaseDevServiceConfig.Firebase {} + + record TestFirebaseDevService( + boolean preferFirebaseDevServices, + String imageName, + String firebaseVersion, + Optional token, + Optional customFirebaseJson, + Optional javaToolOptions, + Optional emulatorData, + UI ui + ) implements FirebaseDevServiceConfig.Firebase.DevService {} + + record TestUI( + boolean enabled, + Optional emulatorPort, + Optional loggingPort, + Optional hubPort + ) implements FirebaseDevServiceConfig.Firebase.DevService.UI {} + + record TestAuth( + FirebaseDevServiceConfig.GenericDevService devservice + ) implements FirebaseDevServiceConfig.Auth {} + + record TestDatabase( + FirebaseDevServiceConfig.GenericDevService devservice + ) implements FirebaseDevServiceConfig.Database {} + + record TestFirestore( + FirestoreDevService devservice + ) implements FirebaseDevServiceConfig.Firestore {} + + record TestFirestoreDevService( + boolean enabled, + Optional emulatorPort, + Optional websocketPort + ) implements FirebaseDevServiceConfig.Firestore.FirestoreDevService {} + + record TestFunctions( + FirebaseDevServiceConfig.GenericDevService devservice + ) implements FirebaseDevServiceConfig.Functions {} + + record TestHosting( + FirebaseDevServiceConfig.GenericDevService devservice, + Optional hostingPath + ) implements FirebaseDevServiceConfig.Hosting {} + + record TestPubSub( + FirebaseDevServiceConfig.GenericDevService devservice + ) implements FirebaseDevServiceConfig.PubSub {} + + record TestStorage( + FirebaseDevServiceConfig.GenericDevService devservice + ) implements FirebaseDevServiceConfig.Storage {} + + record TestGenericDevService( + boolean enabled, + Optional emulatorPort + ) implements FirebaseDevServiceConfig.GenericDevService {} + +} diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index 45e03442..d4f258a6 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -91,10 +91,11 @@ Emulators.LOGGING, new ExposedPort(6011) Optional.empty(), Optional.empty(), Optional.of(tempEmulatorDataDir.toPath()), - Optional.of(tempHostingContentDir.toPath()) + Optional.of(tempHostingContentDir.toPath()), + SERVICES ); - firebaseContainer = new FirebaseEmulatorContainer(config, SERVICES); + firebaseContainer = new FirebaseEmulatorContainer(config); firebaseContainer.start(); emulatorHost = firebaseContainer.getHost(); From a0f1b483732d2dd49f02f3c7ed3bbc7bee66a34d Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Wed, 13 Nov 2024 23:16:49 +0100 Subject: [PATCH 019/101] Removed obsolete check --- .../firebase/deployment/FirebaseEmulatorContainer.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java index 07260147..22e47fff 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java @@ -219,12 +219,6 @@ private void validateConfiguration() { throw new IllegalStateException("Can't create Firebase Auth emulator. Google Project id is required"); } - if (isEmulatorEnabled(Emulators.CLOUD_FIRESTORE) && isEmulatorEnabled(Emulators.EMULATOR_SUITE_UI)) { - if (!isEmulatorEnabled(Emulators.CLOUD_FIRESTORE_WS)) { - throw new IllegalStateException("The Cloud Firestore WebSocket port needs to be configured "); - } - } - if (isEmulatorEnabled(Emulators.EMULATOR_SUITE_UI)) { if (!isEmulatorEnabled(Emulators.EMULATOR_HUB)) { LOGGER.info("Firebase Emulator UI is enabled, but no Hub port is specified. You will not be able to use the Hub API "); From 9a48b15f08cb10320d1393a168e35f7f84e198f7 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Wed, 13 Nov 2024 23:29:38 +0100 Subject: [PATCH 020/101] Formatting changes --- .../deployment/FirebaseDevServiceConfig.java | 2 +- .../FirebaseDevServiceProcessor.java | 44 ++++----- .../FirebaseEmulatorConfigBuilder.java | 21 ++-- .../deployment/FirebaseEmulatorContainer.java | 37 ++++---- .../FirebaseEmulatorConfigBuilderTest.java | 95 ++++++++----------- ...ebaseEmulatorContainerIntegrationTest.java | 85 ++++++++--------- 6 files changed, 129 insertions(+), 155 deletions(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index 2105e28f..85acf702 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -98,7 +98,7 @@ interface DevService { String imageName(); /** - * The version of the firebase tools to use. Default is to use the latest available version. + * The version of the firebase tools to use. Default is to use the latest available version. */ @WithDefault("latest") String firebaseVersion(); diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java index e6b8fef8..6f81f382 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java @@ -31,16 +31,15 @@ public class FirebaseDevServiceProcessor { private static volatile FirebaseDevServiceConfig config; private static final Map CONFIG_PROPERTIES = Map.of( - FirebaseEmulatorContainer.Emulators.AUTHENTICATION, "quarkus.google.cloud.firebase.auth.emulator-host", - FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI, "quarkus.google.cloud.firebase.emulator-host", - FirebaseEmulatorContainer.Emulators.FIREBASE_HOSTING, "quarkus.google.cloud.firebase.hosting.emulator-host", - FirebaseEmulatorContainer.Emulators.CLOUD_FUNCTIONS, "quarkus.google.cloud.functions.emulator-host", - FirebaseEmulatorContainer.Emulators.EVENT_ARC, "quarkus.google.cloud.eventarc.emulator-host", - FirebaseEmulatorContainer.Emulators.REALTIME_DATABASE, "quarkus.google.cloud.database.emulator-host", - FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE, "quarkus.google.cloud.firestore.emulator-host", - FirebaseEmulatorContainer.Emulators.CLOUD_STORAGE, "quarkus.google.cloud.storage.host-override", - FirebaseEmulatorContainer.Emulators.PUB_SUB, "quarkus.google.cloud.pubsub.emulator-host" - ); + FirebaseEmulatorContainer.Emulators.AUTHENTICATION, "quarkus.google.cloud.firebase.auth.emulator-host", + FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI, "quarkus.google.cloud.firebase.emulator-host", + FirebaseEmulatorContainer.Emulators.FIREBASE_HOSTING, "quarkus.google.cloud.firebase.hosting.emulator-host", + FirebaseEmulatorContainer.Emulators.CLOUD_FUNCTIONS, "quarkus.google.cloud.functions.emulator-host", + FirebaseEmulatorContainer.Emulators.EVENT_ARC, "quarkus.google.cloud.eventarc.emulator-host", + FirebaseEmulatorContainer.Emulators.REALTIME_DATABASE, "quarkus.google.cloud.database.emulator-host", + FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE, "quarkus.google.cloud.firestore.emulator-host", + FirebaseEmulatorContainer.Emulators.CLOUD_STORAGE, "quarkus.google.cloud.storage.host-override", + FirebaseEmulatorContainer.Emulators.PUB_SUB, "quarkus.google.cloud.pubsub.emulator-host"); @BuildStep public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildItem, @@ -120,19 +119,17 @@ private boolean isEnabled(FirebaseDevServiceConfig config) { .reduce(Boolean.FALSE, Boolean::logicalOr); } - - /** * Starts the Pub/Sub emulator container with provided configuration. * * @param dockerStatusBuildItem, Docker status - * @param config, Configuration for the Firebase service - * @param timeout, Optional timeout for starting the service + * @param config, Configuration for the Firebase service + * @param timeout, Optional timeout for starting the service * @return Running service item, or null if the service couldn't be started */ private DevServicesResultBuildItem.RunningDevService startContainer(DockerStatusBuildItem dockerStatusBuildItem, - FirebaseDevServiceConfig config, - Optional timeout) { + FirebaseDevServiceConfig config, + Optional timeout) { var emulatorConfig = new FirebaseEmulatorConfigBuilder(config).build(); @@ -150,13 +147,10 @@ private DevServicesResultBuildItem.RunningDevService startContainer(DockerStatus if (LOGGER.isInfoEnabled()) { var runningPorts = emulatorContainer.emulatorPorts(); - runningPorts.forEach((e, p) -> - LOGGER.info("Google Cloud Emulator " + e + " reachable on port " + p) - ); + runningPorts.forEach((e, p) -> LOGGER.info("Google Cloud Emulator " + e + " reachable on port " + p)); - emulatorContainerConfig.forEach((e, h) -> - LOGGER.info("Google Cloud emulator config property " + e + " set to " + h) - ); + emulatorContainerConfig + .forEach((e, h) -> LOGGER.info("Google Cloud emulator config property " + e + " set to " + h)); } // Return running service item with container details @@ -166,7 +160,7 @@ private DevServicesResultBuildItem.RunningDevService startContainer(DockerStatus emulatorContainerConfig); } - private Map emulatorContainerConfig(FirebaseEmulatorContainer emulatorContainer ) { + private Map emulatorContainerConfig(FirebaseEmulatorContainer emulatorContainer) { return emulatorContainer.emulatorEndpoints() .entrySet() .stream() @@ -174,9 +168,7 @@ private Map emulatorContainerConfig(FirebaseEmulatorContainer em .collect( Collectors.toMap( e -> configPropertyForEmulator(e.getKey()), - Map.Entry::getValue - ) - ); + Map.Entry::getValue)); } private String configPropertyForEmulator(FirebaseEmulatorContainer.Emulators emulator) { diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java index ada656c8..f95df4f9 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java @@ -28,11 +28,11 @@ public FirebaseEmulatorContainer.EmulatorConfig build() { devService.javaToolOptions(), devService.emulatorData().map(File::new).map(File::toPath), config.firebase().hosting().hostingPath().map(File::new).map(File::toPath), - exposedEmulators(devServices(config)) - ); + exposedEmulators(devServices(config))); } - public static Map devServices(FirebaseDevServiceConfig config) { + public static Map devServices( + FirebaseDevServiceConfig config) { return Map.of( FirebaseEmulatorContainer.Emulators.AUTHENTICATION, config.firebase().auth().devservice(), FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI, config.firebase().devservice().ui(), @@ -58,22 +58,18 @@ private Map emulators.put( FirebaseEmulatorContainer.Emulators.EMULATOR_HUB, - new FirebaseEmulatorContainer.ExposedPort(port)) - ); + new FirebaseEmulatorContainer.ExposedPort(port))); uiService.loggingPort().ifPresent(port -> emulators.put( FirebaseEmulatorContainer.Emulators.LOGGING, - new FirebaseEmulatorContainer.ExposedPort(port)) - ); + new FirebaseEmulatorContainer.ExposedPort(port))); var firestoreService = (FirebaseDevServiceConfig.Firestore.FirestoreDevService) devServices .get(FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE); - firestoreService.websocketPort().ifPresent(port -> - emulators.put( - FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE_WS, - new FirebaseEmulatorContainer.ExposedPort(port)) - ); + firestoreService.websocketPort().ifPresent(port -> emulators.put( + FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE_WS, + new FirebaseEmulatorContainer.ExposedPort(port))); // TODO: Event arc? @@ -85,5 +81,4 @@ private static FirebaseEmulatorContainer.ExposedPort portForService(FirebaseDevS return new FirebaseEmulatorContainer.ExposedPort(port); } - } diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java index 22e47fff..037e7616 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java @@ -1,12 +1,5 @@ package io.quarkiverse.googlecloudservices.firebase.deployment; -import org.jboss.logging.Logger; -import org.testcontainers.containers.BindMode; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; -import org.testcontainers.images.builder.dockerfile.DockerfileBuilder; - import java.nio.file.Path; import java.util.ArrayList; import java.util.List; @@ -14,6 +7,13 @@ import java.util.Optional; import java.util.stream.Collectors; +import org.jboss.logging.Logger; +import org.testcontainers.containers.BindMode; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.images.builder.ImageFromDockerfile; +import org.testcontainers.images.builder.dockerfile.DockerfileBuilder; + /** * Testcontainers container to run Firebase emulators from Docker. */ @@ -53,8 +53,7 @@ public enum Emulators { LOGGING( 4500, "logging", - null - ), + null), /** * CLoud functions emulator */ @@ -126,6 +125,7 @@ public enum Emulators { /** * Record to hold an exposed port of an emulator. + * * @param fixedPort The exposed port or null in case it is a random port */ public record ExposedPort(Integer fixedPort) { @@ -156,13 +156,14 @@ public record EmulatorConfig( Optional javaToolOptions, Optional emulatorData, Optional hostingContentDir, - Map services - ) {} + Map services) { + } private final Map services; /** * Creates a new Firebase Emulator container + * * @param firebaseConfig The generic configuration of the firebase emulators */ public FirebaseEmulatorContainer(EmulatorConfig firebaseConfig) { @@ -221,11 +222,13 @@ private void validateConfiguration() { if (isEmulatorEnabled(Emulators.EMULATOR_SUITE_UI)) { if (!isEmulatorEnabled(Emulators.EMULATOR_HUB)) { - LOGGER.info("Firebase Emulator UI is enabled, but no Hub port is specified. You will not be able to use the Hub API "); + LOGGER.info( + "Firebase Emulator UI is enabled, but no Hub port is specified. You will not be able to use the Hub API "); } if (!isEmulatorEnabled(Emulators.LOGGING)) { - LOGGER.info("Firebase Emulator UI is enabled, but no Logging port is specified. You will not be able to see the logging "); + LOGGER.info( + "Firebase Emulator UI is enabled, but no Logging port is specified. You will not be able to see the logging "); } if (isEmulatorEnabled(Emulators.CLOUD_FIRESTORE)) { @@ -308,7 +311,8 @@ private void generateFirebaseJson() { if (emulator.equals(Emulators.CLOUD_FIRESTORE)) { var wsService = this.devServices.get(Emulators.CLOUD_FIRESTORE_WS); if (wsService != null) { - var wsPort = Optional.ofNullable(wsService.fixedPort).orElse(Emulators.CLOUD_FIRESTORE.internalPort); + var wsPort = Optional.ofNullable(wsService.fixedPort) + .orElse(Emulators.CLOUD_FIRESTORE.internalPort); additionalConfig = "\t\t\t\"websocketPort\": " + wsPort + ",\n"; } } @@ -378,7 +382,7 @@ private void runExecutable() { .map(path -> "--export-on-exit") .ifPresent(arguments::add); - dockerBuilder.entryPoint(new String[] {"/usr/local/bin/firebase"}); + dockerBuilder.entryPoint(new String[] { "/usr/local/bin/firebase" }); dockerBuilder.cmd(arguments.toArray(new String[0])); } @@ -425,8 +429,7 @@ public Map emulatorEndpoints() { .stream() .collect(Collectors.toMap( e -> e, - this::getEmulatorEndpoint - )); + this::getEmulatorEndpoint)); } public Integer emulatorPort(Emulators emulator) { diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java index bf8afabe..b5c5add9 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java @@ -1,13 +1,13 @@ package io.quarkiverse.googlecloudservices.firebase.deployment; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; import java.nio.file.Path; import java.util.Map; import java.util.Optional; -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; class FirebaseEmulatorConfigBuilderTest { @@ -31,49 +31,34 @@ void setUp() { true, Optional.of(6000), Optional.of(6001), - Optional.of(6002) - ) - ), + Optional.of(6002))), new TestAuth( - new TestGenericDevService(true, Optional.of(6003)) - ), + new TestGenericDevService(true, Optional.of(6003))), new TestHosting( new TestGenericDevService(true, Optional.of(6004)), - Optional.of("public") - ) - ), + Optional.of("public"))), new TestDatabase( new TestGenericDevService( false, - Optional.of(6005) - ) - ), + Optional.of(6005))), new TestFirestore( new TestFirestoreDevService( true, Optional.of(6006), - Optional.of(6007) - ) - ), + Optional.of(6007))), new TestFunctions( new TestGenericDevService( true, - Optional.of(6008) - ) - ), + Optional.of(6008))), new TestPubSub( new TestGenericDevService( true, - Optional.of(6009) - ) - ), + Optional.of(6009))), new TestStorage( new TestGenericDevService( true, - Optional.empty() - ) // Storage - ) - ); + Optional.empty()) // Storage + )); configBuilder = new FirebaseEmulatorConfigBuilder(config); } @@ -101,8 +86,8 @@ private void assertPathEndsWith(String expected, Path path) { void testExposedEmulators() { FirebaseEmulatorContainer.EmulatorConfig emulatorConfig = configBuilder.build(); - Map exposedPorts = - emulatorConfig.services(); + Map exposedPorts = emulatorConfig + .services(); assertEquals(10, exposedPorts.size()); assertEquals(6000, exposedPorts.get(FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI).fixedPort()); @@ -127,14 +112,14 @@ record TestFirebaseDevServiceConfig( Firestore firestore, Functions functions, PubSub pubsub, - Storage storage - ) implements FirebaseDevServiceConfig { } + Storage storage) implements FirebaseDevServiceConfig { + } record TestFirebase( DevService devservice, FirebaseDevServiceConfig.Auth auth, - FirebaseDevServiceConfig.Hosting hosting - ) implements FirebaseDevServiceConfig.Firebase {} + FirebaseDevServiceConfig.Hosting hosting) implements FirebaseDevServiceConfig.Firebase { + } record TestFirebaseDevService( boolean preferFirebaseDevServices, @@ -144,54 +129,54 @@ record TestFirebaseDevService( Optional customFirebaseJson, Optional javaToolOptions, Optional emulatorData, - UI ui - ) implements FirebaseDevServiceConfig.Firebase.DevService {} + UI ui) implements FirebaseDevServiceConfig.Firebase.DevService { + } record TestUI( boolean enabled, Optional emulatorPort, Optional loggingPort, - Optional hubPort - ) implements FirebaseDevServiceConfig.Firebase.DevService.UI {} + Optional hubPort) implements FirebaseDevServiceConfig.Firebase.DevService.UI { + } record TestAuth( - FirebaseDevServiceConfig.GenericDevService devservice - ) implements FirebaseDevServiceConfig.Auth {} + FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.Auth { + } record TestDatabase( - FirebaseDevServiceConfig.GenericDevService devservice - ) implements FirebaseDevServiceConfig.Database {} + FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.Database { + } record TestFirestore( - FirestoreDevService devservice - ) implements FirebaseDevServiceConfig.Firestore {} + FirestoreDevService devservice) implements FirebaseDevServiceConfig.Firestore { + } record TestFirestoreDevService( boolean enabled, Optional emulatorPort, - Optional websocketPort - ) implements FirebaseDevServiceConfig.Firestore.FirestoreDevService {} + Optional websocketPort) implements FirebaseDevServiceConfig.Firestore.FirestoreDevService { + } record TestFunctions( - FirebaseDevServiceConfig.GenericDevService devservice - ) implements FirebaseDevServiceConfig.Functions {} + FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.Functions { + } record TestHosting( FirebaseDevServiceConfig.GenericDevService devservice, - Optional hostingPath - ) implements FirebaseDevServiceConfig.Hosting {} + Optional hostingPath) implements FirebaseDevServiceConfig.Hosting { + } record TestPubSub( - FirebaseDevServiceConfig.GenericDevService devservice - ) implements FirebaseDevServiceConfig.PubSub {} + FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.PubSub { + } record TestStorage( - FirebaseDevServiceConfig.GenericDevService devservice - ) implements FirebaseDevServiceConfig.Storage {} + FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.Storage { + } record TestGenericDevService( boolean enabled, - Optional emulatorPort - ) implements FirebaseDevServiceConfig.GenericDevService {} + Optional emulatorPort) implements FirebaseDevServiceConfig.GenericDevService { + } } diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index d4f258a6..40e46955 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -1,50 +1,50 @@ package io.quarkiverse.googlecloudservices.firebase.deployment; +import static org.junit.jupiter.api.Assertions.*; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.testcontainers.junit.jupiter.Testcontainers; + import com.google.api.core.ApiFuture; import com.google.api.gax.core.NoCredentialsProvider; import com.google.api.gax.grpc.GrpcTransportChannel; import com.google.api.gax.rpc.FixedTransportChannelProvider; import com.google.cloud.NoCredentials; import com.google.cloud.firestore.*; +import com.google.cloud.pubsub.v1.Publisher; import com.google.cloud.pubsub.v1.TopicAdminClient; import com.google.cloud.pubsub.v1.TopicAdminSettings; import com.google.cloud.storage.*; import com.google.cloud.storage.Blob; +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseAuthException; +import com.google.firebase.auth.UserRecord; import com.google.firebase.database.*; import com.google.firebase.internal.EmulatorCredentials; import com.google.firebase.internal.FirebaseProcessEnvironment; import com.google.protobuf.ByteString; +import com.google.pubsub.v1.PubsubMessage; + import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.EmulatorConfig; import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.Emulators; import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.ExposedPort; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -import java.io.*; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -import com.google.firebase.FirebaseApp; -import com.google.firebase.FirebaseOptions; -import com.google.firebase.auth.FirebaseAuth; -import com.google.firebase.auth.UserRecord; -import com.google.cloud.pubsub.v1.Publisher; -import com.google.pubsub.v1.PubsubMessage; - -import static org.junit.jupiter.api.Assertions.*; @Testcontainers public class FirebaseEmulatorContainerIntegrationTest { @@ -63,13 +63,12 @@ Emulators.CLOUD_FIRESTORE, new ExposedPort(6002), Emulators.CLOUD_FIRESTORE_WS, new ExposedPort(6003), Emulators.PUB_SUB, new ExposedPort(6004), Emulators.CLOUD_STORAGE, new ExposedPort(6005), -// Emulators.FIREBASE_HOSTING, new ExposedPort(6006), -// Emulators.CLOUD_FUNCTIONS, new ExposedPort(6007), -// Emulators.EVENT_ARC, new ExposedPort(6008), + // Emulators.FIREBASE_HOSTING, new ExposedPort(6006), + // Emulators.CLOUD_FUNCTIONS, new ExposedPort(6007), + // Emulators.EVENT_ARC, new ExposedPort(6008), Emulators.EMULATOR_SUITE_UI, new ExposedPort(6009), Emulators.EMULATOR_HUB, new ExposedPort(6010), - Emulators.LOGGING, new ExposedPort(6011) - ); + Emulators.LOGGING, new ExposedPort(6011)); static { try { @@ -85,15 +84,14 @@ Emulators.LOGGING, new ExposedPort(6011) EmulatorConfig config = new EmulatorConfig( "node:23-alpine", // Default image - "latest", // Firebase version + "latest", // Firebase version Optional.of("demo-test-project"), Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(tempEmulatorDataDir.toPath()), Optional.of(tempHostingContentDir.toPath()), - SERVICES - ); + SERVICES); firebaseContainer = new FirebaseEmulatorContainer(config); firebaseContainer.start(); @@ -227,7 +225,7 @@ public void testRealtimeDatabaseEmulatorConnection() throws ExecutionException, // Set up a listener and latch for asynchronous reading CountDownLatch latch = new CountDownLatch(1); - final String[] value = {null}; + final String[] value = { null }; ref.addListenerForSingleValueEvent(new ValueEventListener() { @Override @@ -258,7 +256,8 @@ public void testPubSubEmulatorConnection() throws Exception { .build(); // Set the channel provider for Pub/Sub client - FixedTransportChannelProvider channelProvider = FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel)); + FixedTransportChannelProvider channelProvider = FixedTransportChannelProvider + .create(GrpcTransportChannel.create(channel)); TopicAdminSettings topicAdminSettings = TopicAdminSettings.newBuilder() .setCredentialsProvider(new NoCredentialsProvider()) @@ -352,13 +351,13 @@ public void testEmulatorHub() throws Exception { } /* - CLOUD_FUNCTIONS( - 5001, - "quarkus.google.cloud.functions.emulator-host", - "functions"), - EVENT_ARC( - 9299, - "quarkus.google.cloud.eventarc.emulator-host", - "eventarc"), + * CLOUD_FUNCTIONS( + * 5001, + * "quarkus.google.cloud.functions.emulator-host", + * "functions"), + * EVENT_ARC( + * 9299, + * "quarkus.google.cloud.eventarc.emulator-host", + * "eventarc"), */ } From 5084b9f7f1a8c07b7e2cddd70ec682237d8777dd Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Wed, 13 Nov 2024 23:34:39 +0100 Subject: [PATCH 021/101] Fix property for firestore --- .../firebase/deployment/FirebaseDevServiceProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java index 6f81f382..fe2e86c2 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java @@ -37,7 +37,7 @@ public class FirebaseDevServiceProcessor { FirebaseEmulatorContainer.Emulators.CLOUD_FUNCTIONS, "quarkus.google.cloud.functions.emulator-host", FirebaseEmulatorContainer.Emulators.EVENT_ARC, "quarkus.google.cloud.eventarc.emulator-host", FirebaseEmulatorContainer.Emulators.REALTIME_DATABASE, "quarkus.google.cloud.database.emulator-host", - FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE, "quarkus.google.cloud.firestore.emulator-host", + FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE, "quarkus.google.cloud.firestore.host-override", FirebaseEmulatorContainer.Emulators.CLOUD_STORAGE, "quarkus.google.cloud.storage.host-override", FirebaseEmulatorContainer.Emulators.PUB_SUB, "quarkus.google.cloud.pubsub.emulator-host"); From 535d1fac775a2a49dfd038f1c3cc5882b29d5a7c Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 18:10:18 +0100 Subject: [PATCH 022/101] Renamed enum name Sending container output to STDOUT/STDERR for debugging of container behaviour. --- .../FirebaseDevServiceProcessor.java | 22 ++++---- .../FirebaseEmulatorConfigBuilder.java | 32 +++++------ .../deployment/FirebaseEmulatorContainer.java | 55 ++++++++++--------- .../FirebaseEmulatorConfigBuilderTest.java | 26 ++++----- ...ebaseEmulatorContainerIntegrationTest.java | 42 +++++++------- 5 files changed, 92 insertions(+), 85 deletions(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java index fe2e86c2..e30d4ba9 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java @@ -30,16 +30,16 @@ public class FirebaseDevServiceProcessor { // Configuration for the Firebase Dev service private static volatile FirebaseDevServiceConfig config; - private static final Map CONFIG_PROPERTIES = Map.of( - FirebaseEmulatorContainer.Emulators.AUTHENTICATION, "quarkus.google.cloud.firebase.auth.emulator-host", - FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI, "quarkus.google.cloud.firebase.emulator-host", - FirebaseEmulatorContainer.Emulators.FIREBASE_HOSTING, "quarkus.google.cloud.firebase.hosting.emulator-host", - FirebaseEmulatorContainer.Emulators.CLOUD_FUNCTIONS, "quarkus.google.cloud.functions.emulator-host", - FirebaseEmulatorContainer.Emulators.EVENT_ARC, "quarkus.google.cloud.eventarc.emulator-host", - FirebaseEmulatorContainer.Emulators.REALTIME_DATABASE, "quarkus.google.cloud.database.emulator-host", - FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE, "quarkus.google.cloud.firestore.host-override", - FirebaseEmulatorContainer.Emulators.CLOUD_STORAGE, "quarkus.google.cloud.storage.host-override", - FirebaseEmulatorContainer.Emulators.PUB_SUB, "quarkus.google.cloud.pubsub.emulator-host"); + private static final Map CONFIG_PROPERTIES = Map.of( + FirebaseEmulatorContainer.Emulator.AUTHENTICATION, "quarkus.google.cloud.firebase.auth.emulator-host", + FirebaseEmulatorContainer.Emulator.EMULATOR_SUITE_UI, "quarkus.google.cloud.firebase.emulator-host", + FirebaseEmulatorContainer.Emulator.FIREBASE_HOSTING, "quarkus.google.cloud.firebase.hosting.emulator-host", + FirebaseEmulatorContainer.Emulator.CLOUD_FUNCTIONS, "quarkus.google.cloud.functions.emulator-host", + FirebaseEmulatorContainer.Emulator.EVENT_ARC, "quarkus.google.cloud.eventarc.emulator-host", + FirebaseEmulatorContainer.Emulator.REALTIME_DATABASE, "quarkus.google.cloud.database.emulator-host", + FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE, "quarkus.google.cloud.firestore.host-override", + FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE, "quarkus.google.cloud.storage.host-override", + FirebaseEmulatorContainer.Emulator.PUB_SUB, "quarkus.google.cloud.pubsub.emulator-host"); @BuildStep public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildItem, @@ -171,7 +171,7 @@ private Map emulatorContainerConfig(FirebaseEmulatorContainer em Map.Entry::getValue)); } - private String configPropertyForEmulator(FirebaseEmulatorContainer.Emulators emulator) { + private String configPropertyForEmulator(FirebaseEmulatorContainer.Emulator emulator) { return CONFIG_PROPERTIES.get(emulator); } diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java index f95df4f9..4e801e67 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java @@ -31,21 +31,21 @@ public FirebaseEmulatorContainer.EmulatorConfig build() { exposedEmulators(devServices(config))); } - public static Map devServices( + public static Map devServices( FirebaseDevServiceConfig config) { return Map.of( - FirebaseEmulatorContainer.Emulators.AUTHENTICATION, config.firebase().auth().devservice(), - FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI, config.firebase().devservice().ui(), - FirebaseEmulatorContainer.Emulators.REALTIME_DATABASE, config.database().devservice(), - FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE, config.firestore().devservice(), - FirebaseEmulatorContainer.Emulators.CLOUD_FUNCTIONS, config.functions().devservice(), - FirebaseEmulatorContainer.Emulators.CLOUD_STORAGE, config.storage().devservice(), - FirebaseEmulatorContainer.Emulators.FIREBASE_HOSTING, config.firebase().hosting().devservice(), - FirebaseEmulatorContainer.Emulators.PUB_SUB, config.pubsub().devservice()); + FirebaseEmulatorContainer.Emulator.AUTHENTICATION, config.firebase().auth().devservice(), + FirebaseEmulatorContainer.Emulator.EMULATOR_SUITE_UI, config.firebase().devservice().ui(), + FirebaseEmulatorContainer.Emulator.REALTIME_DATABASE, config.database().devservice(), + FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE, config.firestore().devservice(), + FirebaseEmulatorContainer.Emulator.CLOUD_FUNCTIONS, config.functions().devservice(), + FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE, config.storage().devservice(), + FirebaseEmulatorContainer.Emulator.FIREBASE_HOSTING, config.firebase().hosting().devservice(), + FirebaseEmulatorContainer.Emulator.PUB_SUB, config.pubsub().devservice()); } - private Map exposedEmulators( - Map devServices) { + private Map exposedEmulators( + Map devServices) { var emulators = devServices .entrySet() .stream() @@ -54,21 +54,21 @@ private Map emulators.put( - FirebaseEmulatorContainer.Emulators.EMULATOR_HUB, + FirebaseEmulatorContainer.Emulator.EMULATOR_HUB, new FirebaseEmulatorContainer.ExposedPort(port))); uiService.loggingPort().ifPresent(port -> emulators.put( - FirebaseEmulatorContainer.Emulators.LOGGING, + FirebaseEmulatorContainer.Emulator.LOGGING, new FirebaseEmulatorContainer.ExposedPort(port))); var firestoreService = (FirebaseDevServiceConfig.Firestore.FirestoreDevService) devServices - .get(FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE); + .get(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE); firestoreService.websocketPort().ifPresent(port -> emulators.put( - FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE_WS, + FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE_WS, new FirebaseEmulatorContainer.ExposedPort(port))); // TODO: Event arc? diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java index 037e7616..6ad035db 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java @@ -25,7 +25,10 @@ public class FirebaseEmulatorContainer extends GenericContainer javaToolOptions, Optional emulatorData, Optional hostingContentDir, - Map services) { + Map services) { } - private final Map services; + private final Map services; /** * Creates a new Firebase Emulator container @@ -188,7 +191,7 @@ private static class FirebaseDockerBuilder { private final ImageFromDockerfile result; private final EmulatorConfig firebaseConfig; - private final Map devServices; + private final Map devServices; private DockerfileBuilder dockerBuilder; @@ -216,23 +219,23 @@ public ImageFromDockerfile build() { } private void validateConfiguration() { - if (isEmulatorEnabled(Emulators.AUTHENTICATION) && firebaseConfig.projectId().isEmpty()) { + if (isEmulatorEnabled(Emulator.AUTHENTICATION) && firebaseConfig.projectId().isEmpty()) { throw new IllegalStateException("Can't create Firebase Auth emulator. Google Project id is required"); } - if (isEmulatorEnabled(Emulators.EMULATOR_SUITE_UI)) { - if (!isEmulatorEnabled(Emulators.EMULATOR_HUB)) { + if (isEmulatorEnabled(Emulator.EMULATOR_SUITE_UI)) { + if (!isEmulatorEnabled(Emulator.EMULATOR_HUB)) { LOGGER.info( "Firebase Emulator UI is enabled, but no Hub port is specified. You will not be able to use the Hub API "); } - if (!isEmulatorEnabled(Emulators.LOGGING)) { + if (!isEmulatorEnabled(Emulator.LOGGING)) { LOGGER.info( "Firebase Emulator UI is enabled, but no Logging port is specified. You will not be able to see the logging "); } - if (isEmulatorEnabled(Emulators.CLOUD_FIRESTORE)) { - if (!isEmulatorEnabled(Emulators.CLOUD_FIRESTORE_WS)) { + if (isEmulatorEnabled(Emulator.CLOUD_FIRESTORE)) { + if (!isEmulatorEnabled(Emulator.CLOUD_FIRESTORE_WS)) { LOGGER.warn("Firebase Firestore Emulator and Emulator UI are enabled but no Firestore Websocket " + "port is specified. You will not be able to use the Firestore UI"); } @@ -254,14 +257,14 @@ private void installNeededSoftware() { } private void downloadEmulators() { - downloadEmulator(Emulators.REALTIME_DATABASE, "database"); - downloadEmulator(Emulators.CLOUD_FIRESTORE, "firestore"); - downloadEmulator(Emulators.PUB_SUB, "pubsub"); - downloadEmulator(Emulators.CLOUD_STORAGE, "storage"); - downloadEmulator(Emulators.EMULATOR_SUITE_UI, "ui"); + downloadEmulator(Emulator.REALTIME_DATABASE, "database"); + downloadEmulator(Emulator.CLOUD_FIRESTORE, "firestore"); + downloadEmulator(Emulator.PUB_SUB, "pubsub"); + downloadEmulator(Emulator.CLOUD_STORAGE, "storage"); + downloadEmulator(Emulator.EMULATOR_SUITE_UI, "ui"); } - private void downloadEmulator(Emulators emulator, String downloadId) { + private void downloadEmulator(Emulator emulator, String downloadId) { if (isEmulatorEnabled(emulator)) { dockerBuilder.run("firebase setup:emulators:" + downloadId); } @@ -308,11 +311,11 @@ private void generateFirebaseJson() { .orElse(emulator.internalPort); String additionalConfig = ""; - if (emulator.equals(Emulators.CLOUD_FIRESTORE)) { - var wsService = this.devServices.get(Emulators.CLOUD_FIRESTORE_WS); + if (emulator.equals(Emulator.CLOUD_FIRESTORE)) { + var wsService = this.devServices.get(Emulator.CLOUD_FIRESTORE_WS); if (wsService != null) { var wsPort = Optional.ofNullable(wsService.fixedPort) - .orElse(Emulators.CLOUD_FIRESTORE.internalPort); + .orElse(Emulator.CLOUD_FIRESTORE.internalPort); additionalConfig = "\t\t\t\"websocketPort\": " + wsPort + ",\n"; } } @@ -327,7 +330,7 @@ private void generateFirebaseJson() { firebaseJson.append(emulatorsJson).append("\n"); firebaseJson.append("\t}\n"); - if (isEmulatorEnabled(Emulators.CLOUD_FIRESTORE)) { + if (isEmulatorEnabled(Emulator.CLOUD_FIRESTORE)) { var firestoreJson = ",\"firestore\": {}\n"; firebaseJson.append(firestoreJson); } @@ -386,7 +389,7 @@ private void runExecutable() { dockerBuilder.cmd(arguments.toArray(new String[0])); } - private boolean isEmulatorEnabled(Emulators emulator) { + private boolean isEmulatorEnabled(Emulator emulator) { return this.devServices.containsKey(emulator); } } @@ -424,7 +427,7 @@ public void configure() { waitingFor(Wait.forLogMessage(".*Emulator Hub running at.*", 1)); } - public Map emulatorEndpoints() { + public Map emulatorEndpoints() { return services.keySet() .stream() .collect(Collectors.toMap( @@ -432,7 +435,7 @@ public Map emulatorEndpoints() { this::getEmulatorEndpoint)); } - public Integer emulatorPort(Emulators emulator) { + public Integer emulatorPort(Emulator emulator) { var exposedPort = services.get(emulator); if (exposedPort.isFixed()) { return exposedPort.fixedPort(); @@ -441,7 +444,7 @@ public Integer emulatorPort(Emulators emulator) { } } - public Map emulatorPorts() { + public Map emulatorPorts() { return services.keySet() .stream() .collect(Collectors.toMap( @@ -449,7 +452,7 @@ public Map emulatorPorts() { this::emulatorPort)); } - private String getEmulatorEndpoint(Emulators emulator) { + private String getEmulatorEndpoint(Emulator emulator) { return this.getHost() + ":" + emulatorPort(emulator); } } diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java index b5c5add9..51199142 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java @@ -86,22 +86,22 @@ private void assertPathEndsWith(String expected, Path path) { void testExposedEmulators() { FirebaseEmulatorContainer.EmulatorConfig emulatorConfig = configBuilder.build(); - Map exposedPorts = emulatorConfig + Map exposedPorts = emulatorConfig .services(); assertEquals(10, exposedPorts.size()); - assertEquals(6000, exposedPorts.get(FirebaseEmulatorContainer.Emulators.EMULATOR_SUITE_UI).fixedPort()); - assertEquals(6001, exposedPorts.get(FirebaseEmulatorContainer.Emulators.LOGGING).fixedPort()); - assertEquals(6002, exposedPorts.get(FirebaseEmulatorContainer.Emulators.EMULATOR_HUB).fixedPort()); - assertEquals(6003, exposedPorts.get(FirebaseEmulatorContainer.Emulators.AUTHENTICATION).fixedPort()); - assertEquals(6004, exposedPorts.get(FirebaseEmulatorContainer.Emulators.FIREBASE_HOSTING).fixedPort()); - assertEquals(6006, exposedPorts.get(FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE).fixedPort()); - assertEquals(6007, exposedPorts.get(FirebaseEmulatorContainer.Emulators.CLOUD_FIRESTORE_WS).fixedPort()); - assertEquals(6008, exposedPorts.get(FirebaseEmulatorContainer.Emulators.CLOUD_FUNCTIONS).fixedPort()); - assertEquals(6009, exposedPorts.get(FirebaseEmulatorContainer.Emulators.PUB_SUB).fixedPort()); - assertNull(exposedPorts.get(FirebaseEmulatorContainer.Emulators.CLOUD_STORAGE).fixedPort()); - - assertNull(exposedPorts.get(FirebaseEmulatorContainer.Emulators.REALTIME_DATABASE)); + assertEquals(6000, exposedPorts.get(FirebaseEmulatorContainer.Emulator.EMULATOR_SUITE_UI).fixedPort()); + assertEquals(6001, exposedPorts.get(FirebaseEmulatorContainer.Emulator.LOGGING).fixedPort()); + assertEquals(6002, exposedPorts.get(FirebaseEmulatorContainer.Emulator.EMULATOR_HUB).fixedPort()); + assertEquals(6003, exposedPorts.get(FirebaseEmulatorContainer.Emulator.AUTHENTICATION).fixedPort()); + assertEquals(6004, exposedPorts.get(FirebaseEmulatorContainer.Emulator.FIREBASE_HOSTING).fixedPort()); + assertEquals(6006, exposedPorts.get(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE).fixedPort()); + assertEquals(6007, exposedPorts.get(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE_WS).fixedPort()); + assertEquals(6008, exposedPorts.get(FirebaseEmulatorContainer.Emulator.CLOUD_FUNCTIONS).fixedPort()); + assertEquals(6009, exposedPorts.get(FirebaseEmulatorContainer.Emulator.PUB_SUB).fixedPort()); + assertNull(exposedPorts.get(FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE).fixedPort()); + + assertNull(exposedPorts.get(FirebaseEmulatorContainer.Emulator.REALTIME_DATABASE)); } // Record implementations for interfaces diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index 40e46955..de9869a3 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -16,6 +16,7 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.testcontainers.containers.output.OutputFrame; import org.testcontainers.junit.jupiter.Testcontainers; import com.google.api.core.ApiFuture; @@ -43,7 +44,7 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.EmulatorConfig; -import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.Emulators; +import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.Emulator; import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.ExposedPort; @Testcontainers @@ -56,19 +57,19 @@ public class FirebaseEmulatorContainerIntegrationTest { private static final String emulatorHost; private static final FirebaseApp app; - private static final Map SERVICES = Map.of( - Emulators.AUTHENTICATION, new ExposedPort(6000), - Emulators.REALTIME_DATABASE, new ExposedPort(6001), - Emulators.CLOUD_FIRESTORE, new ExposedPort(6002), - Emulators.CLOUD_FIRESTORE_WS, new ExposedPort(6003), - Emulators.PUB_SUB, new ExposedPort(6004), - Emulators.CLOUD_STORAGE, new ExposedPort(6005), + private static final Map SERVICES = Map.of( + Emulator.AUTHENTICATION, new ExposedPort(6000), + Emulator.REALTIME_DATABASE, new ExposedPort(6001), + Emulator.CLOUD_FIRESTORE, new ExposedPort(6002), + Emulator.CLOUD_FIRESTORE_WS, new ExposedPort(6003), + Emulator.PUB_SUB, new ExposedPort(6004), + Emulator.CLOUD_STORAGE, new ExposedPort(6005), // Emulators.FIREBASE_HOSTING, new ExposedPort(6006), // Emulators.CLOUD_FUNCTIONS, new ExposedPort(6007), // Emulators.EVENT_ARC, new ExposedPort(6008), - Emulators.EMULATOR_SUITE_UI, new ExposedPort(6009), - Emulators.EMULATOR_HUB, new ExposedPort(6010), - Emulators.LOGGING, new ExposedPort(6011)); + Emulator.EMULATOR_SUITE_UI, new ExposedPort(6009), + Emulator.EMULATOR_HUB, new ExposedPort(6010), + Emulator.LOGGING, new ExposedPort(6011)); static { try { @@ -96,9 +97,12 @@ Emulators.EMULATOR_HUB, new ExposedPort(6010), firebaseContainer = new FirebaseEmulatorContainer(config); firebaseContainer.start(); + firebaseContainer.followOutput(System.out::println, OutputFrame.OutputType.STDOUT); + firebaseContainer.followOutput(System.err::println, OutputFrame.OutputType.STDERR); + emulatorHost = firebaseContainer.getHost(); - int dbPort = firebaseContainer.emulatorPort(Emulators.REALTIME_DATABASE); + int dbPort = firebaseContainer.emulatorPort(Emulator.REALTIME_DATABASE); var firebaseBuilder = FirebaseOptions.builder() .setProjectId("demo-test-project") @@ -155,7 +159,7 @@ private static void validateEmulatorDataWritten() { @Disabled public void testFirebaseHostingEmulatorConnection() throws Exception { // Validate that the static HTML file is accessible via HTTP - int hostingPort = firebaseContainer.emulatorPort(Emulators.FIREBASE_HOSTING); + int hostingPort = firebaseContainer.emulatorPort(Emulator.FIREBASE_HOSTING); // Construct URL for the hosted file URL url = new URL("http://" + emulatorHost + ":" + hostingPort + "/index.html"); @@ -176,7 +180,7 @@ public void testFirebaseHostingEmulatorConnection() throws Exception { @Test public void testFirebaseAuthenticationEmulatorConnection() throws FirebaseAuthException { // Retrieve the host and port for the Authentication emulator - int authPort = firebaseContainer.emulatorPort(Emulators.AUTHENTICATION); + int authPort = firebaseContainer.emulatorPort(Emulator.AUTHENTICATION); // Set the environment variable for the Firebase Authentication emulator FirebaseProcessEnvironment.setenv("FIREBASE_AUTH_EMULATOR_HOST", emulatorHost + ":" + authPort); @@ -199,7 +203,7 @@ public void testFirebaseAuthenticationEmulatorConnection() throws FirebaseAuthEx @Test public void testFirestoreEmulatorConnection() throws ExecutionException, InterruptedException { - int firestorePort = firebaseContainer.emulatorPort(Emulators.CLOUD_FIRESTORE); + int firestorePort = firebaseContainer.emulatorPort(Emulator.CLOUD_FIRESTORE); FirestoreOptions options = FirestoreOptions.newBuilder() .setProjectId("demo-test-project") @@ -248,7 +252,7 @@ public void onCancelled(DatabaseError error) { @Test public void testPubSubEmulatorConnection() throws Exception { // Retrieve the host and port for the Pub/Sub emulator - int pubSubPort = firebaseContainer.emulatorPort(Emulators.PUB_SUB); + int pubSubPort = firebaseContainer.emulatorPort(Emulator.PUB_SUB); // Set up a gRPC channel to the Pub/Sub emulator ManagedChannel channel = ManagedChannelBuilder.forAddress(emulatorHost, pubSubPort) @@ -286,7 +290,7 @@ public void testPubSubEmulatorConnection() throws Exception { @Test @Disabled public void testStorageEmulatorConnection() { - int storagePort = firebaseContainer.emulatorPort(Emulators.CLOUD_STORAGE); + int storagePort = firebaseContainer.emulatorPort(Emulator.CLOUD_STORAGE); Storage storage = StorageOptions.newBuilder() .setHost("http://" + emulatorHost + ":" + storagePort) @@ -313,7 +317,7 @@ public void testStorageEmulatorConnection() { @Test public void testEmulatorUIReachable() throws Exception { // Get the host and port for the Emulator UI - int uiPort = firebaseContainer.emulatorPort(Emulators.EMULATOR_SUITE_UI); + int uiPort = firebaseContainer.emulatorPort(Emulator.EMULATOR_SUITE_UI); // Construct the URL for the Emulator UI root (where index.html would be served) URL url = new URL("http://" + emulatorHost + ":" + uiPort + "/"); @@ -333,7 +337,7 @@ public void testEmulatorUIReachable() throws Exception { @Test public void testEmulatorHub() throws Exception { // Get the host and port for the Emulator UI - int uiPort = firebaseContainer.emulatorPort(Emulators.EMULATOR_HUB); + int uiPort = firebaseContainer.emulatorPort(Emulator.EMULATOR_HUB); // Construct the URL for the Emulator UI root (where index.html would be served) URL url = new URL("http://" + emulatorHost + ":" + uiPort + "/emulators"); From cf1c7835d4c9533d86680b9f714eb9fa1960ae59 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 18:13:44 +0100 Subject: [PATCH 023/101] Fix writing container logs --- ...FirebaseEmulatorContainerIntegrationTest.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index de9869a3..b6da2d30 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -97,8 +97,8 @@ Emulator.EMULATOR_HUB, new ExposedPort(6010), firebaseContainer = new FirebaseEmulatorContainer(config); firebaseContainer.start(); - firebaseContainer.followOutput(System.out::println, OutputFrame.OutputType.STDOUT); - firebaseContainer.followOutput(System.err::println, OutputFrame.OutputType.STDERR); + firebaseContainer.followOutput(FirebaseEmulatorContainerIntegrationTest::writeToStdOut, OutputFrame.OutputType.STDOUT); + firebaseContainer.followOutput(FirebaseEmulatorContainerIntegrationTest::writeToStdErr, OutputFrame.OutputType.STDERR); emulatorHost = firebaseContainer.getHost(); @@ -116,6 +116,18 @@ Emulator.EMULATOR_HUB, new ExposedPort(6010), } } + private static void writeToStdOut(OutputFrame frame) { + writeOutputFrame(frame, System.out); + } + + private static void writeToStdErr(OutputFrame frame) { + writeOutputFrame(frame, System.err); + } + + private static void writeOutputFrame(OutputFrame frame, PrintStream output) { + output.println(frame.getUtf8StringWithoutLineEnding()); + } + @AfterAll public static void tearDown() { if (firebaseContainer != null) { From 78d83081a5ebecc761d3df92b0a9f9c8483fccf9 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 18:19:18 +0100 Subject: [PATCH 024/101] Formatting fix --- .../FirebaseEmulatorContainerIntegrationTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index b6da2d30..24eac0c6 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -43,8 +43,8 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; -import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.EmulatorConfig; import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.Emulator; +import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.EmulatorConfig; import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.ExposedPort; @Testcontainers @@ -97,8 +97,10 @@ Emulator.EMULATOR_HUB, new ExposedPort(6010), firebaseContainer = new FirebaseEmulatorContainer(config); firebaseContainer.start(); - firebaseContainer.followOutput(FirebaseEmulatorContainerIntegrationTest::writeToStdOut, OutputFrame.OutputType.STDOUT); - firebaseContainer.followOutput(FirebaseEmulatorContainerIntegrationTest::writeToStdErr, OutputFrame.OutputType.STDERR); + firebaseContainer.followOutput(FirebaseEmulatorContainerIntegrationTest::writeToStdOut, + OutputFrame.OutputType.STDOUT); + firebaseContainer.followOutput(FirebaseEmulatorContainerIntegrationTest::writeToStdErr, + OutputFrame.OutputType.STDERR); emulatorHost = firebaseContainer.getHost(); From 9bc76792e2cd9bb2ddfe85fc355d5b0670075c07 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 18:54:11 +0100 Subject: [PATCH 025/101] Output debug data for output files --- .../deployment/FirebaseEmulatorContainerIntegrationTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index 24eac0c6..b20f9421 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -7,6 +7,7 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.util.Arrays; import java.util.Map; import java.util.Optional; import java.util.concurrent.CountDownLatch; @@ -161,6 +162,9 @@ private static void deleteDirectoryRecursively(File directory) { } private static void validateEmulatorDataWritten() { + System.out.println(tempEmulatorDataDir.getAbsolutePath()); + Arrays.stream(tempEmulatorDataDir.listFiles()).forEach(System.out::println); + var emulatorDataDir = new File(tempEmulatorDataDir, "emulator-data"); // Verify that files were written to the emulator data directory From 90bfcec998c6d35b430e9fcde31ce36af21756a0 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 18:55:14 +0100 Subject: [PATCH 026/101] Documentation regenerated --- .../quarkus-google-cloud-firebase.adoc | 150 +++++++++++++++--- ...-google-cloud-firebase_quarkus.google.adoc | 150 +++++++++++++++--- 2 files changed, 256 insertions(+), 44 deletions(-) diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc index bad05ae9..ca13cdb6 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc @@ -47,6 +47,8 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g -- Sets the Docker image name for the Google Cloud SDK. This image is used to emulate the Pub/Sub service in the development environment. The default value is 'gcr.io/google.com/cloudsdktool/google-cloud-cli'. +See also the documentation on Custom Docker images for more info about this image. + ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] @@ -62,7 +64,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Sets the firebase version to use. Defaults to the latest version. +The version of the firebase tools to use. Default is to use the latest available version. ifdef::add-copy-button-to-env-var[] @@ -104,6 +106,8 @@ Indicate to use a custom firebase.json file instead of the automatically generat to ensure the ports of the emulator are exposed correctly at the docker container level. +See the section on Custom Firebase Json in the docs for more info. + ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++[] @@ -119,7 +123,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Sets the JAVA tool options for emulators based on the Java runtime environment. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#specifying_java_options[here] +Sets the JAVA tool options for emulators based on the Java runtime environment like -Xmx. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#specifying_java_options[here] ifdef::add-copy-button-to-env-var[] @@ -136,7 +140,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Allow to import and export data. Specify a path relative to the current working directory of the executable (for most unit tests, this is the root of the build directory) to be used for import and export of emulator data. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data[here] +Allow to import and export data. Specify a path relative to the current working directory of the executable (for most unit tests, this is the root of the build directory) to be used for import and export of emulator data. The data will be written to a subdirectory called "emulator-data" of this directory. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data[here] ifdef::add-copy-button-to-env-var[] @@ -170,7 +174,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] @@ -183,11 +187,45 @@ endif::add-copy-button-to-env-var[] |int | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-logging-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-logging-port[`quarkus.google.cloud.firebase.devservice.ui.logging-port`]## + +[.description] +-- +Port on which to expose the logging endpoint port. This is needed in case you want to view the logging via the Emulator UI. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-hub-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-hub-port[`quarkus.google.cloud.firebase.devservice.ui.hub-port`]## + +[.description] +-- +Port on which to expose the hub endpoint port. This is needed if you want to use the hub API of the Emulator UI. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-enabled[`quarkus.google.cloud.firebase.auth.devservice.enabled`]## [.description] -- -Indicates whether the service should be enabled or not. The default value is 'false'. +Indicates whether the DevService should be enabled or not. The default value is 'false'. ifdef::add-copy-button-to-env-var[] @@ -204,7 +242,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] @@ -221,7 +259,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Indicates whether the service should be enabled or not. The default value is 'false'. +Indicates whether the DevService should be enabled or not. The default value is 'false'. ifdef::add-copy-button-to-env-var[] @@ -238,7 +276,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] @@ -251,11 +289,28 @@ endif::add-copy-button-to-env-var[] |int | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-hosting-path]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-hosting-path[`quarkus.google.cloud.firebase.hosting.hosting-path`]## + +[.description] +-- +Path to the hosting files. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-enabled[`quarkus.google.cloud.database.devservice.enabled`]## [.description] -- -Indicates whether the service should be enabled or not. The default value is 'false'. +Indicates whether the DevService should be enabled or not. The default value is 'false'. ifdef::add-copy-button-to-env-var[] @@ -272,7 +327,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] @@ -289,7 +344,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Indicates whether the service should be enabled or not. The default value is 'false'. +Indicates whether the DevService should be enabled or not. The default value is 'false'. ifdef::add-copy-button-to-env-var[] @@ -306,7 +361,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] @@ -319,11 +374,28 @@ endif::add-copy-button-to-env-var[] |int | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-websocket-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-websocket-port[`quarkus.google.cloud.firestore.devservice.websocket-port`]## + +[.description] +-- +Port on which to expose the websocket port. This is needed in case the Firestore Emulator UI needs is used. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-enabled[`quarkus.google.cloud.functions.devservice.enabled`]## [.description] -- -Indicates whether the service should be enabled or not. The default value is 'false'. +Indicates whether the DevService should be enabled or not. The default value is 'false'. ifdef::add-copy-button-to-env-var[] @@ -340,7 +412,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] @@ -353,35 +425,69 @@ endif::add-copy-button-to-env-var[] |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-enabled[`quarkus.google.cloud.pub-sub.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-enabled[`quarkus.google.cloud.pubsub.devservice.enabled`]## [.description] -- -Indicates whether the service should be enabled or not. The default value is 'false'. +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-emulator-port[`quarkus.google.cloud.pubsub.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-enabled[`quarkus.google.cloud.storage.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-emulator-port[`quarkus.google.cloud.pub-sub.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-emulator-port[`quarkus.google.cloud.storage.devservice.emulator-port`]## [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc index bad05ae9..ca13cdb6 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc @@ -47,6 +47,8 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g -- Sets the Docker image name for the Google Cloud SDK. This image is used to emulate the Pub/Sub service in the development environment. The default value is 'gcr.io/google.com/cloudsdktool/google-cloud-cli'. +See also the documentation on Custom Docker images for more info about this image. + ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] @@ -62,7 +64,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Sets the firebase version to use. Defaults to the latest version. +The version of the firebase tools to use. Default is to use the latest available version. ifdef::add-copy-button-to-env-var[] @@ -104,6 +106,8 @@ Indicate to use a custom firebase.json file instead of the automatically generat to ensure the ports of the emulator are exposed correctly at the docker container level. +See the section on Custom Firebase Json in the docs for more info. + ifdef::add-copy-button-to-env-var[] Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++[] @@ -119,7 +123,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Sets the JAVA tool options for emulators based on the Java runtime environment. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#specifying_java_options[here] +Sets the JAVA tool options for emulators based on the Java runtime environment like -Xmx. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#specifying_java_options[here] ifdef::add-copy-button-to-env-var[] @@ -136,7 +140,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Allow to import and export data. Specify a path relative to the current working directory of the executable (for most unit tests, this is the root of the build directory) to be used for import and export of emulator data. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data[here] +Allow to import and export data. Specify a path relative to the current working directory of the executable (for most unit tests, this is the root of the build directory) to be used for import and export of emulator data. The data will be written to a subdirectory called "emulator-data" of this directory. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data[here] ifdef::add-copy-button-to-env-var[] @@ -170,7 +174,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] @@ -183,11 +187,45 @@ endif::add-copy-button-to-env-var[] |int | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-logging-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-logging-port[`quarkus.google.cloud.firebase.devservice.ui.logging-port`]## + +[.description] +-- +Port on which to expose the logging endpoint port. This is needed in case you want to view the logging via the Emulator UI. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-hub-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-hub-port[`quarkus.google.cloud.firebase.devservice.ui.hub-port`]## + +[.description] +-- +Port on which to expose the hub endpoint port. This is needed if you want to use the hub API of the Emulator UI. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-enabled[`quarkus.google.cloud.firebase.auth.devservice.enabled`]## [.description] -- -Indicates whether the service should be enabled or not. The default value is 'false'. +Indicates whether the DevService should be enabled or not. The default value is 'false'. ifdef::add-copy-button-to-env-var[] @@ -204,7 +242,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] @@ -221,7 +259,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Indicates whether the service should be enabled or not. The default value is 'false'. +Indicates whether the DevService should be enabled or not. The default value is 'false'. ifdef::add-copy-button-to-env-var[] @@ -238,7 +276,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] @@ -251,11 +289,28 @@ endif::add-copy-button-to-env-var[] |int | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-hosting-path]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-hosting-path[`quarkus.google.cloud.firebase.hosting.hosting-path`]## + +[.description] +-- +Path to the hosting files. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-enabled[`quarkus.google.cloud.database.devservice.enabled`]## [.description] -- -Indicates whether the service should be enabled or not. The default value is 'false'. +Indicates whether the DevService should be enabled or not. The default value is 'false'. ifdef::add-copy-button-to-env-var[] @@ -272,7 +327,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] @@ -289,7 +344,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Indicates whether the service should be enabled or not. The default value is 'false'. +Indicates whether the DevService should be enabled or not. The default value is 'false'. ifdef::add-copy-button-to-env-var[] @@ -306,7 +361,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] @@ -319,11 +374,28 @@ endif::add-copy-button-to-env-var[] |int | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-websocket-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-websocket-port[`quarkus.google.cloud.firestore.devservice.websocket-port`]## + +[.description] +-- +Port on which to expose the websocket port. This is needed in case the Firestore Emulator UI needs is used. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-enabled[`quarkus.google.cloud.functions.devservice.enabled`]## [.description] -- -Indicates whether the service should be enabled or not. The default value is 'false'. +Indicates whether the DevService should be enabled or not. The default value is 'false'. ifdef::add-copy-button-to-env-var[] @@ -340,7 +412,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-g [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] @@ -353,35 +425,69 @@ endif::add-copy-button-to-env-var[] |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-enabled[`quarkus.google.cloud.pub-sub.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-enabled[`quarkus.google.cloud.pubsub.devservice.enabled`]## [.description] -- -Indicates whether the service should be enabled or not. The default value is 'false'. +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-emulator-port[`quarkus.google.cloud.pubsub.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-enabled[`quarkus.google.cloud.storage.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pub-sub-devservice-emulator-port[`quarkus.google.cloud.pub-sub.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-emulator-port[`quarkus.google.cloud.storage.devservice.emulator-port`]## [.description] -- -Specifies the emulatorPort on which the service should run in the development environment. +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUB_SUB_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int From 16ca50a17bf26841ed4601787c3ebf6c96ea1a15 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 19:00:12 +0100 Subject: [PATCH 027/101] Debug export on build server --- .../deployment/FirebaseEmulatorContainerIntegrationTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index b20f9421..2008c654 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -166,6 +166,11 @@ private static void validateEmulatorDataWritten() { Arrays.stream(tempEmulatorDataDir.listFiles()).forEach(System.out::println); var emulatorDataDir = new File(tempEmulatorDataDir, "emulator-data"); + assertTrue(emulatorDataDir.exists()); + assertTrue(emulatorDataDir.isDirectory()); + assertTrue(emulatorDataDir.canRead()); + assertTrue(emulatorDataDir.canWrite()); + assertTrue(emulatorDataDir.canExecute()); // Verify that files were written to the emulator data directory File[] files = emulatorDataDir.listFiles(); From 42971d57ea3a5d571861eb9939b71060449349b6 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 19:07:33 +0100 Subject: [PATCH 028/101] Debug export on build server --- .../deployment/FirebaseEmulatorContainerIntegrationTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index 2008c654..bd1e7ecf 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -166,6 +166,11 @@ private static void validateEmulatorDataWritten() { Arrays.stream(tempEmulatorDataDir.listFiles()).forEach(System.out::println); var emulatorDataDir = new File(tempEmulatorDataDir, "emulator-data"); + try { + Runtime.getRuntime().exec(new String[]{"ls", "-l", tempEmulatorDataDir.getAbsolutePath()}); + } catch (IOException e) { + throw new RuntimeException(e); + } assertTrue(emulatorDataDir.exists()); assertTrue(emulatorDataDir.isDirectory()); assertTrue(emulatorDataDir.canRead()); From 020f398c7d1e121c2303422d15c3d54d199839b8 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 19:09:05 +0100 Subject: [PATCH 029/101] Debug export on build server --- .../deployment/FirebaseEmulatorContainerIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index bd1e7ecf..b5b71418 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -167,7 +167,7 @@ private static void validateEmulatorDataWritten() { var emulatorDataDir = new File(tempEmulatorDataDir, "emulator-data"); try { - Runtime.getRuntime().exec(new String[]{"ls", "-l", tempEmulatorDataDir.getAbsolutePath()}); + Runtime.getRuntime().exec(new String[] { "ls", "-l", tempEmulatorDataDir.getAbsolutePath() }); } catch (IOException e) { throw new RuntimeException(e); } From 235c6915d0d09c7a9f73d7aa6dc814c24b608939 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 19:15:16 +0100 Subject: [PATCH 030/101] Debug export on build server --- .../FirebaseEmulatorContainerIntegrationTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index b5b71418..6d90d293 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -14,6 +14,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -167,7 +168,12 @@ private static void validateEmulatorDataWritten() { var emulatorDataDir = new File(tempEmulatorDataDir, "emulator-data"); try { - Runtime.getRuntime().exec(new String[] { "ls", "-l", tempEmulatorDataDir.getAbsolutePath() }); + var process = Runtime + .getRuntime() + .exec(new String[] { "ls", "-l", tempEmulatorDataDir.getAbsolutePath() }); + + IOUtils.copy(process.getInputStream(), System.out); + IOUtils.copy(process.getErrorStream(), System.err); } catch (IOException e) { throw new RuntimeException(e); } From ab2ff11efb872f72ad58a9b147c3c389e90a6ae0 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 19:15:56 +0100 Subject: [PATCH 031/101] Debug export on build server --- .../deployment/FirebaseEmulatorContainerIntegrationTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index 6d90d293..b9f26379 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -171,10 +171,11 @@ private static void validateEmulatorDataWritten() { var process = Runtime .getRuntime() .exec(new String[] { "ls", "-l", tempEmulatorDataDir.getAbsolutePath() }); + process.waitFor(); IOUtils.copy(process.getInputStream(), System.out); IOUtils.copy(process.getErrorStream(), System.err); - } catch (IOException e) { + } catch (IOException | InterruptedException e) { throw new RuntimeException(e); } assertTrue(emulatorDataDir.exists()); From e18d12fadb572614afa7377e5ecf1c2d28b07170 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 21:08:32 +0100 Subject: [PATCH 032/101] Add specifying the user and groupid --- .../deployment/FirebaseDevServiceConfig.java | 10 +++ .../FirebaseEmulatorConfigBuilder.java | 5 +- .../deployment/FirebaseEmulatorContainer.java | 65 +++++++++++++++++-- .../FirebaseEmulatorConfigBuilderTest.java | 6 +- ...ebaseEmulatorContainerIntegrationTest.java | 8 ++- 5 files changed, 84 insertions(+), 10 deletions(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index 85acf702..4376cef0 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -97,6 +97,16 @@ interface DevService { @WithDefault("node:23-alpine") String imageName(); + /** + * Id of the docker user to run the firebase executable. + */ + Optional dockerUser(); + + /** + * Id of the group to which the {@link #dockerUser()} belongs. + */ + Optional dockerGroup(); + /** * The version of the firebase tools to use. Default is to use the latest available version. */ diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java index 4e801e67..062c4d4d 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java @@ -20,7 +20,10 @@ public FirebaseEmulatorContainer.EmulatorConfig build() { var devService = config.firebase().devservice(); return new FirebaseEmulatorContainer.EmulatorConfig( - devService.imageName(), + new FirebaseEmulatorContainer.DockerConfig( + devService.imageName(), + devService.dockerUser(), + devService.dockerGroup()), devService.firebaseVersion(), config.projectId(), devService.token(), diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java index 6ad035db..adcdd9f3 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java @@ -138,10 +138,23 @@ public boolean isFixed() { } } + /** + * The docker image configuration + * + * @param imageName The name of the docker image + * @param userId The user id to run the docker image + * @param groupId The group id to run the docker image + */ + public record DockerConfig( + String imageName, + Optional userId, + Optional groupId) { + } + /** * Describes the Firebase emulator configuration. * - * @param imageName The name of the image to use + * @param dockerConfig The docker configuration * @param firebaseVersion The firebase version to use * @param projectId The project ID, needed when running with the auth emulator * @param token The Google Cloud CLI token to use for authentication. Needed for firebase hosting @@ -151,7 +164,7 @@ public boolean isFixed() { * @param hostingContentDir The path to the directory containing the hosting content */ public record EmulatorConfig( - String imageName, + DockerConfig dockerConfig, String firebaseVersion, Optional projectId, Optional token, @@ -207,10 +220,13 @@ public ImageFromDockerfile build() { this.validateConfiguration(); this.configureBaseImage(); this.installNeededSoftware(); - this.downloadEmulators(); + this.clearUnneededUsersAndGroups(); this.authenticateToFirebase(); this.setupJavaToolOptions(); this.addFirebaseJson(); + this.fixFilePermissions(); + this.setupUserAndGroup(); + this.downloadEmulators(); this.setupDataImportExport(); this.setupHosting(); this.runExecutable(); @@ -246,14 +262,18 @@ private void validateConfiguration() { } private void configureBaseImage() { - dockerBuilder.from(firebaseConfig.imageName()); + dockerBuilder.from(firebaseConfig.dockerConfig().imageName()); } private void installNeededSoftware() { dockerBuilder - .run("apk --no-cache add openjdk11-jre bash curl openssl gettext nano nginx sudo") - .run("npm cache clean --force") - .run("npm i -g firebase-tools@" + firebaseConfig.firebaseVersion()); + .run("apk --no-cache add openjdk11-jre bash curl openssl gettext nano nginx sudo && " + + "npm cache clean --force && " + + "npm i -g firebase-tools@" + firebaseConfig.firebaseVersion()); + } + + private void clearUnneededUsersAndGroups() { + dockerBuilder.run("deluser nginx && delgroup abuild && delgroup ping"); } private void downloadEmulators() { @@ -354,6 +374,37 @@ private void setupHosting() { } } + private void fixFilePermissions() { + var group = dockerGroup(); + var user = dockerUser(); + + dockerBuilder.run("chown " + user + ":" + group + " -R /srv/*"); + } + + private void setupUserAndGroup() { + firebaseConfig.dockerConfig.groupId().ifPresent(group -> { + dockerBuilder.run("addgroup -g " + group + " runner"); + }); + + firebaseConfig.dockerConfig.userId().ifPresent(user -> { + var groupName = firebaseConfig.dockerConfig().groupId().map(i -> "runner").orElse("node"); + dockerBuilder.run("adduser -u " + user + " -G " + groupName + " -D -h /srv/firebase runner"); + }); + + var group = dockerGroup(); + var user = dockerUser(); + + dockerBuilder.user(user + ":" + group); + } + + private int dockerUser() { + return firebaseConfig.dockerConfig().userId().orElse(1000); + } + + private int dockerGroup() { + return firebaseConfig.dockerConfig().groupId().orElse(1000); + } + private void runExecutable() { List arguments = new ArrayList<>(); diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java index 51199142..17682d73 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java @@ -22,6 +22,8 @@ void setUp() { new TestFirebaseDevService( true, "node:21-alpine", + Optional.empty(), + Optional.empty(), "11.0.0", Optional.of("MY_TOKEN"), Optional.of("firebase.json"), @@ -67,7 +69,7 @@ void testBuild() { FirebaseEmulatorContainer.EmulatorConfig emulatorConfig = configBuilder.build(); assertNotNull(emulatorConfig); - assertEquals("node:21-alpine", emulatorConfig.imageName()); + assertEquals("node:21-alpine", emulatorConfig.dockerConfig().imageName()); assertEquals("11.0.0", emulatorConfig.firebaseVersion()); assertEquals("my-project-id", emulatorConfig.projectId().orElse(null)); assertEquals("MY_TOKEN", emulatorConfig.token().orElse(null)); @@ -124,6 +126,8 @@ record TestFirebase( record TestFirebaseDevService( boolean preferFirebaseDevServices, String imageName, + Optional dockerUser, + Optional dockerGroup, String firebaseVersion, Optional token, Optional customFirebaseJson, diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index b9f26379..cbdf3a3b 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -85,8 +85,14 @@ Emulator.EMULATOR_HUB, new ExposedPort(6010), writer.write("

Hello, Firebase Hosting!

"); } + /* + * We use user id = 991 & groupid = 999 by default, as these are the ids used by the gitlab runner. + */ EmulatorConfig config = new EmulatorConfig( - "node:23-alpine", // Default image + new FirebaseEmulatorContainer.DockerConfig( + "node:23-alpine", + Optional.of(991), + Optional.of(999)), "latest", // Firebase version Optional.of("demo-test-project"), Optional.empty(), From c430c57455d01375f18dfd9eafc07209fb17b284 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 21:18:32 +0100 Subject: [PATCH 033/101] Combine docker run commands and fix order of commands to speed up docker image creation. --- .../deployment/FirebaseEmulatorContainer.java | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java index adcdd9f3..7eea4a2b 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java @@ -1,10 +1,7 @@ package io.quarkiverse.googlecloudservices.firebase.deployment; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import org.jboss.logging.Logger; @@ -201,6 +198,13 @@ public FirebaseEmulatorContainer(EmulatorConfig firebaseConfig) { private static class FirebaseDockerBuilder { + private static final Map DOWNLOADABLE_EMULATORS = Map.of( + Emulator.REALTIME_DATABASE, "database", + Emulator.CLOUD_FIRESTORE, "firestore", + Emulator.PUB_SUB, "pubsub", + Emulator.CLOUD_STORAGE, "storage", + Emulator.EMULATOR_SUITE_UI, "ui"); + private final ImageFromDockerfile result; private final EmulatorConfig firebaseConfig; @@ -223,10 +227,10 @@ public ImageFromDockerfile build() { this.clearUnneededUsersAndGroups(); this.authenticateToFirebase(); this.setupJavaToolOptions(); - this.addFirebaseJson(); this.fixFilePermissions(); this.setupUserAndGroup(); this.downloadEmulators(); + this.addFirebaseJson(); this.setupDataImportExport(); this.setupHosting(); this.runExecutable(); @@ -269,7 +273,8 @@ private void installNeededSoftware() { dockerBuilder .run("apk --no-cache add openjdk11-jre bash curl openssl gettext nano nginx sudo && " + "npm cache clean --force && " + - "npm i -g firebase-tools@" + firebaseConfig.firebaseVersion()); + "npm i -g firebase-tools@" + firebaseConfig.firebaseVersion() + " &&" + + "mkdir -p " + FIREBASE_ROOT); } private void clearUnneededUsersAndGroups() { @@ -277,16 +282,21 @@ private void clearUnneededUsersAndGroups() { } private void downloadEmulators() { - downloadEmulator(Emulator.REALTIME_DATABASE, "database"); - downloadEmulator(Emulator.CLOUD_FIRESTORE, "firestore"); - downloadEmulator(Emulator.PUB_SUB, "pubsub"); - downloadEmulator(Emulator.CLOUD_STORAGE, "storage"); - downloadEmulator(Emulator.EMULATOR_SUITE_UI, "ui"); + var cmd = DOWNLOADABLE_EMULATORS + .entrySet() + .stream() + .map(e -> downloadEmulatorCommand(e.getKey(), e.getValue())) + .filter(Objects::nonNull) + .collect(Collectors.joining(" && ")); + + dockerBuilder.run(cmd); } - private void downloadEmulator(Emulator emulator, String downloadId) { + private String downloadEmulatorCommand(Emulator emulator, String downloadId) { if (isEmulatorEnabled(emulator)) { - dockerBuilder.run("firebase setup:emulators:" + downloadId); + return "firebase setup:emulators:" + downloadId; + } else { + return null; } } From beef407c09ff9b6a953568e872584810d64f3dc6 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 21:27:41 +0100 Subject: [PATCH 034/101] Combine docker run commands and fix order of commands to speed up docker image creation. --- .../deployment/FirebaseEmulatorContainer.java | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java index 7eea4a2b..ed08e6cb 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java @@ -223,11 +223,9 @@ public FirebaseDockerBuilder(EmulatorConfig firebaseConfig) { public ImageFromDockerfile build() { this.validateConfiguration(); this.configureBaseImage(); - this.installNeededSoftware(); - this.clearUnneededUsersAndGroups(); + this.initialSetup(); this.authenticateToFirebase(); this.setupJavaToolOptions(); - this.fixFilePermissions(); this.setupUserAndGroup(); this.downloadEmulators(); this.addFirebaseJson(); @@ -269,16 +267,15 @@ private void configureBaseImage() { dockerBuilder.from(firebaseConfig.dockerConfig().imageName()); } - private void installNeededSoftware() { + private void initialSetup() { dockerBuilder .run("apk --no-cache add openjdk11-jre bash curl openssl gettext nano nginx sudo && " + "npm cache clean --force && " + - "npm i -g firebase-tools@" + firebaseConfig.firebaseVersion() + " &&" + - "mkdir -p " + FIREBASE_ROOT); - } - - private void clearUnneededUsersAndGroups() { - dockerBuilder.run("deluser nginx && delgroup abuild && delgroup ping"); + "npm i -g firebase-tools@" + firebaseConfig.firebaseVersion() + " && " + + "deluser nginx && delgroup abuild && delgroup ping && " + + "mkdir -p " + FIREBASE_ROOT + " && " + + "mkdir -p " + FIREBASE_HOSTING_PATH + " && " + + "mkdir -p " + EMULATOR_DATA_PATH); } private void downloadEmulators() { @@ -372,7 +369,6 @@ private void generateFirebaseJson() { private void setupDataImportExport() { firebaseConfig.emulatorData().ifPresent(emulator -> { - this.dockerBuilder.run("mkdir -p " + EMULATOR_DATA_PATH); this.dockerBuilder.volume(EMULATOR_DATA_PATH); }); } @@ -380,31 +376,32 @@ private void setupDataImportExport() { private void setupHosting() { // Specify public directory if hosting is enabled if (firebaseConfig.hostingContentDir().isPresent()) { - dockerBuilder.run("mkdir -p " + FIREBASE_HOSTING_PATH); + this.dockerBuilder.volume(FIREBASE_HOSTING_PATH); } } - private void fixFilePermissions() { - var group = dockerGroup(); - var user = dockerUser(); - - dockerBuilder.run("chown " + user + ":" + group + " -R /srv/*"); - } - private void setupUserAndGroup() { + var commands = new ArrayList(); + firebaseConfig.dockerConfig.groupId().ifPresent(group -> { - dockerBuilder.run("addgroup -g " + group + " runner"); + commands.add("addgroup -g " + group + " runner"); }); firebaseConfig.dockerConfig.userId().ifPresent(user -> { var groupName = firebaseConfig.dockerConfig().groupId().map(i -> "runner").orElse("node"); - dockerBuilder.run("adduser -u " + user + " -G " + groupName + " -D -h /srv/firebase runner"); + commands.add("adduser -u " + user + " -G " + groupName + " -D -h /srv/firebase runner"); }); var group = dockerGroup(); var user = dockerUser(); - dockerBuilder.user(user + ":" + group); + commands.add("chown " + user + ":" + group + " -R /srv/*"); + + var runCmd = String.join(" && ", commands); + + dockerBuilder + .run(runCmd) + .user(user + ":" + group); } private int dockerUser() { From 382ee26cb993cf69e9506bd274e3468937c1b770 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 22:02:32 +0100 Subject: [PATCH 035/101] Fix file permissions --- .../firebase/deployment/FirebaseEmulatorContainer.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java index ed08e6cb..af21690b 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java @@ -21,6 +21,7 @@ public class FirebaseEmulatorContainer extends GenericContainer EMULATOR_DATA_PATH + "/emulator-data") + .map(path -> EMULATOR_EXPORT_PATH) .ifPresent(arguments::add); firebaseConfig From a77608d4d11ec41f4de40442b9beda69f72d4a3a Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 22:09:15 +0100 Subject: [PATCH 036/101] Try run as gitlab user --- .github/workflows/build.yml | 10 ++++++++-- .../FirebaseEmulatorContainerIntegrationTest.java | 13 +++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index da6ed777..becc40ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,8 +33,14 @@ jobs: ${{ runner.os }}-maven- - name: Build with Maven - run: mvn -B formatter:validate install --file pom.xml + run: | + export CURRENT_USER=$(id -u) + export CURRENT_GROUP=$(id -g) + mvn -B formatter:validate install --file pom.xml - name: Build in native - run: mvn -B -Pnative package --file integration-tests/main/pom.xml + run: | + export CURRENT_USER=$(id -u) + export CURRENT_GROUP=$(id -g) + mvn -B -Pnative package --file integration-tests/main/pom.xml diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index cbdf3a3b..719bc44f 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -75,6 +75,15 @@ Emulator.EMULATOR_HUB, new ExposedPort(6010), static { try { + var user = Optional + .ofNullable(System.getenv("CURRENT_USER")) + .map(Integer::valueOf); + var group = Optional + .ofNullable(System.getenv("CURRENT_GROUP")) + .map(Integer::valueOf); + + System.out.println("Running as user " + user + " and group " + group); + // Create a temporary directory for emulator data tempEmulatorDataDir = Files.createTempDirectory("firebase-emulator-data").toFile(); tempHostingContentDir = Files.createTempDirectory("firebase-hosting-content").toFile(); @@ -91,8 +100,8 @@ Emulator.EMULATOR_HUB, new ExposedPort(6010), EmulatorConfig config = new EmulatorConfig( new FirebaseEmulatorContainer.DockerConfig( "node:23-alpine", - Optional.of(991), - Optional.of(999)), + user, + group), "latest", // Firebase version Optional.of("demo-test-project"), Optional.empty(), From 994b330b7254b9df8d39c66dce01d622b42e8235 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 22:14:13 +0100 Subject: [PATCH 037/101] Cleanup debug code --- .../FirebaseEmulatorContainerIntegrationTest.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index 719bc44f..89044773 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -178,21 +178,7 @@ private static void deleteDirectoryRecursively(File directory) { } private static void validateEmulatorDataWritten() { - System.out.println(tempEmulatorDataDir.getAbsolutePath()); - Arrays.stream(tempEmulatorDataDir.listFiles()).forEach(System.out::println); - var emulatorDataDir = new File(tempEmulatorDataDir, "emulator-data"); - try { - var process = Runtime - .getRuntime() - .exec(new String[] { "ls", "-l", tempEmulatorDataDir.getAbsolutePath() }); - process.waitFor(); - - IOUtils.copy(process.getInputStream(), System.out); - IOUtils.copy(process.getErrorStream(), System.err); - } catch (IOException | InterruptedException e) { - throw new RuntimeException(e); - } assertTrue(emulatorDataDir.exists()); assertTrue(emulatorDataDir.isDirectory()); assertTrue(emulatorDataDir.canRead()); From e25d7b06caa7a2d565c6f68c4751679f9eeaeb49 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 22:22:35 +0100 Subject: [PATCH 038/101] Fix documentation --- .../firebase/deployment/FirebaseDevServiceConfig.java | 7 ++++++- .../FirebaseEmulatorContainerIntegrationTest.java | 9 ++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index 4376cef0..c70ba279 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -98,7 +98,12 @@ interface DevService { String imageName(); /** - * Id of the docker user to run the firebase executable. + * Id of the docker user to run the firebase executable. This is needed in environments where Docker + * does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker + * automatically performs this mapping and the data written by the emulator can be read by the user + * running the build. This is not the case in a regular (non-Desktop) setup, this is not the case + * and you may need to set the user id and {@link #dockerGroup()}. This option is often needed in CI + * environments. */ Optional dockerUser(); diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index 89044773..1f83de5b 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -75,6 +75,12 @@ Emulator.EMULATOR_HUB, new ExposedPort(6010), static { try { + /* + * We determine the current group and user using an env variable. This is set by the GitHub Actions runner. + * The user and group are used to set the user/group for the user in the docker container run by + * TestContainers for the Firebase Emulators. This way, the data exported by the Firebase Emulators + * can be read from the build. + */ var user = Optional .ofNullable(System.getenv("CURRENT_USER")) .map(Integer::valueOf); @@ -94,9 +100,6 @@ Emulator.EMULATOR_HUB, new ExposedPort(6010), writer.write("

Hello, Firebase Hosting!

"); } - /* - * We use user id = 991 & groupid = 999 by default, as these are the ids used by the gitlab runner. - */ EmulatorConfig config = new EmulatorConfig( new FirebaseEmulatorContainer.DockerConfig( "node:23-alpine", From f3c3518308f5acf5861ff1cb84dcc0cc2983f6cd Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 22:23:29 +0100 Subject: [PATCH 039/101] Formatting fix --- .../deployment/FirebaseEmulatorContainerIntegrationTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index 1f83de5b..aa0f891c 100644 --- a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -7,14 +7,12 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.util.Arrays; import java.util.Map; import java.util.Optional; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; From db28e3536aa5d25971bace40b39c7f4cf2ef1009 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 14 Nov 2024 22:31:56 +0100 Subject: [PATCH 040/101] Regenerated documentation --- .../quarkus-google-cloud-firebase.adoc | 34 +++++++++++++++++++ ...-google-cloud-firebase_quarkus.google.adoc | 34 +++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc index ca13cdb6..acad4cac 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc @@ -60,6 +60,40 @@ endif::add-copy-button-to-env-var[] |string |`node:23-alpine` +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-user]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-user[`quarkus.google.cloud.firebase.devservice.docker-user`]## + +[.description] +-- +Id of the docker user to run the firebase executable. This is needed in environments where Docker does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker automatically performs this mapping and the data written by the emulator can be read by the user running the build. This is not the case in a regular (non-Desktop) setup, this is not the case and you may need to set the user id and `docker-group()`. This option is often needed in CI environments. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-group]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-group[`quarkus.google.cloud.firebase.devservice.docker-group`]## + +[.description] +-- +Id of the group to which the `docker-user()` belongs. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-version]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-version[`quarkus.google.cloud.firebase.devservice.firebase-version`]## [.description] diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc index ca13cdb6..acad4cac 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc @@ -60,6 +60,40 @@ endif::add-copy-button-to-env-var[] |string |`node:23-alpine` +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-user]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-user[`quarkus.google.cloud.firebase.devservice.docker-user`]## + +[.description] +-- +Id of the docker user to run the firebase executable. This is needed in environments where Docker does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker automatically performs this mapping and the data written by the emulator can be read by the user running the build. This is not the case in a regular (non-Desktop) setup, this is not the case and you may need to set the user id and `docker-group()`. This option is often needed in CI environments. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-group]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-group[`quarkus.google.cloud.firebase.devservice.docker-group`]## + +[.description] +-- +Id of the group to which the `docker-user()` belongs. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-version]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-version[`quarkus.google.cloud.firebase.devservice.firebase-version`]## [.description] From 6d49dded88a3e1feda6753e205bf020863e37234 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 09:31:46 +0100 Subject: [PATCH 041/101] Update firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify javadoc Co-authored-by: Loïc Mathieu --- .../firebase/admin/runtime/FirebaseAuthConfig.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java index 89adc8b2..d6032f23 100644 --- a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java +++ b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java @@ -9,8 +9,6 @@ /** * Root configuration class for Google Cloud Firebase Auth setup. - * This interface provides a nested structure for configuration, including - * a separate group for the development service configuration. *

* This interface mostly provides access to validate whether the Firebase Auth * Emulator is running. From a9af6793d410315edad2e7000904d6059e71308d Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 09:37:22 +0100 Subject: [PATCH 042/101] Update firebase/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix language in readme Co-authored-by: Loïc Mathieu --- firebase/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase/README.md b/firebase/README.md index 369f0c96..d45ed50c 100644 --- a/firebase/README.md +++ b/firebase/README.md @@ -1,5 +1,5 @@ # Quarkus - Google Cloud Services - Firebase -This extension allows start a DevService for the Firebase Emulator Suite. +This extension provides a DevService for the Firebase. You can find the documentation in the [Firebase Quarkiverse documentation site](https://quarkiverse.github.io/quarkiverse-docs/quarkus-google-cloud-services/main/firebase.html). From 874bab4dec6cf575d2ad8b85b5f2e6bd17d87ec5 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:15:07 +0100 Subject: [PATCH 043/101] Added missing test scope --- firebase/deployment/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/firebase/deployment/pom.xml b/firebase/deployment/pom.xml index 71b8f7b8..d95f3520 100644 --- a/firebase/deployment/pom.xml +++ b/firebase/deployment/pom.xml @@ -91,6 +91,7 @@ quarkus-google-cloud-common-grpc and Quarkus includes the netty library --> com.google.cloud google-cloud-pubsub + test commons-logging From 96c2a304c4d267c8204cf6e6fd51c668c089b578 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:15:59 +0100 Subject: [PATCH 044/101] Removed obsolete properties --- firebase/runtime/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/firebase/runtime/pom.xml b/firebase/runtime/pom.xml index 969f6248..83a64e3b 100644 --- a/firebase/runtime/pom.xml +++ b/firebase/runtime/pom.xml @@ -12,11 +12,6 @@ Quarkus - Google Cloud Services - Firebase - Runtime Use Google Cloud Firebase - - 9.4.0 - 2.1 - - io.quarkiverse.googlecloudservices From f7c6cf3dd4bce96a1a57d303e501102a0cef7110 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:16:52 +0100 Subject: [PATCH 045/101] Update firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix comments Co-authored-by: Loïc Mathieu --- .../firebase/deployment/FirebaseDevServiceConfig.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index c70ba279..b63555eb 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -101,8 +101,8 @@ interface DevService { * Id of the docker user to run the firebase executable. This is needed in environments where Docker * does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker * automatically performs this mapping and the data written by the emulator can be read by the user - * running the build. This is not the case in a regular (non-Desktop) setup, this is not the case - * and you may need to set the user id and {@link #dockerGroup()}. This option is often needed in CI + * running the build. This is not the case in a regular (non-Desktop) setup, + * so you may need to set the user id and {@link #dockerGroup()}. This option is often needed in CI * environments. */ Optional dockerUser(); From 0c80a677d97ddf2e58aa24547a1dc860705244a9 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:17:56 +0100 Subject: [PATCH 046/101] Fix comment to match default --- .../firebase/deployment/FirebaseDevServiceConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index c70ba279..e55087a0 100644 --- a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -90,7 +90,7 @@ interface DevService { /** * Sets the Docker image name for the Google Cloud SDK. * This image is used to emulate the Pub/Sub service in the development environment. - * The default value is 'gcr.io/google.com/cloudsdktool/google-cloud-cli'. + * The default value is 'node:23-alpine'. *

* See also the documentation on Custom Docker images for more info about this image. */ From 9cbeb5a0ed6b1e0adaf8614332d3fc6597fb2e24 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:23:09 +0100 Subject: [PATCH 047/101] Renamed module to firebase-devservices --- bom/pom.xml | 4 ++-- {firebase => firebase-devservices}/deployment/pom.xml | 6 +++--- .../firebase/deployment/FirebaseBuildSteps.java | 0 .../firebase/deployment/FirebaseDevServiceConfig.java | 0 .../firebase/deployment/FirebaseDevServiceProcessor.java | 0 .../firebase/deployment/FirebaseEmulatorConfigBuilder.java | 0 .../firebase/deployment/FirebaseEmulatorContainer.java | 0 .../deployment/FirebaseEmulatorConfigBuilderTest.java | 0 .../FirebaseEmulatorContainerIntegrationTest.java | 0 {firebase => firebase-devservices}/pom.xml | 2 +- {firebase => firebase-devservices}/runtime/pom.xml | 4 ++-- pom.xml | 2 +- 12 files changed, 9 insertions(+), 9 deletions(-) rename {firebase => firebase-devservices}/deployment/pom.xml (95%) rename {firebase => firebase-devservices}/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseBuildSteps.java (100%) rename {firebase => firebase-devservices}/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java (100%) rename {firebase => firebase-devservices}/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java (100%) rename {firebase => firebase-devservices}/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java (100%) rename {firebase => firebase-devservices}/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java (100%) rename {firebase => firebase-devservices}/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java (100%) rename {firebase => firebase-devservices}/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java (100%) rename {firebase => firebase-devservices}/pom.xml (90%) rename {firebase => firebase-devservices}/runtime/pom.xml (93%) diff --git a/bom/pom.xml b/bom/pom.xml index efd07690..319b206c 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -146,12 +146,12 @@ io.quarkiverse.googlecloudservices - quarkus-google-cloud-firebase + quarkus-google-cloud-firebase-devservices ${project.version} io.quarkiverse.googlecloudservices - quarkus-google-cloud-firebase-deployment + quarkus-google-cloud-firebase-devservices-deployment ${project.version} diff --git a/firebase/deployment/pom.xml b/firebase-devservices/deployment/pom.xml similarity index 95% rename from firebase/deployment/pom.xml rename to firebase-devservices/deployment/pom.xml index d95f3520..d4a58f8d 100644 --- a/firebase/deployment/pom.xml +++ b/firebase-devservices/deployment/pom.xml @@ -2,13 +2,13 @@ io.quarkiverse.googlecloudservices - quarkus-google-cloud-firebase-parent + quarkus-google-cloud-firebase-devservices-parent 2.14.0-SNAPSHOT ../pom.xml 4.0.0 - quarkus-google-cloud-firebase-deployment + quarkus-google-cloud-firebase-devservices-deployment Quarkus - Google Cloud Services - Firebase - Deployment @@ -22,7 +22,7 @@ io.quarkiverse.googlecloudservices - quarkus-google-cloud-firebase + quarkus-google-cloud-firebase-devservices org.testcontainers diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseBuildSteps.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseBuildSteps.java similarity index 100% rename from firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseBuildSteps.java rename to firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseBuildSteps.java diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java similarity index 100% rename from firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java rename to firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java similarity index 100% rename from firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java rename to firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java similarity index 100% rename from firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java rename to firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java diff --git a/firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java similarity index 100% rename from firebase/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java rename to firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java similarity index 100% rename from firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java rename to firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java diff --git a/firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java similarity index 100% rename from firebase/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java rename to firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java diff --git a/firebase/pom.xml b/firebase-devservices/pom.xml similarity index 90% rename from firebase/pom.xml rename to firebase-devservices/pom.xml index c5b871e2..457a28c1 100644 --- a/firebase/pom.xml +++ b/firebase-devservices/pom.xml @@ -8,7 +8,7 @@ 4.0.0 - quarkus-google-cloud-firebase-parent + quarkus-google-cloud-firebase-devservices-parent Quarkus - Google Cloud Services - Firebase pom diff --git a/firebase/runtime/pom.xml b/firebase-devservices/runtime/pom.xml similarity index 93% rename from firebase/runtime/pom.xml rename to firebase-devservices/runtime/pom.xml index 83a64e3b..ffa92065 100644 --- a/firebase/runtime/pom.xml +++ b/firebase-devservices/runtime/pom.xml @@ -2,13 +2,13 @@ io.quarkiverse.googlecloudservices - quarkus-google-cloud-firebase-parent + quarkus-google-cloud-firebase-devservices-parent 2.14.0-SNAPSHOT ../pom.xml 4.0.0 - quarkus-google-cloud-firebase + quarkus-google-cloud-firebase-devservices Quarkus - Google Cloud Services - Firebase - Runtime Use Google Cloud Firebase diff --git a/pom.xml b/pom.xml index 6fa746be..3030868d 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ pubsub spanner storage - firebase + firebase-devservices firebase-admin firestore bigtable From 30281e11afced17ae1d38527e9d8c999e2cee23b Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:24:34 +0100 Subject: [PATCH 048/101] Renamed module to firebase-devservices --- firebase-admin/deployment/pom.xml | 4 ++-- firebase-admin/runtime/pom.xml | 2 +- integration-tests/firebase/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/firebase-admin/deployment/pom.xml b/firebase-admin/deployment/pom.xml index 9c0b5231..00764387 100644 --- a/firebase-admin/deployment/pom.xml +++ b/firebase-admin/deployment/pom.xml @@ -40,7 +40,7 @@ io.quarkiverse.googlecloudservices - quarkus-google-cloud-firebase-deployment + quarkus-google-cloud-firebase-devservices-deployment io.quarkiverse.googlecloudservices @@ -48,7 +48,7 @@ io.quarkiverse.googlecloudservices - quarkus-google-cloud-firebase + quarkus-google-cloud-firebase-devservices diff --git a/firebase-admin/runtime/pom.xml b/firebase-admin/runtime/pom.xml index 11a87119..a49e23ed 100644 --- a/firebase-admin/runtime/pom.xml +++ b/firebase-admin/runtime/pom.xml @@ -47,7 +47,7 @@ quarkus-google-cloud-common-grpc and Quarkus includes the netty library --> io.quarkiverse.googlecloudservices - quarkus-google-cloud-firebase + quarkus-google-cloud-firebase-devservices org.eclipse.microprofile.jwt diff --git a/integration-tests/firebase/pom.xml b/integration-tests/firebase/pom.xml index c0799bb1..0833face 100644 --- a/integration-tests/firebase/pom.xml +++ b/integration-tests/firebase/pom.xml @@ -24,7 +24,7 @@ io.quarkiverse.googlecloudservices - quarkus-google-cloud-firebase + quarkus-google-cloud-firebase-devservices io.quarkiverse.googlecloudservices From 461172d03e28d8b9ec9c54044987285a468f09a7 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:38:54 +0100 Subject: [PATCH 049/101] Moved files to new directory --- {firebase => firebase-devservices}/README.md | 0 .../runtime/src/main/resources/META-INF/quarkus-extension.yaml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {firebase => firebase-devservices}/README.md (100%) rename {firebase => firebase-devservices}/runtime/src/main/resources/META-INF/quarkus-extension.yaml (100%) diff --git a/firebase/README.md b/firebase-devservices/README.md similarity index 100% rename from firebase/README.md rename to firebase-devservices/README.md diff --git a/firebase/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/firebase-devservices/runtime/src/main/resources/META-INF/quarkus-extension.yaml similarity index 100% rename from firebase/runtime/src/main/resources/META-INF/quarkus-extension.yaml rename to firebase-devservices/runtime/src/main/resources/META-INF/quarkus-extension.yaml From c8d8b2dfe744a97de9d414f2804d60946e58d238 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:42:55 +0100 Subject: [PATCH 050/101] New name for firebase devservices, new doc files generated --- ...kus-google-cloud-firebase-devservices.adoc | 531 ++++++++++++++++++ ...d-firebase-devservices_quarkus.google.adoc | 531 ++++++++++++++++++ 2 files changed, 1062 insertions(+) create mode 100644 docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc create mode 100644 docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc new file mode 100644 index 00000000..ac5ea708 --- /dev/null +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc @@ -0,0 +1,531 @@ +[.configuration-legend] +icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime +[.configuration-reference.searchable, cols="80,.^10,.^10"] +|=== + +h|[.header-title]##Configuration property## +h|Type +h|Default + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-project-id]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-project-id[`quarkus.google.cloud.project-id`]## + +[.description] +-- +Google Cloud project ID. The project is required to be set if you use the Firebase Auth Dev service. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PROJECT_ID+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PROJECT_ID+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services[`quarkus.google.cloud.firebase.devservice.prefer-firebase-dev-services`]## + +[.description] +-- +Indicates to use the dev service for Firebase. The default value is true. This indicator is used to detect the Firebase DevService and disable the DevServices for extensions which conflict with the Firebase DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-image-name]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-image-name[`quarkus.google.cloud.firebase.devservice.image-name`]## + +[.description] +-- +Sets the Docker image name for the Google Cloud SDK. This image is used to emulate the Pub/Sub service in the development environment. The default value is 'node:23-alpine'. + +See also the documentation on Custom Docker images for more info about this image. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`node:23-alpine` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-user]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-user[`quarkus.google.cloud.firebase.devservice.docker-user`]## + +[.description] +-- +Id of the docker user to run the firebase executable. This is needed in environments where Docker does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker automatically performs this mapping and the data written by the emulator can be read by the user running the build. This is not the case in a regular (non-Desktop) setup, this is not the case and you may need to set the user id and `docker-group()`. This option is often needed in CI environments. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-group]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-group[`quarkus.google.cloud.firebase.devservice.docker-group`]## + +[.description] +-- +Id of the group to which the `docker-user()` belongs. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-firebase-version]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-firebase-version[`quarkus.google.cloud.firebase.devservice.firebase-version`]## + +[.description] +-- +The version of the firebase tools to use. Default is to use the latest available version. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`latest` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-token]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-token[`quarkus.google.cloud.firebase.devservice.token`]## + +[.description] +-- +The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This option is mandatory if you use firebase hosting. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-custom-firebase-json]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-custom-firebase-json[`quarkus.google.cloud.firebase.devservice.custom-firebase-json`]## + +[.description] +-- +Indicate to use a custom firebase.json file instead of the automatically generated one. The custom firebase.json file MUST include a setting of + +``` +"host" : "0.0.0.0" +``` + +to ensure the ports of the emulator are exposed correctly at the docker container level. + +See the section on Custom Firebase Json in the docs for more info. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-java-tool-options]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-java-tool-options[`quarkus.google.cloud.firebase.devservice.java-tool-options`]## + +[.description] +-- +Sets the JAVA tool options for emulators based on the Java runtime environment like -Xmx. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#specifying_java_options[here] + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-emulator-data]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-emulator-data[`quarkus.google.cloud.firebase.devservice.emulator-data`]## + +[.description] +-- +Allow to import and export data. Specify a path relative to the current working directory of the executable (for most unit tests, this is the root of the build directory) to be used for import and export of emulator data. The data will be written to a subdirectory called "emulator-data" of this directory. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data[here] + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-enabled[`quarkus.google.cloud.firebase.devservice.ui.enabled`]## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-emulator-port[`quarkus.google.cloud.firebase.devservice.ui.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-logging-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-logging-port[`quarkus.google.cloud.firebase.devservice.ui.logging-port`]## + +[.description] +-- +Port on which to expose the logging endpoint port. This is needed in case you want to view the logging via the Emulator UI. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-hub-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-hub-port[`quarkus.google.cloud.firebase.devservice.ui.hub-port`]## + +[.description] +-- +Port on which to expose the hub endpoint port. This is needed if you want to use the hub API of the Emulator UI. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-enabled[`quarkus.google.cloud.firebase.auth.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-emulator-port[`quarkus.google.cloud.firebase.auth.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-enabled[`quarkus.google.cloud.firebase.hosting.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-emulator-port[`quarkus.google.cloud.firebase.hosting.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-hosting-path]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-hosting-path[`quarkus.google.cloud.firebase.hosting.hosting-path`]## + +[.description] +-- +Path to the hosting files. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-enabled[`quarkus.google.cloud.database.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-emulator-port[`quarkus.google.cloud.database.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-enabled[`quarkus.google.cloud.firestore.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-emulator-port[`quarkus.google.cloud.firestore.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-websocket-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-websocket-port[`quarkus.google.cloud.firestore.devservice.websocket-port`]## + +[.description] +-- +Port on which to expose the websocket port. This is needed in case the Firestore Emulator UI needs is used. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-enabled[`quarkus.google.cloud.functions.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-emulator-port[`quarkus.google.cloud.functions.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-enabled[`quarkus.google.cloud.pubsub.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-emulator-port[`quarkus.google.cloud.pubsub.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-enabled[`quarkus.google.cloud.storage.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-emulator-port[`quarkus.google.cloud.storage.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +|=== + diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc new file mode 100644 index 00000000..ac5ea708 --- /dev/null +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc @@ -0,0 +1,531 @@ +[.configuration-legend] +icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime +[.configuration-reference.searchable, cols="80,.^10,.^10"] +|=== + +h|[.header-title]##Configuration property## +h|Type +h|Default + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-project-id]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-project-id[`quarkus.google.cloud.project-id`]## + +[.description] +-- +Google Cloud project ID. The project is required to be set if you use the Firebase Auth Dev service. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PROJECT_ID+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PROJECT_ID+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services[`quarkus.google.cloud.firebase.devservice.prefer-firebase-dev-services`]## + +[.description] +-- +Indicates to use the dev service for Firebase. The default value is true. This indicator is used to detect the Firebase DevService and disable the DevServices for extensions which conflict with the Firebase DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-image-name]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-image-name[`quarkus.google.cloud.firebase.devservice.image-name`]## + +[.description] +-- +Sets the Docker image name for the Google Cloud SDK. This image is used to emulate the Pub/Sub service in the development environment. The default value is 'node:23-alpine'. + +See also the documentation on Custom Docker images for more info about this image. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`node:23-alpine` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-user]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-user[`quarkus.google.cloud.firebase.devservice.docker-user`]## + +[.description] +-- +Id of the docker user to run the firebase executable. This is needed in environments where Docker does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker automatically performs this mapping and the data written by the emulator can be read by the user running the build. This is not the case in a regular (non-Desktop) setup, this is not the case and you may need to set the user id and `docker-group()`. This option is often needed in CI environments. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-group]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-group[`quarkus.google.cloud.firebase.devservice.docker-group`]## + +[.description] +-- +Id of the group to which the `docker-user()` belongs. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-firebase-version]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-firebase-version[`quarkus.google.cloud.firebase.devservice.firebase-version`]## + +[.description] +-- +The version of the firebase tools to use. Default is to use the latest available version. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`latest` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-token]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-token[`quarkus.google.cloud.firebase.devservice.token`]## + +[.description] +-- +The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This option is mandatory if you use firebase hosting. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-custom-firebase-json]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-custom-firebase-json[`quarkus.google.cloud.firebase.devservice.custom-firebase-json`]## + +[.description] +-- +Indicate to use a custom firebase.json file instead of the automatically generated one. The custom firebase.json file MUST include a setting of + +``` +"host" : "0.0.0.0" +``` + +to ensure the ports of the emulator are exposed correctly at the docker container level. + +See the section on Custom Firebase Json in the docs for more info. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-java-tool-options]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-java-tool-options[`quarkus.google.cloud.firebase.devservice.java-tool-options`]## + +[.description] +-- +Sets the JAVA tool options for emulators based on the Java runtime environment like -Xmx. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#specifying_java_options[here] + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-emulator-data]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-emulator-data[`quarkus.google.cloud.firebase.devservice.emulator-data`]## + +[.description] +-- +Allow to import and export data. Specify a path relative to the current working directory of the executable (for most unit tests, this is the root of the build directory) to be used for import and export of emulator data. The data will be written to a subdirectory called "emulator-data" of this directory. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data[here] + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-enabled[`quarkus.google.cloud.firebase.devservice.ui.enabled`]## + +[.description] +-- +Indicates whether the service should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-emulator-port[`quarkus.google.cloud.firebase.devservice.ui.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-logging-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-logging-port[`quarkus.google.cloud.firebase.devservice.ui.logging-port`]## + +[.description] +-- +Port on which to expose the logging endpoint port. This is needed in case you want to view the logging via the Emulator UI. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-hub-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-hub-port[`quarkus.google.cloud.firebase.devservice.ui.hub-port`]## + +[.description] +-- +Port on which to expose the hub endpoint port. This is needed if you want to use the hub API of the Emulator UI. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-enabled[`quarkus.google.cloud.firebase.auth.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-emulator-port[`quarkus.google.cloud.firebase.auth.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-enabled[`quarkus.google.cloud.firebase.hosting.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-emulator-port[`quarkus.google.cloud.firebase.hosting.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-hosting-path]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-hosting-path[`quarkus.google.cloud.firebase.hosting.hosting-path`]## + +[.description] +-- +Path to the hosting files. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-enabled[`quarkus.google.cloud.database.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-emulator-port[`quarkus.google.cloud.database.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-enabled[`quarkus.google.cloud.firestore.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-emulator-port[`quarkus.google.cloud.firestore.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-websocket-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-websocket-port[`quarkus.google.cloud.firestore.devservice.websocket-port`]## + +[.description] +-- +Port on which to expose the websocket port. This is needed in case the Firestore Emulator UI needs is used. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-enabled[`quarkus.google.cloud.functions.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-emulator-port[`quarkus.google.cloud.functions.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-enabled[`quarkus.google.cloud.pubsub.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-emulator-port[`quarkus.google.cloud.pubsub.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-enabled[`quarkus.google.cloud.storage.devservice.enabled`]## + +[.description] +-- +Indicates whether the DevService should be enabled or not. The default value is 'false'. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-emulator-port[`quarkus.google.cloud.storage.devservice.emulator-port`]## + +[.description] +-- +Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +| + +|=== + From 021d9cca76a3fe48846e2633e6082eb1d22103ee Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:43:50 +0100 Subject: [PATCH 051/101] New name for firebase devservices, new doc files generated --- docs/modules/ROOT/pages/firebase.adoc | 2 +- .../quarkus-google-cloud-firebase.adoc | 531 ------------------ ...-google-cloud-firebase_quarkus.google.adoc | 531 ------------------ 3 files changed, 1 insertion(+), 1063 deletions(-) delete mode 100644 docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc delete mode 100644 docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc diff --git a/docs/modules/ROOT/pages/firebase.adoc b/docs/modules/ROOT/pages/firebase.adoc index ff736604..8d88db53 100644 --- a/docs/modules/ROOT/pages/firebase.adoc +++ b/docs/modules/ROOT/pages/firebase.adoc @@ -95,4 +95,4 @@ When including this module, these DevServices will automatically be disabled, as == Configuration Reference -include::./includes/quarkus-google-cloud-firebase.adoc[] \ No newline at end of file +include::./includes/quarkus-google-cloud-firebase-devservices.adoc[] \ No newline at end of file diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc deleted file mode 100644 index acad4cac..00000000 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase.adoc +++ /dev/null @@ -1,531 +0,0 @@ -[.configuration-legend] -icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime -[.configuration-reference.searchable, cols="80,.^10,.^10"] -|=== - -h|[.header-title]##Configuration property## -h|Type -h|Default - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-project-id]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-project-id[`quarkus.google.cloud.project-id`]## - -[.description] --- -Google Cloud project ID. The project is required to be set if you use the Firebase Auth Dev service. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PROJECT_ID+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PROJECT_ID+++` -endif::add-copy-button-to-env-var[] --- -|string -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services[`quarkus.google.cloud.firebase.devservice.prefer-firebase-dev-services`]## - -[.description] --- -Indicates to use the dev service for Firebase. The default value is true. This indicator is used to detect the Firebase DevService and disable the DevServices for extensions which conflict with the Firebase DevService. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`true` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-image-name]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-image-name[`quarkus.google.cloud.firebase.devservice.image-name`]## - -[.description] --- -Sets the Docker image name for the Google Cloud SDK. This image is used to emulate the Pub/Sub service in the development environment. The default value is 'gcr.io/google.com/cloudsdktool/google-cloud-cli'. - -See also the documentation on Custom Docker images for more info about this image. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++` -endif::add-copy-button-to-env-var[] --- -|string -|`node:23-alpine` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-user]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-user[`quarkus.google.cloud.firebase.devservice.docker-user`]## - -[.description] --- -Id of the docker user to run the firebase executable. This is needed in environments where Docker does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker automatically performs this mapping and the data written by the emulator can be read by the user running the build. This is not the case in a regular (non-Desktop) setup, this is not the case and you may need to set the user id and `docker-group()`. This option is often needed in CI environments. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-group]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-group[`quarkus.google.cloud.firebase.devservice.docker-group`]## - -[.description] --- -Id of the group to which the `docker-user()` belongs. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-version]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-version[`quarkus.google.cloud.firebase.devservice.firebase-version`]## - -[.description] --- -The version of the firebase tools to use. Default is to use the latest available version. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++` -endif::add-copy-button-to-env-var[] --- -|string -|`latest` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-token]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-token[`quarkus.google.cloud.firebase.devservice.token`]## - -[.description] --- -The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This option is mandatory if you use firebase hosting. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++` -endif::add-copy-button-to-env-var[] --- -|string -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-custom-firebase-json]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-custom-firebase-json[`quarkus.google.cloud.firebase.devservice.custom-firebase-json`]## - -[.description] --- -Indicate to use a custom firebase.json file instead of the automatically generated one. The custom firebase.json file MUST include a setting of - -``` -"host" : "0.0.0.0" -``` - -to ensure the ports of the emulator are exposed correctly at the docker container level. - -See the section on Custom Firebase Json in the docs for more info. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++` -endif::add-copy-button-to-env-var[] --- -|string -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-java-tool-options]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-java-tool-options[`quarkus.google.cloud.firebase.devservice.java-tool-options`]## - -[.description] --- -Sets the JAVA tool options for emulators based on the Java runtime environment like -Xmx. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#specifying_java_options[here] - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++` -endif::add-copy-button-to-env-var[] --- -|string -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-emulator-data]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-emulator-data[`quarkus.google.cloud.firebase.devservice.emulator-data`]## - -[.description] --- -Allow to import and export data. Specify a path relative to the current working directory of the executable (for most unit tests, this is the root of the build directory) to be used for import and export of emulator data. The data will be written to a subdirectory called "emulator-data" of this directory. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data[here] - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++` -endif::add-copy-button-to-env-var[] --- -|string -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-enabled[`quarkus.google.cloud.firebase.devservice.ui.enabled`]## - -[.description] --- -Indicates whether the service should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`true` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-emulator-port[`quarkus.google.cloud.firebase.devservice.ui.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-logging-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-logging-port[`quarkus.google.cloud.firebase.devservice.ui.logging-port`]## - -[.description] --- -Port on which to expose the logging endpoint port. This is needed in case you want to view the logging via the Emulator UI. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-hub-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-hub-port[`quarkus.google.cloud.firebase.devservice.ui.hub-port`]## - -[.description] --- -Port on which to expose the hub endpoint port. This is needed if you want to use the hub API of the Emulator UI. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-enabled[`quarkus.google.cloud.firebase.auth.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-emulator-port[`quarkus.google.cloud.firebase.auth.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-enabled[`quarkus.google.cloud.firebase.hosting.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-emulator-port[`quarkus.google.cloud.firebase.hosting.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-hosting-path]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-hosting-path[`quarkus.google.cloud.firebase.hosting.hosting-path`]## - -[.description] --- -Path to the hosting files. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++` -endif::add-copy-button-to-env-var[] --- -|string -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-enabled[`quarkus.google.cloud.database.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-emulator-port[`quarkus.google.cloud.database.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-enabled[`quarkus.google.cloud.firestore.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-emulator-port[`quarkus.google.cloud.firestore.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-websocket-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-websocket-port[`quarkus.google.cloud.firestore.devservice.websocket-port`]## - -[.description] --- -Port on which to expose the websocket port. This is needed in case the Firestore Emulator UI needs is used. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-enabled[`quarkus.google.cloud.functions.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-emulator-port[`quarkus.google.cloud.functions.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-enabled[`quarkus.google.cloud.pubsub.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-emulator-port[`quarkus.google.cloud.pubsub.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-enabled[`quarkus.google.cloud.storage.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-emulator-port[`quarkus.google.cloud.storage.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -|=== - diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc deleted file mode 100644 index acad4cac..00000000 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase_quarkus.google.adoc +++ /dev/null @@ -1,531 +0,0 @@ -[.configuration-legend] -icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime -[.configuration-reference.searchable, cols="80,.^10,.^10"] -|=== - -h|[.header-title]##Configuration property## -h|Type -h|Default - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-project-id]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-project-id[`quarkus.google.cloud.project-id`]## - -[.description] --- -Google Cloud project ID. The project is required to be set if you use the Firebase Auth Dev service. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PROJECT_ID+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PROJECT_ID+++` -endif::add-copy-button-to-env-var[] --- -|string -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services[`quarkus.google.cloud.firebase.devservice.prefer-firebase-dev-services`]## - -[.description] --- -Indicates to use the dev service for Firebase. The default value is true. This indicator is used to detect the Firebase DevService and disable the DevServices for extensions which conflict with the Firebase DevService. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`true` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-image-name]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-image-name[`quarkus.google.cloud.firebase.devservice.image-name`]## - -[.description] --- -Sets the Docker image name for the Google Cloud SDK. This image is used to emulate the Pub/Sub service in the development environment. The default value is 'gcr.io/google.com/cloudsdktool/google-cloud-cli'. - -See also the documentation on Custom Docker images for more info about this image. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++` -endif::add-copy-button-to-env-var[] --- -|string -|`node:23-alpine` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-user]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-user[`quarkus.google.cloud.firebase.devservice.docker-user`]## - -[.description] --- -Id of the docker user to run the firebase executable. This is needed in environments where Docker does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker automatically performs this mapping and the data written by the emulator can be read by the user running the build. This is not the case in a regular (non-Desktop) setup, this is not the case and you may need to set the user id and `docker-group()`. This option is often needed in CI environments. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-group]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-docker-group[`quarkus.google.cloud.firebase.devservice.docker-group`]## - -[.description] --- -Id of the group to which the `docker-user()` belongs. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-version]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-firebase-version[`quarkus.google.cloud.firebase.devservice.firebase-version`]## - -[.description] --- -The version of the firebase tools to use. Default is to use the latest available version. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++` -endif::add-copy-button-to-env-var[] --- -|string -|`latest` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-token]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-token[`quarkus.google.cloud.firebase.devservice.token`]## - -[.description] --- -The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This option is mandatory if you use firebase hosting. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++` -endif::add-copy-button-to-env-var[] --- -|string -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-custom-firebase-json]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-custom-firebase-json[`quarkus.google.cloud.firebase.devservice.custom-firebase-json`]## - -[.description] --- -Indicate to use a custom firebase.json file instead of the automatically generated one. The custom firebase.json file MUST include a setting of - -``` -"host" : "0.0.0.0" -``` - -to ensure the ports of the emulator are exposed correctly at the docker container level. - -See the section on Custom Firebase Json in the docs for more info. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++` -endif::add-copy-button-to-env-var[] --- -|string -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-java-tool-options]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-java-tool-options[`quarkus.google.cloud.firebase.devservice.java-tool-options`]## - -[.description] --- -Sets the JAVA tool options for emulators based on the Java runtime environment like -Xmx. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#specifying_java_options[here] - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++` -endif::add-copy-button-to-env-var[] --- -|string -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-emulator-data]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-emulator-data[`quarkus.google.cloud.firebase.devservice.emulator-data`]## - -[.description] --- -Allow to import and export data. Specify a path relative to the current working directory of the executable (for most unit tests, this is the root of the build directory) to be used for import and export of emulator data. The data will be written to a subdirectory called "emulator-data" of this directory. See also link:https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data[here] - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++` -endif::add-copy-button-to-env-var[] --- -|string -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-enabled[`quarkus.google.cloud.firebase.devservice.ui.enabled`]## - -[.description] --- -Indicates whether the service should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`true` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-emulator-port[`quarkus.google.cloud.firebase.devservice.ui.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-logging-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-logging-port[`quarkus.google.cloud.firebase.devservice.ui.logging-port`]## - -[.description] --- -Port on which to expose the logging endpoint port. This is needed in case you want to view the logging via the Emulator UI. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-hub-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-devservice-ui-hub-port[`quarkus.google.cloud.firebase.devservice.ui.hub-port`]## - -[.description] --- -Port on which to expose the hub endpoint port. This is needed if you want to use the hub API of the Emulator UI. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-enabled[`quarkus.google.cloud.firebase.auth.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-auth-devservice-emulator-port[`quarkus.google.cloud.firebase.auth.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-enabled[`quarkus.google.cloud.firebase.hosting.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-devservice-emulator-port[`quarkus.google.cloud.firebase.hosting.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-hosting-path]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firebase-hosting-hosting-path[`quarkus.google.cloud.firebase.hosting.hosting-path`]## - -[.description] --- -Path to the hosting files. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++` -endif::add-copy-button-to-env-var[] --- -|string -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-enabled[`quarkus.google.cloud.database.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-database-devservice-emulator-port[`quarkus.google.cloud.database.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-enabled[`quarkus.google.cloud.firestore.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-emulator-port[`quarkus.google.cloud.firestore.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-websocket-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-firestore-devservice-websocket-port[`quarkus.google.cloud.firestore.devservice.websocket-port`]## - -[.description] --- -Port on which to expose the websocket port. This is needed in case the Firestore Emulator UI needs is used. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-enabled[`quarkus.google.cloud.functions.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-functions-devservice-emulator-port[`quarkus.google.cloud.functions.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-enabled[`quarkus.google.cloud.pubsub.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-pubsub-devservice-emulator-port[`quarkus.google.cloud.pubsub.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-enabled[`quarkus.google.cloud.storage.devservice.enabled`]## - -[.description] --- -Indicates whether the DevService should be enabled or not. The default value is 'false'. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++` -endif::add-copy-button-to-env-var[] --- -|boolean -|`false` - -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase_quarkus-google-cloud-storage-devservice-emulator-port[`quarkus.google.cloud.storage.devservice.emulator-port`]## - -[.description] --- -Specifies the emulatorPort on which the service should run in the development environment. The default is to expose the service on a random port. - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++` -endif::add-copy-button-to-env-var[] --- -|int -| - -|=== - From 83dea999a06f610e9bf3b60936c621d8060c5b91 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:44:00 +0100 Subject: [PATCH 052/101] Formatting fix --- .../firebase/deployment/FirebaseDevServiceConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index a958633f..27e21dff 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -101,7 +101,7 @@ interface DevService { * Id of the docker user to run the firebase executable. This is needed in environments where Docker * does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker * automatically performs this mapping and the data written by the emulator can be read by the user - * running the build. This is not the case in a regular (non-Desktop) setup, + * running the build. This is not the case in a regular (non-Desktop) setup, * so you may need to set the user id and {@link #dockerGroup()}. This option is often needed in CI * environments. */ From a3e8a0605018464189117e08578e4c5455d874a6 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 11:19:41 +0100 Subject: [PATCH 053/101] Docs regenerated --- .../includes/quarkus-google-cloud-firebase-devservices.adoc | 2 +- ...uarkus-google-cloud-firebase-devservices_quarkus.google.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc index ac5ea708..7436ad50 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc @@ -64,7 +64,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservic [.description] -- -Id of the docker user to run the firebase executable. This is needed in environments where Docker does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker automatically performs this mapping and the data written by the emulator can be read by the user running the build. This is not the case in a regular (non-Desktop) setup, this is not the case and you may need to set the user id and `docker-group()`. This option is often needed in CI environments. +Id of the docker user to run the firebase executable. This is needed in environments where Docker does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker automatically performs this mapping and the data written by the emulator can be read by the user running the build. This is not the case in a regular (non-Desktop) setup, so you may need to set the user id and `docker-group()`. This option is often needed in CI environments. ifdef::add-copy-button-to-env-var[] diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc index ac5ea708..7436ad50 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc @@ -64,7 +64,7 @@ a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservic [.description] -- -Id of the docker user to run the firebase executable. This is needed in environments where Docker does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker automatically performs this mapping and the data written by the emulator can be read by the user running the build. This is not the case in a regular (non-Desktop) setup, this is not the case and you may need to set the user id and `docker-group()`. This option is often needed in CI environments. +Id of the docker user to run the firebase executable. This is needed in environments where Docker does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker automatically performs this mapping and the data written by the emulator can be read by the user running the build. This is not the case in a regular (non-Desktop) setup, so you may need to set the user id and `docker-group()`. This option is often needed in CI environments. ifdef::add-copy-button-to-env-var[] From 79dd652c4bec6f482e5eddd1f2d5e929a5f7d884 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 15 Nov 2024 11:11:44 +0100 Subject: [PATCH 054/101] Added firebase schema --- .../src/main/schema/firebase-config.json | 2758 +++++++++++++++++ 1 file changed, 2758 insertions(+) create mode 100644 firebase/deployment/src/main/schema/firebase-config.json diff --git a/firebase/deployment/src/main/schema/firebase-config.json b/firebase/deployment/src/main/schema/firebase-config.json new file mode 100644 index 00000000..6e39fa99 --- /dev/null +++ b/firebase/deployment/src/main/schema/firebase-config.json @@ -0,0 +1,2758 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "definitions": { + "ExtensionsConfig": { + "additionalProperties": false, + "type": "object" + }, + "FrameworksBackendOptions": { + "additionalProperties": false, + "properties": { + "concurrency": { + "description": "Number of requests a function can serve at once.", + "type": "number" + }, + "cors": { + "description": "If true, allows CORS on requests to this function.\nIf this is a `string` or `RegExp`, allows requests from domains that match the provided value.\nIf this is an `Array`, allows requests from domains matching at least one entry of the array.\nDefaults to true for {@link https.CallableFunction} and false otherwise.", + "type": [ + "string", + "boolean" + ] + }, + "cpu": { + "anyOf": [ + { + "enum": [ + "gcf_gen1" + ], + "type": "string" + }, + { + "type": "number" + } + ], + "description": "Fractional number of CPUs to allocate to a function." + }, + "enforceAppCheck": { + "description": "Determines whether Firebase AppCheck is enforced. Defaults to false.", + "type": "boolean" + }, + "ingressSettings": { + "description": "Ingress settings which control where this function can be called from.", + "enum": [ + "ALLOW_ALL", + "ALLOW_INTERNAL_AND_GCLB", + "ALLOW_INTERNAL_ONLY" + ], + "type": "string" + }, + "invoker": { + "description": "Invoker to set access control on https functions.", + "enum": [ + "public" + ], + "type": "string" + }, + "labels": { + "$ref": "#/definitions/Record", + "description": "User labels to set on the function." + }, + "maxInstances": { + "description": "Max number of instances to be running in parallel.", + "type": "number" + }, + "memory": { + "description": "Amount of memory to allocate to a function.", + "enum": [ + "128MiB", + "16GiB", + "1GiB", + "256MiB", + "2GiB", + "32GiB", + "4GiB", + "512MiB", + "8GiB" + ], + "type": "string" + }, + "minInstances": { + "description": "Min number of actual instances to be running at a given time.", + "type": "number" + }, + "omit": { + "description": "If true, do not deploy or emulate this function.", + "type": "boolean" + }, + "preserveExternalChanges": { + "description": "Controls whether function configuration modified outside of function source is preserved. Defaults to false.", + "type": "boolean" + }, + "region": { + "description": "HTTP functions can override global options and can specify multiple regions to deploy to.", + "type": "string" + }, + "secrets": { + "items": { + "type": "string" + }, + "type": "array" + }, + "serviceAccount": { + "description": "Specific service account for the function to run as.", + "type": "string" + }, + "timeoutSeconds": { + "description": "Timeout for the function in seconds, possible values are 0 to 540.\nHTTPS functions can specify a higher timeout.", + "type": "number" + }, + "vpcConnector": { + "description": "Connect cloud function to specified VPC connector.", + "type": "string" + }, + "vpcConnectorEgressSettings": { + "description": "Egress settings for VPC connector.", + "enum": [ + "ALL_TRAFFIC", + "PRIVATE_RANGES_ONLY" + ], + "type": "string" + } + }, + "type": "object" + }, + "Record": { + "additionalProperties": false, + "type": "object" + } + }, + "properties": { + "$schema": { + "format": "uri", + "type": "string" + }, + "database": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "rules": { + "type": "string" + } + }, + "required": [ + "rules" + ], + "type": "object" + }, + { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "instance": { + "type": "string" + }, + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "rules": { + "type": "string" + }, + "target": { + "type": "string" + } + }, + "required": [ + "instance", + "rules" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "instance": { + "type": "string" + }, + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "rules": { + "type": "string" + }, + "target": { + "type": "string" + } + }, + "required": [ + "rules", + "target" + ], + "type": "object" + } + ] + }, + "type": "array" + } + ] + }, + "dataconnect": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "source": { + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "source": { + "type": "string" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "type": "array" + } + ] + }, + "emulators": { + "additionalProperties": false, + "properties": { + "apphosting": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + }, + "startCommandOverride": { + "type": "string" + } + }, + "type": "object" + }, + "auth": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + } + }, + "type": "object" + }, + "database": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + } + }, + "type": "object" + }, + "dataconnect": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + }, + "postgresHost": { + "type": "string" + }, + "postgresPort": { + "type": "number" + } + }, + "type": "object" + }, + "eventarc": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + } + }, + "type": "object" + }, + "extensions": { + "properties": { + }, + "type": "object" + }, + "firestore": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + }, + "websocketPort": { + "type": "number" + } + }, + "type": "object" + }, + "functions": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + } + }, + "type": "object" + }, + "hosting": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + } + }, + "type": "object" + }, + "hub": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + } + }, + "type": "object" + }, + "logging": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + } + }, + "type": "object" + }, + "pubsub": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + } + }, + "type": "object" + }, + "singleProjectMode": { + "type": "boolean" + }, + "storage": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + } + }, + "type": "object" + }, + "tasks": { + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "number" + } + }, + "type": "object" + }, + "ui": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "host": { + "type": "string" + }, + "port": { + "type": [ + "string", + "number" + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "extensions": { + "$ref": "#/definitions/ExtensionsConfig" + }, + "firestore": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "database": { + "type": "string" + }, + "indexes": { + "type": "string" + }, + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "rules": { + "type": "string" + } + }, + "type": "object" + }, + { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "database": { + "type": "string" + }, + "indexes": { + "type": "string" + }, + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "rules": { + "type": "string" + }, + "target": { + "type": "string" + } + }, + "required": [ + "target" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "database": { + "type": "string" + }, + "indexes": { + "type": "string" + }, + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "rules": { + "type": "string" + }, + "target": { + "type": "string" + } + }, + "required": [ + "database" + ], + "type": "object" + } + ] + }, + "type": "array" + } + ] + }, + "functions": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "codebase": { + "type": "string" + }, + "ignore": { + "items": { + "type": "string" + }, + "type": "array" + }, + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "runtime": { + "enum": [ + "nodejs10", + "nodejs12", + "nodejs14", + "nodejs16", + "nodejs18", + "nodejs20", + "nodejs22", + "nodejs6", + "nodejs8", + "python310", + "python311", + "python312" + ], + "type": "string" + }, + "source": { + "type": "string" + } + }, + "type": "object" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "codebase": { + "type": "string" + }, + "ignore": { + "items": { + "type": "string" + }, + "type": "array" + }, + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "runtime": { + "enum": [ + "nodejs10", + "nodejs12", + "nodejs14", + "nodejs16", + "nodejs18", + "nodejs20", + "nodejs22", + "nodejs6", + "nodejs8", + "python310", + "python311", + "python312" + ], + "type": "string" + }, + "source": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + ] + }, + "hosting": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "appAssociation": { + "enum": [ + "AUTO", + "NONE" + ], + "type": "string" + }, + "cleanUrls": { + "type": "boolean" + }, + "frameworksBackend": { + "$ref": "#/definitions/FrameworksBackendOptions" + }, + "headers": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "glob": { + "type": "string" + }, + "headers": { + "items": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "glob", + "headers" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "headers": { + "items": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "type": "string" + } + }, + "required": [ + "headers", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "headers": { + "items": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "regex": { + "type": "string" + } + }, + "required": [ + "headers", + "regex" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "i18n": { + "additionalProperties": false, + "properties": { + "root": { + "type": "string" + } + }, + "required": [ + "root" + ], + "type": "object" + }, + "ignore": { + "items": { + "type": "string" + }, + "type": "array" + }, + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "public": { + "type": "string" + }, + "redirects": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "glob": { + "type": "string" + }, + "type": { + "type": "number" + } + }, + "required": [ + "destination", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "source": { + "type": "string" + }, + "type": { + "type": "number" + } + }, + "required": [ + "destination", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "regex": { + "type": "string" + }, + "type": { + "type": "number" + } + }, + "required": [ + "destination", + "regex" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "rewrites": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "glob": { + "type": "string" + } + }, + "required": [ + "destination", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "type": "string" + }, + "glob": { + "type": "string" + }, + "region": { + "type": "string" + } + }, + "required": [ + "function", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "additionalProperties": false, + "properties": { + "functionId": { + "type": "string" + }, + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + } + }, + "required": [ + "functionId" + ], + "type": "object" + }, + "glob": { + "type": "string" + } + }, + "required": [ + "function", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "glob": { + "type": "string" + }, + "run": { + "additionalProperties": false, + "properties": { + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + }, + "serviceId": { + "type": "string" + } + }, + "required": [ + "serviceId" + ], + "type": "object" + } + }, + "required": [ + "glob", + "run" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "dynamicLinks": { + "type": "boolean" + }, + "glob": { + "type": "string" + } + }, + "required": [ + "dynamicLinks", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "source": { + "type": "string" + } + }, + "required": [ + "destination", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "type": "string" + }, + "region": { + "type": "string" + }, + "source": { + "type": "string" + } + }, + "required": [ + "function", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "additionalProperties": false, + "properties": { + "functionId": { + "type": "string" + }, + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + } + }, + "required": [ + "functionId" + ], + "type": "object" + }, + "source": { + "type": "string" + } + }, + "required": [ + "function", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "run": { + "additionalProperties": false, + "properties": { + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + }, + "serviceId": { + "type": "string" + } + }, + "required": [ + "serviceId" + ], + "type": "object" + }, + "source": { + "type": "string" + } + }, + "required": [ + "run", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "dynamicLinks": { + "type": "boolean" + }, + "source": { + "type": "string" + } + }, + "required": [ + "dynamicLinks", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "regex": { + "type": "string" + } + }, + "required": [ + "destination", + "regex" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "type": "string" + }, + "regex": { + "type": "string" + }, + "region": { + "type": "string" + } + }, + "required": [ + "function", + "regex" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "additionalProperties": false, + "properties": { + "functionId": { + "type": "string" + }, + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + } + }, + "required": [ + "functionId" + ], + "type": "object" + }, + "regex": { + "type": "string" + } + }, + "required": [ + "function", + "regex" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "regex": { + "type": "string" + }, + "run": { + "additionalProperties": false, + "properties": { + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + }, + "serviceId": { + "type": "string" + } + }, + "required": [ + "serviceId" + ], + "type": "object" + } + }, + "required": [ + "regex", + "run" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "dynamicLinks": { + "type": "boolean" + }, + "regex": { + "type": "string" + } + }, + "required": [ + "dynamicLinks", + "regex" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "site": { + "type": "string" + }, + "source": { + "type": "string" + }, + "target": { + "type": "string" + }, + "trailingSlash": { + "type": "boolean" + } + }, + "type": "object" + }, + { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "appAssociation": { + "enum": [ + "AUTO", + "NONE" + ], + "type": "string" + }, + "cleanUrls": { + "type": "boolean" + }, + "frameworksBackend": { + "$ref": "#/definitions/FrameworksBackendOptions" + }, + "headers": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "glob": { + "type": "string" + }, + "headers": { + "items": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "glob", + "headers" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "headers": { + "items": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "type": "string" + } + }, + "required": [ + "headers", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "headers": { + "items": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "regex": { + "type": "string" + } + }, + "required": [ + "headers", + "regex" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "i18n": { + "additionalProperties": false, + "properties": { + "root": { + "type": "string" + } + }, + "required": [ + "root" + ], + "type": "object" + }, + "ignore": { + "items": { + "type": "string" + }, + "type": "array" + }, + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "public": { + "type": "string" + }, + "redirects": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "glob": { + "type": "string" + }, + "type": { + "type": "number" + } + }, + "required": [ + "destination", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "source": { + "type": "string" + }, + "type": { + "type": "number" + } + }, + "required": [ + "destination", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "regex": { + "type": "string" + }, + "type": { + "type": "number" + } + }, + "required": [ + "destination", + "regex" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "rewrites": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "glob": { + "type": "string" + } + }, + "required": [ + "destination", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "type": "string" + }, + "glob": { + "type": "string" + }, + "region": { + "type": "string" + } + }, + "required": [ + "function", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "additionalProperties": false, + "properties": { + "functionId": { + "type": "string" + }, + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + } + }, + "required": [ + "functionId" + ], + "type": "object" + }, + "glob": { + "type": "string" + } + }, + "required": [ + "function", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "glob": { + "type": "string" + }, + "run": { + "additionalProperties": false, + "properties": { + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + }, + "serviceId": { + "type": "string" + } + }, + "required": [ + "serviceId" + ], + "type": "object" + } + }, + "required": [ + "glob", + "run" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "dynamicLinks": { + "type": "boolean" + }, + "glob": { + "type": "string" + } + }, + "required": [ + "dynamicLinks", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "source": { + "type": "string" + } + }, + "required": [ + "destination", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "type": "string" + }, + "region": { + "type": "string" + }, + "source": { + "type": "string" + } + }, + "required": [ + "function", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "additionalProperties": false, + "properties": { + "functionId": { + "type": "string" + }, + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + } + }, + "required": [ + "functionId" + ], + "type": "object" + }, + "source": { + "type": "string" + } + }, + "required": [ + "function", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "run": { + "additionalProperties": false, + "properties": { + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + }, + "serviceId": { + "type": "string" + } + }, + "required": [ + "serviceId" + ], + "type": "object" + }, + "source": { + "type": "string" + } + }, + "required": [ + "run", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "dynamicLinks": { + "type": "boolean" + }, + "source": { + "type": "string" + } + }, + "required": [ + "dynamicLinks", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "regex": { + "type": "string" + } + }, + "required": [ + "destination", + "regex" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "type": "string" + }, + "regex": { + "type": "string" + }, + "region": { + "type": "string" + } + }, + "required": [ + "function", + "regex" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "additionalProperties": false, + "properties": { + "functionId": { + "type": "string" + }, + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + } + }, + "required": [ + "functionId" + ], + "type": "object" + }, + "regex": { + "type": "string" + } + }, + "required": [ + "function", + "regex" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "regex": { + "type": "string" + }, + "run": { + "additionalProperties": false, + "properties": { + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + }, + "serviceId": { + "type": "string" + } + }, + "required": [ + "serviceId" + ], + "type": "object" + } + }, + "required": [ + "regex", + "run" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "dynamicLinks": { + "type": "boolean" + }, + "regex": { + "type": "string" + } + }, + "required": [ + "dynamicLinks", + "regex" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "site": { + "type": "string" + }, + "source": { + "type": "string" + }, + "target": { + "type": "string" + }, + "trailingSlash": { + "type": "boolean" + } + }, + "required": [ + "target" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "appAssociation": { + "enum": [ + "AUTO", + "NONE" + ], + "type": "string" + }, + "cleanUrls": { + "type": "boolean" + }, + "frameworksBackend": { + "$ref": "#/definitions/FrameworksBackendOptions" + }, + "headers": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "glob": { + "type": "string" + }, + "headers": { + "items": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "glob", + "headers" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "headers": { + "items": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "type": "string" + } + }, + "required": [ + "headers", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "headers": { + "items": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "regex": { + "type": "string" + } + }, + "required": [ + "headers", + "regex" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "i18n": { + "additionalProperties": false, + "properties": { + "root": { + "type": "string" + } + }, + "required": [ + "root" + ], + "type": "object" + }, + "ignore": { + "items": { + "type": "string" + }, + "type": "array" + }, + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "public": { + "type": "string" + }, + "redirects": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "glob": { + "type": "string" + }, + "type": { + "type": "number" + } + }, + "required": [ + "destination", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "source": { + "type": "string" + }, + "type": { + "type": "number" + } + }, + "required": [ + "destination", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "regex": { + "type": "string" + }, + "type": { + "type": "number" + } + }, + "required": [ + "destination", + "regex" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "rewrites": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "glob": { + "type": "string" + } + }, + "required": [ + "destination", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "type": "string" + }, + "glob": { + "type": "string" + }, + "region": { + "type": "string" + } + }, + "required": [ + "function", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "additionalProperties": false, + "properties": { + "functionId": { + "type": "string" + }, + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + } + }, + "required": [ + "functionId" + ], + "type": "object" + }, + "glob": { + "type": "string" + } + }, + "required": [ + "function", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "glob": { + "type": "string" + }, + "run": { + "additionalProperties": false, + "properties": { + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + }, + "serviceId": { + "type": "string" + } + }, + "required": [ + "serviceId" + ], + "type": "object" + } + }, + "required": [ + "glob", + "run" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "dynamicLinks": { + "type": "boolean" + }, + "glob": { + "type": "string" + } + }, + "required": [ + "dynamicLinks", + "glob" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "source": { + "type": "string" + } + }, + "required": [ + "destination", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "type": "string" + }, + "region": { + "type": "string" + }, + "source": { + "type": "string" + } + }, + "required": [ + "function", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "additionalProperties": false, + "properties": { + "functionId": { + "type": "string" + }, + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + } + }, + "required": [ + "functionId" + ], + "type": "object" + }, + "source": { + "type": "string" + } + }, + "required": [ + "function", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "run": { + "additionalProperties": false, + "properties": { + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + }, + "serviceId": { + "type": "string" + } + }, + "required": [ + "serviceId" + ], + "type": "object" + }, + "source": { + "type": "string" + } + }, + "required": [ + "run", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "dynamicLinks": { + "type": "boolean" + }, + "source": { + "type": "string" + } + }, + "required": [ + "dynamicLinks", + "source" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destination": { + "type": "string" + }, + "regex": { + "type": "string" + } + }, + "required": [ + "destination", + "regex" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "type": "string" + }, + "regex": { + "type": "string" + }, + "region": { + "type": "string" + } + }, + "required": [ + "function", + "regex" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "function": { + "additionalProperties": false, + "properties": { + "functionId": { + "type": "string" + }, + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + } + }, + "required": [ + "functionId" + ], + "type": "object" + }, + "regex": { + "type": "string" + } + }, + "required": [ + "function", + "regex" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "regex": { + "type": "string" + }, + "run": { + "additionalProperties": false, + "properties": { + "pinTag": { + "type": "boolean" + }, + "region": { + "type": "string" + }, + "serviceId": { + "type": "string" + } + }, + "required": [ + "serviceId" + ], + "type": "object" + } + }, + "required": [ + "regex", + "run" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "dynamicLinks": { + "type": "boolean" + }, + "regex": { + "type": "string" + } + }, + "required": [ + "dynamicLinks", + "regex" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "site": { + "type": "string" + }, + "source": { + "type": "string" + }, + "target": { + "type": "string" + }, + "trailingSlash": { + "type": "boolean" + } + }, + "required": [ + "site" + ], + "type": "object" + } + ] + }, + "type": "array" + } + ] + }, + "remoteconfig": { + "additionalProperties": false, + "properties": { + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "template": { + "type": "string" + } + }, + "required": [ + "template" + ], + "type": "object" + }, + "storage": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "rules": { + "type": "string" + }, + "target": { + "type": "string" + } + }, + "required": [ + "rules" + ], + "type": "object" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "bucket": { + "type": "string" + }, + "postdeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "predeploy": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "rules": { + "type": "string" + }, + "target": { + "type": "string" + } + }, + "required": [ + "bucket", + "rules" + ], + "type": "object" + }, + "type": "array" + } + ] + } + }, + "type": "object" +} From b45041e787cdc28e04696a6a64af388454b3cea3 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 15 Nov 2024 14:57:53 +0100 Subject: [PATCH 055/101] Changed schema ports number -> integer --- .../src/main/schema/firebase-config.json | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/firebase/deployment/src/main/schema/firebase-config.json b/firebase/deployment/src/main/schema/firebase-config.json index 6e39fa99..c851ecd4 100644 --- a/firebase/deployment/src/main/schema/firebase-config.json +++ b/firebase/deployment/src/main/schema/firebase-config.json @@ -364,7 +364,7 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" }, "startCommandOverride": { "type": "string" @@ -379,7 +379,7 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" } }, "type": "object" @@ -391,7 +391,7 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" } }, "type": "object" @@ -403,13 +403,13 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" }, "postgresHost": { "type": "string" }, "postgresPort": { - "type": "number" + "type": "integer" } }, "type": "object" @@ -421,7 +421,7 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" } }, "type": "object" @@ -438,10 +438,10 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" }, "websocketPort": { - "type": "number" + "type": "integer" } }, "type": "object" @@ -453,7 +453,7 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" } }, "type": "object" @@ -465,7 +465,7 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" } }, "type": "object" @@ -477,7 +477,7 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" } }, "type": "object" @@ -489,7 +489,7 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" } }, "type": "object" @@ -501,7 +501,7 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" } }, "type": "object" @@ -516,7 +516,7 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" } }, "type": "object" @@ -528,7 +528,7 @@ "type": "string" }, "port": { - "type": "number" + "type": "integer" } }, "type": "object" @@ -545,7 +545,7 @@ "port": { "type": [ "string", - "number" + "integer" ] } }, From cb826d6d83c6d9cf4eb3c94b77f3f75a062debda Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 15 Nov 2024 11:11:44 +0100 Subject: [PATCH 056/101] Merge fixes --- firebase-devservices/deployment/pom.xml | 19 ++ .../FirebaseEmulatorContainer.java | 190 +++++++++++++----- .../testcontainers/FirebaseJsonBuilder.java | 168 ++++++++++++++++ .../src/main/schema/firebase-config.json | 0 4 files changed, 325 insertions(+), 52 deletions(-) rename firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/{ => testcontainers}/FirebaseEmulatorContainer.java (70%) create mode 100644 firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java rename {firebase => firebase-devservices}/deployment/src/main/schema/firebase-config.json (100%) diff --git a/firebase-devservices/deployment/pom.xml b/firebase-devservices/deployment/pom.xml index d4a58f8d..f065ab42 100644 --- a/firebase-devservices/deployment/pom.xml +++ b/firebase-devservices/deployment/pom.xml @@ -133,6 +133,25 @@ quarkus-google-cloud-common-grpc and Quarkus includes the netty library --> + + org.jsonschema2pojo + jsonschema2pojo-maven-plugin + 1.2.2 + + ${basedir}/src/main/schema + io.quarkiverse.googlecloudservices.firebase.deployment.firebase.json + jackson2 + true + + + + + + generate + + + + diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java similarity index 70% rename from firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java rename to firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java index af21690b..5623ebaa 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainer.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java @@ -1,5 +1,6 @@ -package io.quarkiverse.googlecloudservices.firebase.deployment; +package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; +import java.io.IOException; import java.nio.file.Path; import java.util.*; import java.util.stream.Collectors; @@ -112,9 +113,9 @@ public enum Emulator { "pubsub", "pubsub"); - final int internalPort; - final String configProperty; - final String emulatorName; + public final int internalPort; + public final String configProperty; + public final String emulatorName; Emulator(int internalPort, String configProperty, String onlyArgument) { this.internalPort = internalPort; @@ -149,6 +150,35 @@ public record DockerConfig( Optional groupId) { } + /** + * Firebase hosting configuration + * + * @param hostingContentDir The path to the directory containing the hosting content + */ + public record HostingConfig( + Optional hostingContentDir) { + } + + /** + * Cloud storage configuration + * + * @param rulesFile Cloud storage rules file + */ + public record StorageConfig( + Optional rulesFile) { + } + + /** + * Firestore configuration + * + * @param rulesFile The rules file + * @param indexesFile The indexes file + */ + public record FirestoreConfig( + Optional rulesFile, + Optional indexesFile) { + } + /** * Describes the Firebase emulator configuration. * @@ -159,7 +189,10 @@ public record DockerConfig( * @param customFirebaseJson The path to a custom firebase * @param javaToolOptions The options to pass to the java based emulators * @param emulatorData The path to the directory where to store the emulator data - * @param hostingContentDir The path to the directory containing the hosting content + * @param hostingConfig The firebase hosting configuration + * @param storageConfig The storage configuration + * @param firestoreConfig The firestore configuration + * @param services The exposed services configuration */ public record EmulatorConfig( DockerConfig dockerConfig, @@ -169,7 +202,9 @@ public record EmulatorConfig( Optional customFirebaseJson, Optional javaToolOptions, Optional emulatorData, - Optional hostingContentDir, + HostingConfig hostingConfig, + StorageConfig storageConfig, + FirestoreConfig firestoreConfig, Map services) { } @@ -189,7 +224,7 @@ public FirebaseEmulatorContainer(EmulatorConfig firebaseConfig) { this.withFileSystemBind(path.toString(), EMULATOR_DATA_PATH, BindMode.READ_WRITE); }); - firebaseConfig.hostingContentDir().ifPresent(hostingPath -> { + firebaseConfig.hostingConfig().hostingContentDir().ifPresent(hostingPath -> { // Mount volume for static hosting content this.withFileSystemBind(hostingPath.toString(), FIREBASE_HOSTING_PATH, BindMode.READ_ONLY); }); @@ -230,6 +265,8 @@ public ImageFromDockerfile build() { this.setupUserAndGroup(); this.downloadEmulators(); this.addFirebaseJson(); + this.includeFirestoreFiles(); + this.includeStorageFiles(); this.setupDataImportExport(); this.setupHosting(); this.runExecutable(); @@ -324,61 +361,112 @@ private void includeCustomFirebaseJson(Path customFilePath) { customFilePath); } - private void generateFirebaseJson() { - StringBuilder firebaseJson = new StringBuilder(); + private void includeFirestoreFiles() { + firebaseConfig.firestoreConfig.rulesFile.ifPresent(rulesFile -> { + this.dockerBuilder.add("firestore.rules", FIREBASE_ROOT + "/firestore.rules"); + this.result.withFileFromPath("firestore.rules", rulesFile); + }); - firebaseJson.append("{\n"); - firebaseJson.append("\t\"emulators\": {\n"); + firebaseConfig.firestoreConfig.indexesFile.ifPresent(indexesFile -> { + this.dockerBuilder.add("firestore.indexes.json", FIREBASE_ROOT + "/firestore.indexes.json"); + this.result.withFileFromPath("firestore.indexes.json", indexesFile); + }); + } - var emulatorsJson = this.devServices - .entrySet() - .stream() - .filter(service -> service.getKey().configProperty != null) - .map((service -> { - var emulator = service.getKey(); - - var port = Optional.ofNullable(service.getValue().fixedPort()) - .orElse(emulator.internalPort); - - String additionalConfig = ""; - if (emulator.equals(Emulator.CLOUD_FIRESTORE)) { - var wsService = this.devServices.get(Emulator.CLOUD_FIRESTORE_WS); - if (wsService != null) { - var wsPort = Optional.ofNullable(wsService.fixedPort) - .orElse(Emulator.CLOUD_FIRESTORE.internalPort); - additionalConfig = "\t\t\t\"websocketPort\": " + wsPort + ",\n"; - } - } - - return "\t\t\"" + emulator.configProperty + "\": {\n" + - "\t\t\t\"port\": " + port + ",\n" + - additionalConfig + - "\t\t\t\"host\": \"0.0.0.0\"\n" + - "\t\t}"; - })) - .collect(Collectors.joining(",\n")); - firebaseJson.append(emulatorsJson).append("\n"); - firebaseJson.append("\t}\n"); - - if (isEmulatorEnabled(Emulator.CLOUD_FIRESTORE)) { - var firestoreJson = ",\"firestore\": {}\n"; - firebaseJson.append(firestoreJson); + private void includeStorageFiles() { + firebaseConfig.storageConfig.rulesFile.ifPresent(rulesFile -> { + this.dockerBuilder.add("storage.rules", FIREBASE_ROOT + "/storage.rules"); + this.result.withFileFromPath("storage.rules", rulesFile); + }); + } + + private void generateFirebaseJson() { + var firebaseJsonBuilder = new FirebaseJsonBuilder(this.firebaseConfig); + String firebaseJson = null; + try { + firebaseJson = firebaseJsonBuilder.buildFirebaseConfig(); + } catch (IOException e) { + throw new IllegalStateException("Failed to generate firebase.json file", e); } - firebaseJson.append("}\n"); + // StringBuilder firebaseJson = new StringBuilder(); + // + // firebaseJson.append("{\n"); + // firebaseJson.append("\t\"emulators\": {\n"); + // + // var emulatorsJson = this.devServices + // .entrySet() + // .stream() + // .filter(service -> service.getKey().configProperty != null) + // .map((service -> { + // var emulator = service.getKey(); + // + // var port = Optional.ofNullable(service.getValue().fixedPort()) + // .orElse(emulator.internalPort); + // + // String additionalConfig = ""; + // if (emulator.equals(Emulator.CLOUD_FIRESTORE)) { + // var wsService = this.devServices.get(Emulator.CLOUD_FIRESTORE_WS); + // if (wsService != null) { + // var wsPort = Optional.ofNullable(wsService.fixedPort) + // .orElse(Emulator.CLOUD_FIRESTORE.internalPort); + // additionalConfig = "\t\t\t\"websocketPort\": " + wsPort + ",\n"; + // } + // } + // + // return "\t\t\"" + emulator.configProperty + "\": {\n" + + // "\t\t\t\"port\": " + port + ",\n" + + // additionalConfig + + // "\t\t\t\"host\": \"0.0.0.0\"\n" + + // "\t\t}"; + // })) + // .collect(Collectors.joining(",\n")); + // firebaseJson.append(emulatorsJson).append("\n"); + // firebaseJson.append("\t}\n"); + // + // if (isEmulatorEnabled(Emulator.CLOUD_FIRESTORE)) { + // var firestoreJson = ",\"firestore\": {"; + // + // var files = Stream.of( + // firebaseConfig.firestoreConfig() + // .rulesFile + // .map(rulesFile -> "\t\"rules\": \"" + rulesFile + "\""), + // firebaseConfig.firestoreConfig() + // .indexesFile + // .map(indexesFile -> "\t\"indexes\": \"" + indexesFile + "\"") + // ) + // .filter(Optional::isPresent) + // .map(Optional::get) + // .collect(Collectors.joining(",\n")); + // + // firestoreJson += files; + // firestoreJson += "}\n"; + // firebaseJson.append(firestoreJson); + // } + // + // if (isEmulatorEnabled(Emulator.CLOUD_STORAGE)) { + // var storageJson = ",\"storage\": {"; + // + // storageJson += firebaseConfig.storageConfig.rulesFile().map(rulesFile -> + // "\n\t\"rules\": \"" + rulesFile + "\"\n" + // ); + // + // storageJson += "}\n"; + // firebaseJson.append(storageJson); + // } + // + // firebaseJson.append("}\n"); this.result.withFileFromString("firebase.json", firebaseJson.toString()); } private void setupDataImportExport() { - firebaseConfig.emulatorData().ifPresent(emulator -> { - this.dockerBuilder.volume(EMULATOR_DATA_PATH); - }); + firebaseConfig.emulatorData().ifPresent(emulator -> this.dockerBuilder.volume(EMULATOR_DATA_PATH)); } private void setupHosting() { // Specify public directory if hosting is enabled - if (firebaseConfig.hostingContentDir().isPresent()) { + if (firebaseConfig.hostingConfig().hostingContentDir().isPresent()) { this.dockerBuilder.volume(FIREBASE_HOSTING_PATH); } } @@ -386,9 +474,7 @@ private void setupHosting() { private void setupUserAndGroup() { var commands = new ArrayList(); - firebaseConfig.dockerConfig.groupId().ifPresent(group -> { - commands.add("addgroup -g " + group + " runner"); - }); + firebaseConfig.dockerConfig.groupId().ifPresent(group -> commands.add("addgroup -g " + group + " runner")); firebaseConfig.dockerConfig.userId().ifPresent(user -> { var groupName = firebaseConfig.dockerConfig().groupId().map(i -> "runner").orElse("node"); diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java new file mode 100644 index 00000000..e3c4af98 --- /dev/null +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java @@ -0,0 +1,168 @@ +package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.Optional; +import java.util.function.Consumer; + +import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper; + +import io.quarkiverse.googlecloudservices.firebase.deployment.firebase.json.*; + +/** + * This class is responsible to generate the Firebase.json file which controls the emulators. + */ +public class FirebaseJsonBuilder { + + private static final String ALL_IP = "0.0.0.0"; + + private final FirebaseConfig root; + private final FirebaseEmulatorContainer.EmulatorConfig emulatorConfig; + + public FirebaseJsonBuilder(FirebaseEmulatorContainer.EmulatorConfig emulatorConfig) { + this.emulatorConfig = emulatorConfig; + this.root = new FirebaseConfig(); + } + + public String buildFirebaseConfig() throws IOException { + // private Object database; + // private Object dataconnect; + configureEmulator(); + // private ExtensionsConfig extensions; + configureFirestore(); + // private Object functions; + // private Object hosting; + // private Remoteconfig remoteconfig; + configureStorage(); + + StringWriter writer = new StringWriter(); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.writeValue(writer, root); + return writer.toString(); + } + + private void configureEmulator() { + var emulators = new Emulators(); + root.setEmulators(emulators); + + withEmulator(FirebaseEmulatorContainer.Emulator.AUTHENTICATION, (port) -> { + var auth = new Auth(); + emulators.setAuth(auth); + auth.setHost(ALL_IP); + auth.setPort(port); + }); + + withEmulator(FirebaseEmulatorContainer.Emulator.REALTIME_DATABASE, (port) -> { + var database = new Database(); + emulators.setDatabase(database); + database.setHost(ALL_IP); + database.setPort(port); + }); + + withEmulator(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE, (port) -> { + var firestore = new Firestore(); + emulators.setFirestore(firestore); + firestore.setHost(ALL_IP); + firestore.setPort(port); + withEmulator(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE_WS, firestore::setWebsocketPort); + }); + + withEmulator(FirebaseEmulatorContainer.Emulator.CLOUD_FUNCTIONS, (port) -> { + var functions = new Functions(); + emulators.setFunctions(functions); + functions.setHost(ALL_IP); + functions.setPort(port); + }); + + withEmulator(FirebaseEmulatorContainer.Emulator.EVENT_ARC, (port) -> { + var eventarc = new Eventarc(); + emulators.setEventarc(eventarc); + eventarc.setHost(ALL_IP); + eventarc.setPort(port); + }); + + withEmulator(FirebaseEmulatorContainer.Emulator.FIREBASE_HOSTING, (port) -> { + var hosting = new Hosting(); + emulators.setHosting(hosting); + hosting.setHost(ALL_IP); + hosting.setPort(port); + }); + + withEmulator(FirebaseEmulatorContainer.Emulator.EMULATOR_HUB, (port) -> { + var hub = new Hub(); + emulators.setHub(hub); + hub.setHost(ALL_IP); + hub.setPort(port); + }); + + withEmulator(FirebaseEmulatorContainer.Emulator.LOGGING, (port) -> { + var logging = new Logging(); + emulators.setLogging(logging); + logging.setHost(ALL_IP); + logging.setPort(port); + }); + + withEmulator(FirebaseEmulatorContainer.Emulator.PUB_SUB, (port) -> { + var pubSub = new Pubsub(); + emulators.setPubsub(pubSub); + pubSub.setHost(ALL_IP); + pubSub.setPort(port); + }); + + withEmulator(FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE, (port) -> { + var storage = new Storage(); + emulators.setStorage(storage); + storage.setHost(ALL_IP); + storage.setPort(port); + }); + + withEmulator(FirebaseEmulatorContainer.Emulator.EMULATOR_SUITE_UI, (port) -> { + var ui = new Ui(); + emulators.setUi(ui); + ui.setHost(ALL_IP); + ui.setPort(port); + }); + + // Missing emulators + // private Apphosting apphosting; + // private Dataconnect dataconnect; + // private Extensions extensions; + // private Boolean singleProjectMode; + // private Tasks tasks; + } + + private void withEmulator(FirebaseEmulatorContainer.Emulator emulator, Consumer handler) { + if (isEmulatorEnabled(emulator)) { + var exposedPort = emulatorConfig.services().get(emulator); + var port = Optional.ofNullable(exposedPort.fixedPort()) + .orElse(emulator.internalPort); + + handler.accept(port); + } + } + + private void configureFirestore() { + if (isEmulatorEnabled(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE)) { + emulatorConfig.firestoreConfig().rulesFile().ifPresent(rules -> { + + }); + + emulatorConfig.firestoreConfig().indexesFile().ifPresent(index -> { + + }); + } + } + + private void configureStorage() { + if (isEmulatorEnabled(FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE)) { + emulatorConfig.storageConfig().rulesFile().ifPresent(rules -> { + + }); + } + } + + private boolean isEmulatorEnabled(FirebaseEmulatorContainer.Emulator emulator) { + return this.emulatorConfig.services().containsKey(emulator); + } + +} diff --git a/firebase/deployment/src/main/schema/firebase-config.json b/firebase-devservices/deployment/src/main/schema/firebase-config.json similarity index 100% rename from firebase/deployment/src/main/schema/firebase-config.json rename to firebase-devservices/deployment/src/main/schema/firebase-config.json From f9352016038fb62522eed18639bebf6125073700 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:13:45 +0100 Subject: [PATCH 057/101] Added config options for the rules and indexes files --- .../deployment/FirebaseDevServiceConfig.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index 27e21dff..343342f7 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -219,6 +219,16 @@ interface FirestoreDevService extends GenericDevService { * used. */ Optional websocketPort(); + + /** + * Path to the firestore.rules file. + */ + Optional rulesFile(); + + /** + * Path to the firestore.indexes.json file. + */ + Optional indexesFile(); } } @@ -256,7 +266,15 @@ interface Storage { /** * Configuration for the storage emulator */ - GenericDevService devservice(); + StorageDevService devservice(); + + interface StorageDevService extends GenericDevService{ + + /** + * Path to the storage.rules file. + */ + Optional rulesFile(); + } } /** From 9c8fa6eb880c52593a52e01fefbcf0b4bab727c9 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:14:02 +0100 Subject: [PATCH 058/101] Firebase container moved to separate package --- .../firebase/deployment/FirebaseDevServiceProcessor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java index e30d4ba9..e86f6ec3 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java @@ -4,6 +4,7 @@ import java.util.*; import java.util.stream.Collectors; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; import org.jboss.logging.Logger; import io.quarkus.deployment.IsNormal; From a712b1b5f704346182bcfa27c4617688449d60b9 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 21 Nov 2024 10:14:38 +0100 Subject: [PATCH 059/101] Firebase container moved to separate package Added config options for rules files --- .../FirebaseEmulatorConfigBuilder.java | 18 ++++++++++- .../testcontainers/FirebaseJsonBuilder.java | 26 ++++++++++++++-- .../FirebaseEmulatorConfigBuilderTest.java | 30 +++++++++++++++---- ...ebaseEmulatorContainerIntegrationTest.java | 18 ++++++++--- 4 files changed, 78 insertions(+), 14 deletions(-) diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java index 062c4d4d..a586a630 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java @@ -1,6 +1,9 @@ package io.quarkiverse.googlecloudservices.firebase.deployment; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; + import java.io.File; +import java.nio.file.Path; import java.util.Map; import java.util.stream.Collectors; @@ -30,10 +33,23 @@ public FirebaseEmulatorContainer.EmulatorConfig build() { devService.customFirebaseJson().map(File::new).map(File::toPath), devService.javaToolOptions(), devService.emulatorData().map(File::new).map(File::toPath), - config.firebase().hosting().hostingPath().map(File::new).map(File::toPath), + new FirebaseEmulatorContainer.HostingConfig( + config.firebase().hosting().hostingPath().map(FirebaseEmulatorConfigBuilder::asPath) + ), + new FirebaseEmulatorContainer.StorageConfig( + config.storage().devservice().rulesFile().map(FirebaseEmulatorConfigBuilder::asPath) + ), + new FirebaseEmulatorContainer.FirestoreConfig( + config.firestore().devservice().rulesFile().map(FirebaseEmulatorConfigBuilder::asPath), + config.firestore().devservice().indexesFile().map(FirebaseEmulatorConfigBuilder::asPath) + ), exposedEmulators(devServices(config))); } + private static Path asPath(String path) { + return new File(path).toPath(); + } + public static Map devServices( FirebaseDevServiceConfig config) { return Map.of( diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java index e3c4af98..15c23fa4 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.io.StringWriter; +import java.nio.file.Path; import java.util.Optional; import java.util.function.Consumer; @@ -143,24 +144,43 @@ private void withEmulator(FirebaseEmulatorContainer.Emulator emulator, Consumer< private void configureFirestore() { if (isEmulatorEnabled(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE)) { - emulatorConfig.firestoreConfig().rulesFile().ifPresent(rules -> { + var firestore = new Firestore(); + root.setFirestore(firestore); + emulatorConfig.firestoreConfig().rulesFile().ifPresent(rules -> { + var rulesFile = fileRelativeToCustomJsonOrDefault(rules, "firestore.rules"); + // TODO: Add rules file }); emulatorConfig.firestoreConfig().indexesFile().ifPresent(index -> { - + var indexFile = fileRelativeToCustomJsonOrDefault(index, "firestore.indexes.json"); + // TODO add index file }); } } private void configureStorage() { if (isEmulatorEnabled(FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE)) { - emulatorConfig.storageConfig().rulesFile().ifPresent(rules -> { + var storage = new Storage(); + root.setStorage(storage); + emulatorConfig.storageConfig().rulesFile().ifPresent(rules -> { + var rulesFile = fileRelativeToCustomJsonOrDefault(rules, "storage.rules"); + // TODO add rules file }); } } + private String fileRelativeToCustomJsonOrDefault(Path otherFile, String defaultFile) { + return emulatorConfig.customFirebaseJson() + .map(path -> relativePath(path, otherFile)) + .orElse(defaultFile); + } + + private String relativePath(Path firebaseJson, Path otherFile) { + return firebaseJson.getParent().relativize(otherFile).toString(); + } + private boolean isEmulatorEnabled(FirebaseEmulatorContainer.Emulator emulator) { return this.emulatorConfig.services().containsKey(emulator); } diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java index 17682d73..baba80e3 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java @@ -6,6 +6,7 @@ import java.util.Map; import java.util.Optional; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -47,7 +48,9 @@ void setUp() { new TestFirestoreDevService( true, Optional.of(6006), - Optional.of(6007))), + Optional.of(6007), + Optional.of("firestore.rules"), + Optional.of("firestore.indexes.json"))), new TestFunctions( new TestGenericDevService( true, @@ -57,9 +60,10 @@ void setUp() { true, Optional.of(6009))), new TestStorage( - new TestGenericDevService( + new TestStorageDevService( true, - Optional.empty()) // Storage + Optional.empty(), + Optional.of("storage.rules")) )); configBuilder = new FirebaseEmulatorConfigBuilder(config); } @@ -76,7 +80,11 @@ void testBuild() { assertPathEndsWith("firebase.json", emulatorConfig.customFirebaseJson().orElse(null)); assertEquals("-Xmx", emulatorConfig.javaToolOptions().orElse(null)); assertPathEndsWith("data", emulatorConfig.emulatorData().orElse(null)); - assertPathEndsWith("public", emulatorConfig.hostingContentDir().orElse(null)); + assertPathEndsWith("public", emulatorConfig.hostingConfig().hostingContentDir().orElse(null)); + assertPathEndsWith("storage.rules", emulatorConfig.storageConfig().rulesFile().orElse(null)); + assertPathEndsWith("firestore.rules", emulatorConfig.firestoreConfig().rulesFile().orElse(null)); + assertPathEndsWith("firestore.indexes.json", emulatorConfig.firestoreConfig().indexesFile().orElse(null)); + } private void assertPathEndsWith(String expected, Path path) { @@ -158,7 +166,9 @@ record TestFirestore( record TestFirestoreDevService( boolean enabled, Optional emulatorPort, - Optional websocketPort) implements FirebaseDevServiceConfig.Firestore.FirestoreDevService { + Optional websocketPort, + Optional rulesFile, + Optional indexesFile) implements FirebaseDevServiceConfig.Firestore.FirestoreDevService { } record TestFunctions( @@ -175,7 +185,15 @@ record TestPubSub( } record TestStorage( - FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.Storage { + FirebaseDevServiceConfig.Storage.StorageDevService devservice) implements FirebaseDevServiceConfig.Storage { + } + + record TestStorageDevService( + boolean enabled, + Optional emulatorPort, + Optional rulesFile + ) implements FirebaseDevServiceConfig.Storage.StorageDevService { + } record TestGenericDevService( diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index aa0f891c..c78778e1 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -13,6 +13,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -43,9 +44,9 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; -import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.Emulator; -import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.EmulatorConfig; -import io.quarkiverse.googlecloudservices.firebase.deployment.FirebaseEmulatorContainer.ExposedPort; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.Emulator; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.EmulatorConfig; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.ExposedPort; @Testcontainers public class FirebaseEmulatorContainerIntegrationTest { @@ -109,7 +110,16 @@ Emulator.EMULATOR_HUB, new ExposedPort(6010), Optional.empty(), Optional.empty(), Optional.of(tempEmulatorDataDir.toPath()), - Optional.of(tempHostingContentDir.toPath()), + new FirebaseEmulatorContainer.HostingConfig( + Optional.of(tempHostingContentDir.toPath()) + ), + new FirebaseEmulatorContainer.StorageConfig( + Optional.empty() + ), + new FirebaseEmulatorContainer.FirestoreConfig( + Optional.empty(), + Optional.empty() + ), SERVICES); firebaseContainer = new FirebaseEmulatorContainer(config); From eb031f7426b271f879244202ef7cb30705e4ced5 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sat, 30 Nov 2024 13:24:50 +0100 Subject: [PATCH 060/101] Added tests and completed setup to include custom firebase.json, Firestore and Storage files. --- ...kus-google-cloud-firebase-devservices.adoc | 51 +++++ ...d-firebase-devservices_quarkus.google.adoc | 51 +++++ firebase-devservices/deployment/firebase.json | 26 +++ .../deployment/firestore.indexes.json | 39 ++++ .../deployment/firestore.rules | 9 + .../deployment/FirebaseDevServiceConfig.java | 2 +- .../FirebaseDevServiceProcessor.java | 2 +- .../FirebaseEmulatorConfigBuilder.java | 24 ++- .../CustomFirebaseConfigReader.java | 180 ++++++++++++++++++ .../FirebaseEmulatorContainer.java | 160 +++++----------- .../testcontainers/FirebaseJsonBuilder.java | 42 ++-- .../src/main/schema/firebase-config.json | 1 - .../FirebaseEmulatorConfigBuilderTest.java | 20 +- ...baseEmulatorContainerCustomConfigTest.java | 76 ++++++++ ...ebaseEmulatorContainerIntegrationTest.java | 144 +++++--------- .../TestableFirebaseEmulatorContainer.java | 85 +++++++++ firebase-devservices/deployment/storage.rules | 10 + 17 files changed, 675 insertions(+), 247 deletions(-) create mode 100644 firebase-devservices/deployment/firebase.json create mode 100644 firebase-devservices/deployment/firestore.indexes.json create mode 100644 firebase-devservices/deployment/firestore.rules create mode 100644 firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java create mode 100644 firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerCustomConfigTest.java create mode 100644 firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/TestableFirebaseEmulatorContainer.java create mode 100644 firebase-devservices/deployment/storage.rules diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc index 7436ad50..c7fb8c0c 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc @@ -425,6 +425,40 @@ endif::add-copy-button-to-env-var[] |int | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-rules-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-rules-file[`quarkus.google.cloud.firestore.devservice.rules-file`]## + +[.description] +-- +Path to the firestore.rules file. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_RULES_FILE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_RULES_FILE+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-indexes-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-indexes-file[`quarkus.google.cloud.firestore.devservice.indexes-file`]## + +[.description] +-- +Path to the firestore.indexes.json file. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_INDEXES_FILE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_INDEXES_FILE+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-enabled[`quarkus.google.cloud.functions.devservice.enabled`]## [.description] @@ -527,5 +561,22 @@ endif::add-copy-button-to-env-var[] |int | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-rules-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-rules-file[`quarkus.google.cloud.storage.devservice.rules-file`]## + +[.description] +-- +Path to the storage.rules file. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_RULES_FILE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_RULES_FILE+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + |=== diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc index 7436ad50..c7fb8c0c 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc @@ -425,6 +425,40 @@ endif::add-copy-button-to-env-var[] |int | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-rules-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-rules-file[`quarkus.google.cloud.firestore.devservice.rules-file`]## + +[.description] +-- +Path to the firestore.rules file. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_RULES_FILE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_RULES_FILE+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-indexes-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-indexes-file[`quarkus.google.cloud.firestore.devservice.indexes-file`]## + +[.description] +-- +Path to the firestore.indexes.json file. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_INDEXES_FILE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_INDEXES_FILE+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-enabled[`quarkus.google.cloud.functions.devservice.enabled`]## [.description] @@ -527,5 +561,22 @@ endif::add-copy-button-to-env-var[] |int | +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-rules-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-rules-file[`quarkus.google.cloud.storage.devservice.rules-file`]## + +[.description] +-- +Path to the storage.rules file. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_RULES_FILE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_RULES_FILE+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + |=== diff --git a/firebase-devservices/deployment/firebase.json b/firebase-devservices/deployment/firebase.json new file mode 100644 index 00000000..03be7de1 --- /dev/null +++ b/firebase-devservices/deployment/firebase.json @@ -0,0 +1,26 @@ +{ + "emulators": { + "firestore": { + "host": "0.0.0.0", + "port": 7002, + "websocketPort": 7003 + }, + "storage": { + "host": "0.0.0.0", + "port": 7005 + }, + "ui": { + "host": "0.0.0.0", + "enabled": true, + "port": 7009 + }, + "singleProjectMode": true + }, + "firestore": { + "rules": "firestore.rules", + "indexes": "firestore.indexes.json" + }, + "storage": { + "rules": "storage.rules" + } +} diff --git a/firebase-devservices/deployment/firestore.indexes.json b/firebase-devservices/deployment/firestore.indexes.json new file mode 100644 index 00000000..28787432 --- /dev/null +++ b/firebase-devservices/deployment/firestore.indexes.json @@ -0,0 +1,39 @@ +{ + "indexes": [], + "fieldOverrides": [ + { + "collectionGroup": "Aanmelding", + "fieldPath": "datum", + "ttl": false, + "indexes": [ + { + "order": "ASCENDING", + "queryScope": "COLLECTION_GROUP" + } + ] + }, + { + "collectionGroup": "events", + "fieldPath": "transactionId", + "ttl": false, + "indexes": [ + { + "order": "ASCENDING", + "queryScope": "COLLECTION" + }, + { + "order": "DESCENDING", + "queryScope": "COLLECTION" + }, + { + "arrayConfig": "CONTAINS", + "queryScope": "COLLECTION" + }, + { + "order": "ASCENDING", + "queryScope": "COLLECTION_GROUP" + } + ] + } + ] +} diff --git a/firebase-devservices/deployment/firestore.rules b/firebase-devservices/deployment/firestore.rules new file mode 100644 index 00000000..5627b22e --- /dev/null +++ b/firebase-devservices/deployment/firestore.rules @@ -0,0 +1,9 @@ +rules_version = '2'; +service cloud.firestore { + match /databases/{database}/documents { + match /data/{document} { + allow read: if request.auth != null && request.auth.uid == resource.data.ownerId; + allow write: if request.auth != null && request.auth.uid == resource.data.ownerId; + } + } +} \ No newline at end of file diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index 343342f7..b1f371da 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -268,7 +268,7 @@ interface Storage { */ StorageDevService devservice(); - interface StorageDevService extends GenericDevService{ + interface StorageDevService extends GenericDevService { /** * Path to the storage.rules file. diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java index e86f6ec3..542cda4e 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java @@ -4,9 +4,9 @@ import java.util.*; import java.util.stream.Collectors; -import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; import org.jboss.logging.Logger; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; import io.quarkus.deployment.IsNormal; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.annotations.BuildSteps; diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java index a586a630..a5203183 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java @@ -1,12 +1,12 @@ package io.quarkiverse.googlecloudservices.firebase.deployment; -import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; - import java.io.File; import java.nio.file.Path; import java.util.Map; import java.util.stream.Collectors; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; + /** * This class translates the Quarkus Firebase extension configuration to the {@link FirebaseEmulatorContainer} * configuration. @@ -33,17 +33,15 @@ public FirebaseEmulatorContainer.EmulatorConfig build() { devService.customFirebaseJson().map(File::new).map(File::toPath), devService.javaToolOptions(), devService.emulatorData().map(File::new).map(File::toPath), - new FirebaseEmulatorContainer.HostingConfig( - config.firebase().hosting().hostingPath().map(FirebaseEmulatorConfigBuilder::asPath) - ), - new FirebaseEmulatorContainer.StorageConfig( - config.storage().devservice().rulesFile().map(FirebaseEmulatorConfigBuilder::asPath) - ), - new FirebaseEmulatorContainer.FirestoreConfig( - config.firestore().devservice().rulesFile().map(FirebaseEmulatorConfigBuilder::asPath), - config.firestore().devservice().indexesFile().map(FirebaseEmulatorConfigBuilder::asPath) - ), - exposedEmulators(devServices(config))); + new FirebaseEmulatorContainer.FirebaseConfig( + new FirebaseEmulatorContainer.HostingConfig( + config.firebase().hosting().hostingPath().map(FirebaseEmulatorConfigBuilder::asPath)), + new FirebaseEmulatorContainer.StorageConfig( + config.storage().devservice().rulesFile().map(FirebaseEmulatorConfigBuilder::asPath)), + new FirebaseEmulatorContainer.FirestoreConfig( + config.firestore().devservice().rulesFile().map(FirebaseEmulatorConfigBuilder::asPath), + config.firestore().devservice().indexesFile().map(FirebaseEmulatorConfigBuilder::asPath)), + exposedEmulators(devServices(config)))); } private static Path asPath(String path) { diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java new file mode 100644 index 00000000..f93a7567 --- /dev/null +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java @@ -0,0 +1,180 @@ +package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Path; +import java.util.*; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper; + +import io.quarkiverse.googlecloudservices.firebase.deployment.firebase.json.Emulators; +import io.quarkiverse.googlecloudservices.firebase.deployment.firebase.json.FirebaseConfig; + +public class CustomFirebaseConfigReader { + + private final ObjectMapper objectMapper = new ObjectMapper(); + + public FirebaseEmulatorContainer.FirebaseConfig readFromFirebase(Path customFirebaseJson) throws IOException { + var root = readCustomFirebaseJson(customFirebaseJson); + + return new FirebaseEmulatorContainer.FirebaseConfig( + readHosting(root.getHosting()), + readStorage(root.getStorage()), + readFirestore(root.getFirestore()), + readEmulators(root.getEmulators())); + } + + private record EmulatorMergeStrategy( + FirebaseEmulatorContainer.Emulator emulator, + Supplier configObjectSupplier, + Function> portSupplier) { + } + + private Map readEmulators(Emulators em) { + var mergeStrategies = new EmulatorMergeStrategy[] { + new EmulatorMergeStrategy<>( + FirebaseEmulatorContainer.Emulator.AUTHENTICATION, + em::getAuth, + a -> a::getPort), + new EmulatorMergeStrategy<>( + FirebaseEmulatorContainer.Emulator.EMULATOR_SUITE_UI, + em::getUi, + u -> u::getPort), + new EmulatorMergeStrategy<>( + FirebaseEmulatorContainer.Emulator.EMULATOR_HUB, + em::getHub, + h -> h::getPort), + new EmulatorMergeStrategy<>( + FirebaseEmulatorContainer.Emulator.LOGGING, + em::getLogging, + l -> l::getPort), + new EmulatorMergeStrategy<>( + FirebaseEmulatorContainer.Emulator.CLOUD_FUNCTIONS, + em::getFunctions, + f -> f::getPort), + new EmulatorMergeStrategy<>( + FirebaseEmulatorContainer.Emulator.EVENT_ARC, + em::getEventarc, + e -> e::getPort), + new EmulatorMergeStrategy<>( + FirebaseEmulatorContainer.Emulator.REALTIME_DATABASE, + em::getDatabase, + d -> d::getPort), + new EmulatorMergeStrategy<>( + FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE, + em::getFirestore, + d -> d::getPort), + new EmulatorMergeStrategy<>( + FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE, + em::getStorage, + s -> s::getPort), + new EmulatorMergeStrategy<>( + FirebaseEmulatorContainer.Emulator.FIREBASE_HOSTING, + em::getHosting, + h -> h::getPort) + }; + + var map = Arrays.stream(mergeStrategies) + .map(this::mergeEmulator) + .filter(e -> !Objects.isNull(e)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + if (em.getFirestore() != null && em.getFirestore().getWebsocketPort() != null) { + map = new HashMap<>(map); + + map.put( + FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE_WS, + new FirebaseEmulatorContainer.ExposedPort(em.getFirestore().getWebsocketPort())); + + map = Map.copyOf(map); + } + + return map; + } + + private Map.Entry mergeEmulator( + EmulatorMergeStrategy emulatorMergeStrategy) { + + var configObject = emulatorMergeStrategy.configObjectSupplier.get(); + if (configObject != null) { + var port = emulatorMergeStrategy.portSupplier.apply(configObject).get(); + return Map.entry(emulatorMergeStrategy.emulator, new FirebaseEmulatorContainer.ExposedPort(port)); + } else { + return null; + } + } + + private FirebaseEmulatorContainer.FirestoreConfig readFirestore(Object firestore) { + if (firestore instanceof Map) { + @SuppressWarnings("unchecked") + Map firestoreMap = (Map) firestore; + + var rulesFile = Optional + .ofNullable(firestoreMap.get("rules")) + .map(this::resolvePath); + var indexesFile = Optional + .ofNullable(firestoreMap.get("indexes")) + .map(this::resolvePath); + + return new FirebaseEmulatorContainer.FirestoreConfig( + rulesFile, + indexesFile); + } else { + return new FirebaseEmulatorContainer.FirestoreConfig( + Optional.empty(), + Optional.empty()); + } + } + + private FirebaseEmulatorContainer.HostingConfig readHosting(Object hosting) { + if (hosting instanceof Map) { + @SuppressWarnings("unchecked") + Map hostingMap = (Map) hosting; + + var publicDir = Optional + .ofNullable(hostingMap.get("public")) + .map(this::resolvePath); + + return new FirebaseEmulatorContainer.HostingConfig( + publicDir); + } else { + return new FirebaseEmulatorContainer.HostingConfig( + Optional.empty()); + } + } + + private FirebaseEmulatorContainer.StorageConfig readStorage(Object storage) { + if (storage instanceof Map) { + @SuppressWarnings("unchecked") + Map storageMap = (Map) storage; + + var rulesFile = Optional + .ofNullable(storageMap.get("rules")) + .map(this::resolvePath); + + return new FirebaseEmulatorContainer.StorageConfig( + rulesFile); + } else { + return new FirebaseEmulatorContainer.StorageConfig( + Optional.empty()); + } + } + + private Path resolvePath(String filename) { + return new File(filename).toPath(); + } + + private FirebaseConfig readCustomFirebaseJson(Path customFirebaseJson) throws IOException { + var customFirebaseFile = customFirebaseJson.toFile(); + var customFirebaseStream = new BufferedInputStream(new FileInputStream(customFirebaseFile)); + + return objectMapper.readerFor(FirebaseConfig.class) + .readValue(customFirebaseStream); + } + +} diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java index 5623ebaa..c1846efc 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java @@ -179,6 +179,20 @@ public record FirestoreConfig( Optional indexesFile) { } + /** + * + * @param hostingConfig The firebase hosting configuration + * @param storageConfig The storage configuration + * @param firestoreConfig The firestore configuration + * @param services The exposed services configuration + */ + public record FirebaseConfig( + HostingConfig hostingConfig, + StorageConfig storageConfig, + FirestoreConfig firestoreConfig, + Map services) { + } + /** * Describes the Firebase emulator configuration. * @@ -189,10 +203,7 @@ public record FirestoreConfig( * @param customFirebaseJson The path to a custom firebase * @param javaToolOptions The options to pass to the java based emulators * @param emulatorData The path to the directory where to store the emulator data - * @param hostingConfig The firebase hosting configuration - * @param storageConfig The storage configuration - * @param firestoreConfig The firestore configuration - * @param services The exposed services configuration + * @param firebaseConfig The firebase configuration */ public record EmulatorConfig( DockerConfig dockerConfig, @@ -202,10 +213,7 @@ public record EmulatorConfig( Optional customFirebaseJson, Optional javaToolOptions, Optional emulatorData, - HostingConfig hostingConfig, - StorageConfig storageConfig, - FirestoreConfig firestoreConfig, - Map services) { + FirebaseConfig firebaseConfig) { } private final Map services; @@ -213,23 +221,23 @@ public record EmulatorConfig( /** * Creates a new Firebase Emulator container * - * @param firebaseConfig The generic configuration of the firebase emulators + * @param emulatorConfig The generic configuration of the firebase emulators */ - public FirebaseEmulatorContainer(EmulatorConfig firebaseConfig) { - super(new FirebaseDockerBuilder(firebaseConfig).build()); + public FirebaseEmulatorContainer(EmulatorConfig emulatorConfig) { + super(new FirebaseDockerBuilder(emulatorConfig).build()); - firebaseConfig.emulatorData().ifPresent(path -> { + emulatorConfig.emulatorData().ifPresent(path -> { // https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data // Mount the volume to the specified path this.withFileSystemBind(path.toString(), EMULATOR_DATA_PATH, BindMode.READ_WRITE); }); - firebaseConfig.hostingConfig().hostingContentDir().ifPresent(hostingPath -> { + emulatorConfig.firebaseConfig().hostingConfig().hostingContentDir().ifPresent(hostingPath -> { // Mount volume for static hosting content this.withFileSystemBind(hostingPath.toString(), FIREBASE_HOSTING_PATH, BindMode.READ_ONLY); }); - this.services = firebaseConfig.services; + this.services = emulatorConfig.firebaseConfig().services; } private static class FirebaseDockerBuilder { @@ -243,14 +251,14 @@ private static class FirebaseDockerBuilder { private final ImageFromDockerfile result; - private final EmulatorConfig firebaseConfig; + private final EmulatorConfig emulatorConfig; private final Map devServices; private DockerfileBuilder dockerBuilder; - public FirebaseDockerBuilder(EmulatorConfig firebaseConfig) { - this.devServices = firebaseConfig.services; - this.firebaseConfig = firebaseConfig; + public FirebaseDockerBuilder(EmulatorConfig emulatorConfig) { + this.devServices = emulatorConfig.firebaseConfig().services; + this.emulatorConfig = emulatorConfig; this.result = new ImageFromDockerfile("localhost/testcontainers/firebase", false) .withDockerfileFromBuilder(builder -> this.dockerBuilder = builder); @@ -275,7 +283,7 @@ public ImageFromDockerfile build() { } private void validateConfiguration() { - if (isEmulatorEnabled(Emulator.AUTHENTICATION) && firebaseConfig.projectId().isEmpty()) { + if (isEmulatorEnabled(Emulator.AUTHENTICATION) && emulatorConfig.projectId().isEmpty()) { throw new IllegalStateException("Can't create Firebase Auth emulator. Google Project id is required"); } @@ -302,14 +310,14 @@ private void validateConfiguration() { } private void configureBaseImage() { - dockerBuilder.from(firebaseConfig.dockerConfig().imageName()); + dockerBuilder.from(emulatorConfig.dockerConfig().imageName()); } private void initialSetup() { dockerBuilder .run("apk --no-cache add openjdk11-jre bash curl openssl gettext nano nginx sudo && " + "npm cache clean --force && " + - "npm i -g firebase-tools@" + firebaseConfig.firebaseVersion() + " && " + + "npm i -g firebase-tools@" + emulatorConfig.firebaseVersion() + " && " + "deluser nginx && delgroup abuild && delgroup ping && " + "mkdir -p " + FIREBASE_ROOT + " && " + "mkdir -p " + FIREBASE_HOSTING_PATH + " && " + @@ -338,17 +346,17 @@ private String downloadEmulatorCommand(Emulator emulator, String downloadId) { } private void authenticateToFirebase() { - firebaseConfig.token().ifPresent(token -> dockerBuilder.env("FIREBASE_TOKEN", token)); + emulatorConfig.token().ifPresent(token -> dockerBuilder.env("FIREBASE_TOKEN", token)); } private void setupJavaToolOptions() { - firebaseConfig.javaToolOptions().ifPresent(toolOptions -> dockerBuilder.env("JAVA_TOOL_OPTIONS", toolOptions)); + emulatorConfig.javaToolOptions().ifPresent(toolOptions -> dockerBuilder.env("JAVA_TOOL_OPTIONS", toolOptions)); } private void addFirebaseJson() { dockerBuilder.workDir(FIREBASE_ROOT); - firebaseConfig.customFirebaseJson().ifPresentOrElse( + emulatorConfig.customFirebaseJson().ifPresentOrElse( this::includeCustomFirebaseJson, this::generateFirebaseJson); @@ -362,111 +370,43 @@ private void includeCustomFirebaseJson(Path customFilePath) { } private void includeFirestoreFiles() { - firebaseConfig.firestoreConfig.rulesFile.ifPresent(rulesFile -> { + emulatorConfig.firebaseConfig().firestoreConfig.rulesFile.ifPresent(rulesFile -> { this.dockerBuilder.add("firestore.rules", FIREBASE_ROOT + "/firestore.rules"); this.result.withFileFromPath("firestore.rules", rulesFile); }); - firebaseConfig.firestoreConfig.indexesFile.ifPresent(indexesFile -> { + emulatorConfig.firebaseConfig().firestoreConfig.indexesFile.ifPresent(indexesFile -> { this.dockerBuilder.add("firestore.indexes.json", FIREBASE_ROOT + "/firestore.indexes.json"); this.result.withFileFromPath("firestore.indexes.json", indexesFile); }); } private void includeStorageFiles() { - firebaseConfig.storageConfig.rulesFile.ifPresent(rulesFile -> { + emulatorConfig.firebaseConfig().storageConfig.rulesFile.ifPresent(rulesFile -> { this.dockerBuilder.add("storage.rules", FIREBASE_ROOT + "/storage.rules"); this.result.withFileFromPath("storage.rules", rulesFile); }); } private void generateFirebaseJson() { - var firebaseJsonBuilder = new FirebaseJsonBuilder(this.firebaseConfig); - String firebaseJson = null; + var firebaseJsonBuilder = new FirebaseJsonBuilder(this.emulatorConfig); + String firebaseJson; try { firebaseJson = firebaseJsonBuilder.buildFirebaseConfig(); } catch (IOException e) { throw new IllegalStateException("Failed to generate firebase.json file", e); } - // StringBuilder firebaseJson = new StringBuilder(); - // - // firebaseJson.append("{\n"); - // firebaseJson.append("\t\"emulators\": {\n"); - // - // var emulatorsJson = this.devServices - // .entrySet() - // .stream() - // .filter(service -> service.getKey().configProperty != null) - // .map((service -> { - // var emulator = service.getKey(); - // - // var port = Optional.ofNullable(service.getValue().fixedPort()) - // .orElse(emulator.internalPort); - // - // String additionalConfig = ""; - // if (emulator.equals(Emulator.CLOUD_FIRESTORE)) { - // var wsService = this.devServices.get(Emulator.CLOUD_FIRESTORE_WS); - // if (wsService != null) { - // var wsPort = Optional.ofNullable(wsService.fixedPort) - // .orElse(Emulator.CLOUD_FIRESTORE.internalPort); - // additionalConfig = "\t\t\t\"websocketPort\": " + wsPort + ",\n"; - // } - // } - // - // return "\t\t\"" + emulator.configProperty + "\": {\n" + - // "\t\t\t\"port\": " + port + ",\n" + - // additionalConfig + - // "\t\t\t\"host\": \"0.0.0.0\"\n" + - // "\t\t}"; - // })) - // .collect(Collectors.joining(",\n")); - // firebaseJson.append(emulatorsJson).append("\n"); - // firebaseJson.append("\t}\n"); - // - // if (isEmulatorEnabled(Emulator.CLOUD_FIRESTORE)) { - // var firestoreJson = ",\"firestore\": {"; - // - // var files = Stream.of( - // firebaseConfig.firestoreConfig() - // .rulesFile - // .map(rulesFile -> "\t\"rules\": \"" + rulesFile + "\""), - // firebaseConfig.firestoreConfig() - // .indexesFile - // .map(indexesFile -> "\t\"indexes\": \"" + indexesFile + "\"") - // ) - // .filter(Optional::isPresent) - // .map(Optional::get) - // .collect(Collectors.joining(",\n")); - // - // firestoreJson += files; - // firestoreJson += "}\n"; - // firebaseJson.append(firestoreJson); - // } - // - // if (isEmulatorEnabled(Emulator.CLOUD_STORAGE)) { - // var storageJson = ",\"storage\": {"; - // - // storageJson += firebaseConfig.storageConfig.rulesFile().map(rulesFile -> - // "\n\t\"rules\": \"" + rulesFile + "\"\n" - // ); - // - // storageJson += "}\n"; - // firebaseJson.append(storageJson); - // } - // - // firebaseJson.append("}\n"); - - this.result.withFileFromString("firebase.json", firebaseJson.toString()); + this.result.withFileFromString("firebase.json", firebaseJson); } private void setupDataImportExport() { - firebaseConfig.emulatorData().ifPresent(emulator -> this.dockerBuilder.volume(EMULATOR_DATA_PATH)); + emulatorConfig.emulatorData().ifPresent(emulator -> this.dockerBuilder.volume(EMULATOR_DATA_PATH)); } private void setupHosting() { // Specify public directory if hosting is enabled - if (firebaseConfig.hostingConfig().hostingContentDir().isPresent()) { + if (emulatorConfig.firebaseConfig().hostingConfig().hostingContentDir().isPresent()) { this.dockerBuilder.volume(FIREBASE_HOSTING_PATH); } } @@ -474,10 +414,10 @@ private void setupHosting() { private void setupUserAndGroup() { var commands = new ArrayList(); - firebaseConfig.dockerConfig.groupId().ifPresent(group -> commands.add("addgroup -g " + group + " runner")); + emulatorConfig.dockerConfig.groupId().ifPresent(group -> commands.add("addgroup -g " + group + " runner")); - firebaseConfig.dockerConfig.userId().ifPresent(user -> { - var groupName = firebaseConfig.dockerConfig().groupId().map(i -> "runner").orElse("node"); + emulatorConfig.dockerConfig.userId().ifPresent(user -> { + var groupName = emulatorConfig.dockerConfig().groupId().map(i -> "runner").orElse("node"); commands.add("adduser -u " + user + " -G " + groupName + " -D -h /srv/firebase runner"); }); @@ -494,11 +434,11 @@ private void setupUserAndGroup() { } private int dockerUser() { - return firebaseConfig.dockerConfig().userId().orElse(1000); + return emulatorConfig.dockerConfig().userId().orElse(1000); } private int dockerGroup() { - return firebaseConfig.dockerConfig().groupId().orElse(1000); + return emulatorConfig.dockerConfig().groupId().orElse(1000); } private void runExecutable() { @@ -506,14 +446,14 @@ private void runExecutable() { arguments.add("emulators:start"); - firebaseConfig.projectId() + emulatorConfig.projectId() .map(id -> "--project") .ifPresent(arguments::add); - firebaseConfig.projectId() + emulatorConfig.projectId() .ifPresent(arguments::add); - firebaseConfig + emulatorConfig .emulatorData() .map(path -> "--import") .ifPresent(arguments::add); @@ -522,12 +462,12 @@ private void runExecutable() { * We write the data to a subdirectory of the mount point. The firebase emulator tries to remove and * recreate the mount-point directory, which will obviously fail. By using a subdirectory, export succeeds. */ - firebaseConfig + emulatorConfig .emulatorData() .map(path -> EMULATOR_EXPORT_PATH) .ifPresent(arguments::add); - firebaseConfig + emulatorConfig .emulatorData() .map(path -> "--export-on-exit") .ifPresent(arguments::add); diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java index 15c23fa4..15737742 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java @@ -1,8 +1,8 @@ package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; -import java.io.IOException; -import java.io.StringWriter; +import java.io.*; import java.nio.file.Path; +import java.util.HashMap; import java.util.Optional; import java.util.function.Consumer; @@ -17,8 +17,9 @@ public class FirebaseJsonBuilder { private static final String ALL_IP = "0.0.0.0"; - private final FirebaseConfig root; + private final ObjectMapper objectMapper = new ObjectMapper(); private final FirebaseEmulatorContainer.EmulatorConfig emulatorConfig; + private final FirebaseConfig root; public FirebaseJsonBuilder(FirebaseEmulatorContainer.EmulatorConfig emulatorConfig) { this.emulatorConfig = emulatorConfig; @@ -26,6 +27,14 @@ public FirebaseJsonBuilder(FirebaseEmulatorContainer.EmulatorConfig emulatorConf } public String buildFirebaseConfig() throws IOException { + generateFirebaseConfig(); + + StringWriter writer = new StringWriter(); + objectMapper.writeValue(writer, root); + return writer.toString(); + } + + private void generateFirebaseConfig() { // private Object database; // private Object dataconnect; configureEmulator(); @@ -35,11 +44,6 @@ public String buildFirebaseConfig() throws IOException { // private Object hosting; // private Remoteconfig remoteconfig; configureStorage(); - - StringWriter writer = new StringWriter(); - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.writeValue(writer, root); - return writer.toString(); } private void configureEmulator() { @@ -134,7 +138,7 @@ private void configureEmulator() { private void withEmulator(FirebaseEmulatorContainer.Emulator emulator, Consumer handler) { if (isEmulatorEnabled(emulator)) { - var exposedPort = emulatorConfig.services().get(emulator); + var exposedPort = emulatorConfig.firebaseConfig().services().get(emulator); var port = Optional.ofNullable(exposedPort.fixedPort()) .orElse(emulator.internalPort); @@ -144,29 +148,29 @@ private void withEmulator(FirebaseEmulatorContainer.Emulator emulator, Consumer< private void configureFirestore() { if (isEmulatorEnabled(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE)) { - var firestore = new Firestore(); + var firestore = new HashMap(); // Generated sources can't handle anyOf yet root.setFirestore(firestore); - emulatorConfig.firestoreConfig().rulesFile().ifPresent(rules -> { + emulatorConfig.firebaseConfig().firestoreConfig().rulesFile().ifPresent(rules -> { var rulesFile = fileRelativeToCustomJsonOrDefault(rules, "firestore.rules"); - // TODO: Add rules file + firestore.put("rules", rulesFile); }); - emulatorConfig.firestoreConfig().indexesFile().ifPresent(index -> { + emulatorConfig.firebaseConfig().firestoreConfig().indexesFile().ifPresent(index -> { var indexFile = fileRelativeToCustomJsonOrDefault(index, "firestore.indexes.json"); - // TODO add index file + firestore.put("indexes", indexFile); }); } } private void configureStorage() { if (isEmulatorEnabled(FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE)) { - var storage = new Storage(); - root.setStorage(storage); + emulatorConfig.firebaseConfig().storageConfig().rulesFile().ifPresent(rules -> { + var storage = new HashMap(); // Generated sources can't handle anyOf yet + root.setStorage(storage); - emulatorConfig.storageConfig().rulesFile().ifPresent(rules -> { var rulesFile = fileRelativeToCustomJsonOrDefault(rules, "storage.rules"); - // TODO add rules file + storage.put("rules", rulesFile); }); } } @@ -182,7 +186,7 @@ private String relativePath(Path firebaseJson, Path otherFile) { } private boolean isEmulatorEnabled(FirebaseEmulatorContainer.Emulator emulator) { - return this.emulatorConfig.services().containsKey(emulator); + return this.emulatorConfig.firebaseConfig().services().containsKey(emulator); } } diff --git a/firebase-devservices/deployment/src/main/schema/firebase-config.json b/firebase-devservices/deployment/src/main/schema/firebase-config.json index c851ecd4..02e77372 100644 --- a/firebase-devservices/deployment/src/main/schema/firebase-config.json +++ b/firebase-devservices/deployment/src/main/schema/firebase-config.json @@ -544,7 +544,6 @@ }, "port": { "type": [ - "string", "integer" ] } diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java index baba80e3..d49e707b 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java @@ -6,10 +6,11 @@ import java.util.Map; import java.util.Optional; -import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; + class FirebaseEmulatorConfigBuilderTest { private FirebaseEmulatorConfigBuilder configBuilder; @@ -63,8 +64,7 @@ void setUp() { new TestStorageDevService( true, Optional.empty(), - Optional.of("storage.rules")) - )); + Optional.of("storage.rules")))); configBuilder = new FirebaseEmulatorConfigBuilder(config); } @@ -80,10 +80,11 @@ void testBuild() { assertPathEndsWith("firebase.json", emulatorConfig.customFirebaseJson().orElse(null)); assertEquals("-Xmx", emulatorConfig.javaToolOptions().orElse(null)); assertPathEndsWith("data", emulatorConfig.emulatorData().orElse(null)); - assertPathEndsWith("public", emulatorConfig.hostingConfig().hostingContentDir().orElse(null)); - assertPathEndsWith("storage.rules", emulatorConfig.storageConfig().rulesFile().orElse(null)); - assertPathEndsWith("firestore.rules", emulatorConfig.firestoreConfig().rulesFile().orElse(null)); - assertPathEndsWith("firestore.indexes.json", emulatorConfig.firestoreConfig().indexesFile().orElse(null)); + assertPathEndsWith("public", emulatorConfig.firebaseConfig().hostingConfig().hostingContentDir().orElse(null)); + assertPathEndsWith("storage.rules", emulatorConfig.firebaseConfig().storageConfig().rulesFile().orElse(null)); + assertPathEndsWith("firestore.rules", emulatorConfig.firebaseConfig().firestoreConfig().rulesFile().orElse(null)); + assertPathEndsWith("firestore.indexes.json", + emulatorConfig.firebaseConfig().firestoreConfig().indexesFile().orElse(null)); } @@ -97,7 +98,7 @@ void testExposedEmulators() { FirebaseEmulatorContainer.EmulatorConfig emulatorConfig = configBuilder.build(); Map exposedPorts = emulatorConfig - .services(); + .firebaseConfig().services(); assertEquals(10, exposedPorts.size()); assertEquals(6000, exposedPorts.get(FirebaseEmulatorContainer.Emulator.EMULATOR_SUITE_UI).fixedPort()); @@ -191,8 +192,7 @@ record TestStorage( record TestStorageDevService( boolean enabled, Optional emulatorPort, - Optional rulesFile - ) implements FirebaseDevServiceConfig.Storage.StorageDevService { + Optional rulesFile) implements FirebaseDevServiceConfig.Storage.StorageDevService { } diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerCustomConfigTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerCustomConfigTest.java new file mode 100644 index 00000000..941d256d --- /dev/null +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerCustomConfigTest.java @@ -0,0 +1,76 @@ +package io.quarkiverse.googlecloudservices.firebase.deployment; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Optional; + +import org.junit.jupiter.api.Test; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import com.google.firebase.FirebaseOptions; + +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.CustomFirebaseConfigReader; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; + +@Testcontainers +public class FirebaseEmulatorContainerCustomConfigTest { + + private static final File tempEmulatorDataDir; + + static { + try { + // Create a temporary directory for emulator data + tempEmulatorDataDir = Files.createTempDirectory("firebase-emulator-data").toFile(); + firebaseContainer = new TestableFirebaseEmulatorContainer( + new FirebaseEmulatorContainer.EmulatorConfig( + new FirebaseEmulatorContainer.DockerConfig( + "node:23-alpine", + TestableFirebaseEmulatorContainer.user, + TestableFirebaseEmulatorContainer.group), + "latest", // Firebase version + Optional.of("demo-test-project"), + Optional.empty(), + Optional.of(new File("firebase.json").toPath()), + Optional.empty(), + Optional.of(tempEmulatorDataDir.toPath()), + new CustomFirebaseConfigReader().readFromFirebase(new File("firebase.json").toPath())), + "FirebaseEmulatorContainerCustomConfigTest") { + + @Override + protected void createFirebaseOptions(FirebaseOptions.Builder builder) { + } + }; + + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + @Container + private static final FirebaseEmulatorContainer firebaseContainer; + + @Test + public void testFirestoreRulesAndIndexes() throws InterruptedException, IOException { + // Verify the firebase.json file exists in the container + String firebaseJsonCheck = firebaseContainer.execInContainer("cat", "/srv/firebase/firebase.json").getStdout(); + assertTrue(firebaseJsonCheck.contains("\"emulators\""), "Expected firebase.json to be present in the container"); + + // Verify the firestore.rules file exists in the container + String firestoreRulesCheck = firebaseContainer.execInContainer("cat", "/srv/firebase/firestore.rules").getStdout(); + assertTrue(firestoreRulesCheck.contains("service cloud.firestore"), + "Expected firestore.rules to be present in the container"); + } + + @Test + public void testStorageRules() throws IOException, InterruptedException { + // Verify the storage.rules file exists in the container + String storageRulesCheck = firebaseContainer.execInContainer("cat", "/srv/firebase/storage.rules").getStdout(); + assertTrue(storageRulesCheck.contains("service firebase.storage"), + "Expected storage.rules to be present in the container"); + } + +} diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java index c78778e1..85643062 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java @@ -13,11 +13,10 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.testcontainers.containers.output.OutputFrame; import org.testcontainers.junit.jupiter.Testcontainers; import com.google.api.core.ApiFuture; @@ -31,7 +30,6 @@ import com.google.cloud.pubsub.v1.TopicAdminSettings; import com.google.cloud.storage.*; import com.google.cloud.storage.Blob; -import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseAuthException; @@ -44,6 +42,7 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.Emulator; import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.EmulatorConfig; import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.ExposedPort; @@ -51,12 +50,25 @@ @Testcontainers public class FirebaseEmulatorContainerIntegrationTest { - private static final FirebaseEmulatorContainer firebaseContainer; private static final File tempEmulatorDataDir; private static final File tempHostingContentDir; - private static final String emulatorHost; - private static final FirebaseApp app; + static { + try { + // Create a temporary directory for emulator data + tempEmulatorDataDir = Files.createTempDirectory("firebase-emulator-data").toFile(); + tempHostingContentDir = Files.createTempDirectory("firebase-hosting-content").toFile(); + + // Create a static HTML file in the hosting directory + File indexFile = new File(tempHostingContentDir, "index.html"); + try (FileWriter writer = new FileWriter(indexFile)) { + writer.write("

Hello, Firebase Hosting!

"); + } + + } catch (IOException e) { + throw new IllegalStateException(e); + } + } private static final Map SERVICES = Map.of( Emulator.AUTHENTICATION, new ExposedPort(6000), @@ -72,97 +84,45 @@ Emulator.EMULATOR_SUITE_UI, new ExposedPort(6009), Emulator.EMULATOR_HUB, new ExposedPort(6010), Emulator.LOGGING, new ExposedPort(6011)); - static { - try { - /* - * We determine the current group and user using an env variable. This is set by the GitHub Actions runner. - * The user and group are used to set the user/group for the user in the docker container run by - * TestContainers for the Firebase Emulators. This way, the data exported by the Firebase Emulators - * can be read from the build. - */ - var user = Optional - .ofNullable(System.getenv("CURRENT_USER")) - .map(Integer::valueOf); - var group = Optional - .ofNullable(System.getenv("CURRENT_GROUP")) - .map(Integer::valueOf); - - System.out.println("Running as user " + user + " and group " + group); - - // Create a temporary directory for emulator data - tempEmulatorDataDir = Files.createTempDirectory("firebase-emulator-data").toFile(); - tempHostingContentDir = Files.createTempDirectory("firebase-hosting-content").toFile(); - - // Create a static HTML file in the hosting directory - File indexFile = new File(tempHostingContentDir, "index.html"); - try (FileWriter writer = new FileWriter(indexFile)) { - writer.write("

Hello, Firebase Hosting!

"); - } - - EmulatorConfig config = new EmulatorConfig( + private static final TestableFirebaseEmulatorContainer firebaseContainer = new TestableFirebaseEmulatorContainer( + new EmulatorConfig( new FirebaseEmulatorContainer.DockerConfig( "node:23-alpine", - user, - group), + TestableFirebaseEmulatorContainer.user, + TestableFirebaseEmulatorContainer.group), "latest", // Firebase version Optional.of("demo-test-project"), Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(tempEmulatorDataDir.toPath()), - new FirebaseEmulatorContainer.HostingConfig( - Optional.of(tempHostingContentDir.toPath()) - ), - new FirebaseEmulatorContainer.StorageConfig( - Optional.empty() - ), - new FirebaseEmulatorContainer.FirestoreConfig( - Optional.empty(), - Optional.empty() - ), - SERVICES); - - firebaseContainer = new FirebaseEmulatorContainer(config); - firebaseContainer.start(); - - firebaseContainer.followOutput(FirebaseEmulatorContainerIntegrationTest::writeToStdOut, - OutputFrame.OutputType.STDOUT); - firebaseContainer.followOutput(FirebaseEmulatorContainerIntegrationTest::writeToStdErr, - OutputFrame.OutputType.STDERR); - - emulatorHost = firebaseContainer.getHost(); - - int dbPort = firebaseContainer.emulatorPort(Emulator.REALTIME_DATABASE); - - var firebaseBuilder = FirebaseOptions.builder() - .setProjectId("demo-test-project") - .setCredentials(new EmulatorCredentials()) - .setDatabaseUrl("http://" + emulatorHost + ":" + dbPort + "?ns=demo-test-project"); - - FirebaseOptions options = firebaseBuilder.build(); - app = FirebaseApp.initializeApp(options); - } catch (IOException e) { - throw new IllegalStateException(e); + new FirebaseEmulatorContainer.FirebaseConfig( + new FirebaseEmulatorContainer.HostingConfig( + Optional.of(tempHostingContentDir.toPath())), + new FirebaseEmulatorContainer.StorageConfig( + Optional.empty()), + new FirebaseEmulatorContainer.FirestoreConfig( + Optional.empty(), + Optional.empty()), + SERVICES)), + "FirebaseEmulatorContainerIntegrationTest") { + @Override + protected void createFirebaseOptions(FirebaseOptions.Builder builder) { + var emulatorHost = firebaseContainer.getHost(); + var dbPort = firebaseContainer.emulatorPort(Emulator.REALTIME_DATABASE); + + builder.setDatabaseUrl("http://" + emulatorHost + ":" + dbPort + "?ns=demo-test-project"); } - } + }; - private static void writeToStdOut(OutputFrame frame) { - writeOutputFrame(frame, System.out); - } - - private static void writeToStdErr(OutputFrame frame) { - writeOutputFrame(frame, System.err); - } - - private static void writeOutputFrame(OutputFrame frame, PrintStream output) { - output.println(frame.getUtf8StringWithoutLineEnding()); + @BeforeAll + public static void setup() { + firebaseContainer.start(); } @AfterAll public static void tearDown() { - if (firebaseContainer != null) { - firebaseContainer.stop(); - } + firebaseContainer.stop(); validateEmulatorDataWritten(); @@ -209,7 +169,7 @@ public void testFirebaseHostingEmulatorConnection() throws Exception { int hostingPort = firebaseContainer.emulatorPort(Emulator.FIREBASE_HOSTING); // Construct URL for the hosted file - URL url = new URL("http://" + emulatorHost + ":" + hostingPort + "/index.html"); + URL url = new URL("http://" + firebaseContainer.getHost() + ":" + hostingPort + "/index.html"); // Fetch content from the URL HttpURLConnection connection = (HttpURLConnection) url.openConnection(); @@ -230,10 +190,10 @@ public void testFirebaseAuthenticationEmulatorConnection() throws FirebaseAuthEx int authPort = firebaseContainer.emulatorPort(Emulator.AUTHENTICATION); // Set the environment variable for the Firebase Authentication emulator - FirebaseProcessEnvironment.setenv("FIREBASE_AUTH_EMULATOR_HOST", emulatorHost + ":" + authPort); + FirebaseProcessEnvironment.setenv("FIREBASE_AUTH_EMULATOR_HOST", firebaseContainer.getHost() + ":" + authPort); // Initialize FirebaseOptions without setting the auth emulator host directly - FirebaseAuth auth = FirebaseAuth.getInstance(app); + FirebaseAuth auth = FirebaseAuth.getInstance(firebaseContainer.getApp()); // Create a test user and verify it UserRecord.CreateRequest request = new UserRecord.CreateRequest() @@ -254,7 +214,7 @@ public void testFirestoreEmulatorConnection() throws ExecutionException, Interru FirestoreOptions options = FirestoreOptions.newBuilder() .setProjectId("demo-test-project") - .setEmulatorHost(emulatorHost + ":" + firestorePort) + .setEmulatorHost(firebaseContainer.getHost() + ":" + firestorePort) .setCredentials(new EmulatorCredentials()) .build(); Firestore firestore = options.getService(); @@ -269,7 +229,7 @@ public void testFirestoreEmulatorConnection() throws ExecutionException, Interru @Test public void testRealtimeDatabaseEmulatorConnection() throws ExecutionException, InterruptedException { - DatabaseReference ref = FirebaseDatabase.getInstance(app).getReference("testData"); + DatabaseReference ref = FirebaseDatabase.getInstance(firebaseContainer.getApp()).getReference("testData"); // Write data to the database ref.setValueAsync("testValue").get(); @@ -302,7 +262,7 @@ public void testPubSubEmulatorConnection() throws Exception { int pubSubPort = firebaseContainer.emulatorPort(Emulator.PUB_SUB); // Set up a gRPC channel to the Pub/Sub emulator - ManagedChannel channel = ManagedChannelBuilder.forAddress(emulatorHost, pubSubPort) + ManagedChannel channel = ManagedChannelBuilder.forAddress(firebaseContainer.getHost(), pubSubPort) .usePlaintext() .build(); @@ -340,7 +300,7 @@ public void testStorageEmulatorConnection() { int storagePort = firebaseContainer.emulatorPort(Emulator.CLOUD_STORAGE); Storage storage = StorageOptions.newBuilder() - .setHost("http://" + emulatorHost + ":" + storagePort) + .setHost("http://" + firebaseContainer.getHost() + ":" + storagePort) .setProjectId("demo-test-project") .setCredentials(NoCredentials.getInstance()) .build().getService(); @@ -367,7 +327,7 @@ public void testEmulatorUIReachable() throws Exception { int uiPort = firebaseContainer.emulatorPort(Emulator.EMULATOR_SUITE_UI); // Construct the URL for the Emulator UI root (where index.html would be served) - URL url = new URL("http://" + emulatorHost + ":" + uiPort + "/"); + URL url = new URL("http://" + firebaseContainer.getHost() + ":" + uiPort + "/"); // Open a connection and send an HTTP GET request HttpURLConnection connection = (HttpURLConnection) url.openConnection(); @@ -387,7 +347,7 @@ public void testEmulatorHub() throws Exception { int uiPort = firebaseContainer.emulatorPort(Emulator.EMULATOR_HUB); // Construct the URL for the Emulator UI root (where index.html would be served) - URL url = new URL("http://" + emulatorHost + ":" + uiPort + "/emulators"); + URL url = new URL("http://" + firebaseContainer.getHost() + ":" + uiPort + "/emulators"); // Open a connection and send an HTTP GET request HttpURLConnection connection = (HttpURLConnection) url.openConnection(); diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/TestableFirebaseEmulatorContainer.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/TestableFirebaseEmulatorContainer.java new file mode 100644 index 00000000..89d4982b --- /dev/null +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/TestableFirebaseEmulatorContainer.java @@ -0,0 +1,85 @@ +package io.quarkiverse.googlecloudservices.firebase.deployment; + +import java.io.PrintStream; +import java.util.Optional; + +import org.testcontainers.containers.output.OutputFrame; + +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import com.google.firebase.internal.EmulatorCredentials; + +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; + +/** + * Subclass of {@link FirebaseEmulatorContainer} which has some extra facilities to ease testing. Functionally + * this class is equivalent of its superclass with respect to the testing we need to perform. + */ +public abstract class TestableFirebaseEmulatorContainer extends FirebaseEmulatorContainer { + + /* + * We determine the current group and user using an env variable. This is set by the GitHub Actions runner. + * The user and group are used to set the user/group for the user in the docker container run by + * TestContainers for the Firebase Emulators. This way, the data exported by the Firebase Emulators + * can be read from the build. + */ + protected static Optional user = Optional + .ofNullable(System.getenv("CURRENT_USER")) + .map(Integer::valueOf); + protected static Optional group = Optional + .ofNullable(System.getenv("CURRENT_GROUP")) + .map(Integer::valueOf); + + static { + System.out.println("Running as user " + user + " and group " + group); + } + + private final String name; + private FirebaseApp app; + + /** + * Creates a new Firebase Emulator container + * + * @param firebaseConfig The generic configuration of the firebase emulators + * @param name The name of the firebase app (must be unique across the JVM). + */ + public TestableFirebaseEmulatorContainer(EmulatorConfig firebaseConfig, String name) { + super(firebaseConfig); + this.name = name; + } + + @Override + public void start() { + super.start(); + + followOutput(this::writeToStdOut, OutputFrame.OutputType.STDOUT); + followOutput(this::writeToStdErr, OutputFrame.OutputType.STDERR); + + var firebaseBuilder = FirebaseOptions.builder() + .setProjectId("demo-test-project") + .setCredentials(new EmulatorCredentials()); + + createFirebaseOptions(firebaseBuilder); + + FirebaseOptions options = firebaseBuilder.build(); + app = FirebaseApp.initializeApp(options, name); + } + + protected abstract void createFirebaseOptions(FirebaseOptions.Builder builder); + + private void writeToStdOut(OutputFrame frame) { + writeOutputFrame(frame, System.out); + } + + private void writeToStdErr(OutputFrame frame) { + writeOutputFrame(frame, System.err); + } + + private void writeOutputFrame(OutputFrame frame, PrintStream output) { + output.println(frame.getUtf8StringWithoutLineEnding()); + } + + public FirebaseApp getApp() { + return app; + } +} diff --git a/firebase-devservices/deployment/storage.rules b/firebase-devservices/deployment/storage.rules new file mode 100644 index 00000000..17f5f58e --- /dev/null +++ b/firebase-devservices/deployment/storage.rules @@ -0,0 +1,10 @@ +service firebase.storage { + match /b/{bucket}/o { + match /company/{allPaths=**} { + allow read: if true + } + match /building/{allPaths=**} { + allow read: if true + } + } +} From e9f2219d18d21cc65e41a1d6643e87e5415ce2d8 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 12 Dec 2024 18:15:53 +0100 Subject: [PATCH 061/101] Update docs/modules/ROOT/pages/firebase.adoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix typo Co-authored-by: Loïc Mathieu --- docs/modules/ROOT/pages/firebase.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/firebase.adoc b/docs/modules/ROOT/pages/firebase.adoc index 8d88db53..88227046 100644 --- a/docs/modules/ROOT/pages/firebase.adoc +++ b/docs/modules/ROOT/pages/firebase.adoc @@ -83,7 +83,7 @@ By default a `firebase.json` file is generated inside the image to configure the * Each of the emulators must be exposed on `0.0.0.0` as host as described https://firebase.google.com/docs/emulator-suite/use_hosting#emulators-no-local-host[here]. If this is not done, the Emulators will not be reachable from the Docker host. * Emulators need to be configured to use the default ports. Customizing the ports on which they run is currently not supported (this might change in a future version). -== Interaction with other other extensions +== Interaction with other extensions The following extensions support a DevService which conflicts with the DevService exposed by the Firebase Emulators. From 6ff127c4e3193fbac2dfd1f142ada08d686629c5 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 12 Dec 2024 18:16:32 +0100 Subject: [PATCH 062/101] Update firebase-devservices/runtime/src/main/resources/META-INF/quarkus-extension.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix extension name Co-authored-by: Loïc Mathieu --- .../runtime/src/main/resources/META-INF/quarkus-extension.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase-devservices/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/firebase-devservices/runtime/src/main/resources/META-INF/quarkus-extension.yaml index f0adf31d..237fa448 100644 --- a/firebase-devservices/runtime/src/main/resources/META-INF/quarkus-extension.yaml +++ b/firebase-devservices/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -1,5 +1,5 @@ --- -name: "Google Cloud Firebase" +name: "Google Cloud Firebase Devservices" artifact: ${project.groupId}:${project.artifactId}:${project.version} metadata: keywords: From 2b82260f7648b8afca28d200366ae6a3a4a6494f Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 12 Dec 2024 18:17:04 +0100 Subject: [PATCH 063/101] Update docs/modules/ROOT/pages/firebase.adoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Mathieu --- docs/modules/ROOT/pages/firebase.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/firebase.adoc b/docs/modules/ROOT/pages/firebase.adoc index 88227046..01afb6fc 100644 --- a/docs/modules/ROOT/pages/firebase.adoc +++ b/docs/modules/ROOT/pages/firebase.adoc @@ -91,7 +91,7 @@ The following extensions support a DevService which conflicts with the DevServic * PubSub * TODO: Verify Storage -When including this module, these DevServices will automatically be disabled, as the Firebase emulator should feature wise be on-par or more extensive than the individual emulators. +When including this module, these Dev Services will automatically be disabled, as the Firebase emulator should feature wise be on-par or more extensive than the individual emulators. == Configuration Reference From 0b90afc049c912f220196ddf66552f57fc6843bb Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 12 Dec 2024 22:32:59 +0100 Subject: [PATCH 064/101] Update docs/modules/ROOT/pages/firebase.adoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Mathieu --- docs/modules/ROOT/pages/firebase.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/firebase.adoc b/docs/modules/ROOT/pages/firebase.adoc index 01afb6fc..6409189e 100644 --- a/docs/modules/ROOT/pages/firebase.adoc +++ b/docs/modules/ROOT/pages/firebase.adoc @@ -85,7 +85,7 @@ By default a `firebase.json` file is generated inside the image to configure the == Interaction with other extensions -The following extensions support a DevService which conflicts with the DevService exposed by the Firebase Emulators. +The following extensions support Dev Services which conflicts with the Dev Services exposed by the Firebase Emulators. * Firestore * PubSub From baab7ed4ca40fddedd4e7215b80e4364d5263a96 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Thu, 12 Dec 2024 22:37:17 +0100 Subject: [PATCH 065/101] Fix documentation page name and include in navigation --- docs/modules/ROOT/nav.adoc | 1 + .../ROOT/pages/{firebase.adoc => firebase-devservices.adoc} | 0 2 files changed, 1 insertion(+) rename docs/modules/ROOT/pages/{firebase.adoc => firebase-devservices.adoc} (100%) diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index 984e79fb..3d528b84 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -4,6 +4,7 @@ ** xref:index.adoc#examples[Example applications] * xref:bigquery.adoc[BigQuery] * xref:bigtable.adoc[BigTable] +* xref:firebase-devservices.adoc[Firebase Admin] * xref:firebase-admin.adoc[Firebase Admin] * xref:firestore.adoc[Firestore] * xref:logging.adoc[Logging] diff --git a/docs/modules/ROOT/pages/firebase.adoc b/docs/modules/ROOT/pages/firebase-devservices.adoc similarity index 100% rename from docs/modules/ROOT/pages/firebase.adoc rename to docs/modules/ROOT/pages/firebase-devservices.adoc From a16bb5536bf02ad43868d0be84262757121861b3 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sun, 15 Dec 2024 01:37:42 +0100 Subject: [PATCH 066/101] Update firebase.adoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Mathieu --- docs/modules/ROOT/pages/firebase.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/firebase.adoc b/docs/modules/ROOT/pages/firebase.adoc index 6409189e..32ee7661 100644 --- a/docs/modules/ROOT/pages/firebase.adoc +++ b/docs/modules/ROOT/pages/firebase.adoc @@ -78,7 +78,7 @@ You can configure a custom image if needed as base image to run the Firebase Emu == Custom Firebase JSON -By default a `firebase.json` file is generated inside the image to configure the various emulators. You can configure the DevService to use your own custom firebase.json file (e.g generated using the Firebase tools CLI). The following requirements are defined for this file: +By default a `firebase.json` file is generated inside the image to configure the various emulators. You can configure the Dev Services to use your own custom firebase.json file (e.g generated using the Firebase tools CLI). The following requirements are defined for this file: * Each of the emulators must be exposed on `0.0.0.0` as host as described https://firebase.google.com/docs/emulator-suite/use_hosting#emulators-no-local-host[here]. If this is not done, the Emulators will not be reachable from the Docker host. * Emulators need to be configured to use the default ports. Customizing the ports on which they run is currently not supported (this might change in a future version). From ad647a62b57d23a187f2625f6646a377269eea9d Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sun, 15 Dec 2024 21:23:19 +0100 Subject: [PATCH 067/101] Refactored config setup --- .../deployment/FirebaseDevServiceConfig.java | 61 ++++++++++--------- .../FirebaseEmulatorConfigBuilder.java | 3 +- .../FirebaseEmulatorConfigBuilderTest.java | 20 +++--- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index b1f371da..89b093ee 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -34,11 +34,6 @@ public interface FirebaseDevServiceConfig { */ Firebase firebase(); - /** - * Configure the realtime database - */ - Database database(); - /** * Configure the firestore */ @@ -77,6 +72,11 @@ interface Firebase { */ Hosting hosting(); + /** + * Configure the realtime database + */ + Database database(); + interface DevService { /** @@ -184,22 +184,36 @@ interface UI extends GenericDevService { } } - } - interface Auth { + interface Auth { - /** - * Configuration for the firebase auth emulator - */ - GenericDevService devservice(); - } + /** + * Configuration for the firebase auth emulator + */ + GenericDevService devservice(); + } - interface Database { + interface Database { + + /** + * Configuration for the realtime database emulator + */ + GenericDevService devservice(); + } + + interface Hosting { + + /** + * Configuration for the hosting emulator + */ + GenericDevService devservice(); + + /** + * Path to the hosting files. + */ + Optional hostingPath(); + } - /** - * Configuration for the realtime database emulator - */ - GenericDevService devservice(); } interface Firestore { @@ -240,19 +254,6 @@ interface Functions { GenericDevService devservice(); } - interface Hosting { - - /** - * Configuration for the hosting emulator - */ - GenericDevService devservice(); - - /** - * Path to the hosting files. - */ - Optional hostingPath(); - } - interface PubSub { /** diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java index a5203183..6b3a5e91 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java @@ -3,6 +3,7 @@ import java.io.File; import java.nio.file.Path; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; @@ -53,7 +54,7 @@ public static Map projectId, Firebase firebase, - Database database, Firestore firestore, Functions functions, PubSub pubsub, @@ -128,8 +127,9 @@ record TestFirebaseDevServiceConfig( record TestFirebase( DevService devservice, - FirebaseDevServiceConfig.Auth auth, - FirebaseDevServiceConfig.Hosting hosting) implements FirebaseDevServiceConfig.Firebase { + FirebaseDevServiceConfig.Firebase.Auth auth, + FirebaseDevServiceConfig.Firebase.Database database, + FirebaseDevServiceConfig.Firebase.Hosting hosting) implements FirebaseDevServiceConfig.Firebase { } record TestFirebaseDevService( @@ -153,11 +153,11 @@ record TestUI( } record TestAuth( - FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.Auth { + FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.Firebase.Auth { } record TestDatabase( - FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.Database { + FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.Firebase.Database { } record TestFirestore( @@ -178,7 +178,7 @@ record TestFunctions( record TestHosting( FirebaseDevServiceConfig.GenericDevService devservice, - Optional hostingPath) implements FirebaseDevServiceConfig.Hosting { + Optional hostingPath) implements FirebaseDevServiceConfig.Firebase.Hosting { } record TestPubSub( From 0be5dad772669abbc3bca91fbfe69ea4f06dd900 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sun, 15 Dec 2024 21:32:56 +0100 Subject: [PATCH 068/101] Refactored to separate package --- .../FirebaseEmulatorContainerCustomConfigTest.java | 5 +---- .../FirebaseEmulatorContainerIntegrationTest.java | 3 +-- .../TestableFirebaseEmulatorContainer.java | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) rename firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/{ => testcontainers}/FirebaseEmulatorContainerCustomConfigTest.java (91%) rename firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/{ => testcontainers}/FirebaseEmulatorContainerIntegrationTest.java (98%) rename firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/{ => testcontainers}/TestableFirebaseEmulatorContainer.java (94%) diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerCustomConfigTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java similarity index 91% rename from firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerCustomConfigTest.java rename to firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java index 941d256d..9896efc4 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerCustomConfigTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java @@ -1,4 +1,4 @@ -package io.quarkiverse.googlecloudservices.firebase.deployment; +package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -13,9 +13,6 @@ import com.google.firebase.FirebaseOptions; -import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.CustomFirebaseConfigReader; -import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; - @Testcontainers public class FirebaseEmulatorContainerCustomConfigTest { diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java similarity index 98% rename from firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java rename to firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java index 85643062..e6437f56 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java @@ -1,4 +1,4 @@ -package io.quarkiverse.googlecloudservices.firebase.deployment; +package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; import static org.junit.jupiter.api.Assertions.*; @@ -42,7 +42,6 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; -import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.Emulator; import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.EmulatorConfig; import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.ExposedPort; diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/TestableFirebaseEmulatorContainer.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/TestableFirebaseEmulatorContainer.java similarity index 94% rename from firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/TestableFirebaseEmulatorContainer.java rename to firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/TestableFirebaseEmulatorContainer.java index 89d4982b..a1c10aef 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/TestableFirebaseEmulatorContainer.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/TestableFirebaseEmulatorContainer.java @@ -1,4 +1,4 @@ -package io.quarkiverse.googlecloudservices.firebase.deployment; +package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; import java.io.PrintStream; import java.util.Optional; @@ -9,8 +9,6 @@ import com.google.firebase.FirebaseOptions; import com.google.firebase.internal.EmulatorCredentials; -import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; - /** * Subclass of {@link FirebaseEmulatorContainer} which has some extra facilities to ease testing. Functionally * this class is equivalent of its superclass with respect to the testing we need to perform. From 59b926c4c6511ae7e18ef33be9fb2b7269848b4e Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sun, 15 Dec 2024 21:38:30 +0100 Subject: [PATCH 069/101] Import changes from testcontainers-firebase module --- firebase-devservices/deployment/firebase.json | 14 + firebase-devservices/deployment/pom.xml | 2 +- .../FirebaseEmulatorConfigBuilder.java | 1 - .../CustomFirebaseConfigReader.java | 51 +- .../FirebaseEmulatorContainer.java | 931 +++++- .../testcontainers/FirebaseJsonBuilder.java | 46 +- .../deployment/src/test/functions/.gitignore | 1 + .../deployment/src/test/functions/index.js | 8 + .../src/test/functions/package-lock.json | 2694 +++++++++++++++++ .../src/test/functions/package.json | 18 + .../deployment/src/test/hosting/test.me | 1 + ...baseEmulatorContainerCustomConfigTest.java | 63 +- ...ebaseEmulatorContainerIntegrationTest.java | 174 +- .../TestableFirebaseEmulatorContainer.java | 87 +- 14 files changed, 3875 insertions(+), 216 deletions(-) create mode 100644 firebase-devservices/deployment/src/test/functions/.gitignore create mode 100644 firebase-devservices/deployment/src/test/functions/index.js create mode 100644 firebase-devservices/deployment/src/test/functions/package-lock.json create mode 100644 firebase-devservices/deployment/src/test/functions/package.json create mode 100644 firebase-devservices/deployment/src/test/hosting/test.me diff --git a/firebase-devservices/deployment/firebase.json b/firebase-devservices/deployment/firebase.json index 03be7de1..b57a1592 100644 --- a/firebase-devservices/deployment/firebase.json +++ b/firebase-devservices/deployment/firebase.json @@ -9,6 +9,14 @@ "host": "0.0.0.0", "port": 7005 }, + "hosting": { + "host": "0.0.0.0", + "port": 7006 + }, + "functions": { + "host": "0.0.0.0", + "port": 7007 + }, "ui": { "host": "0.0.0.0", "enabled": true, @@ -16,6 +24,12 @@ }, "singleProjectMode": true }, + "hosting": { + "public": "src/test/hosting" + }, + "functions": { + "source": "src/test/functions" + }, "firestore": { "rules": "firestore.rules", "indexes": "firestore.indexes.json" diff --git a/firebase-devservices/deployment/pom.xml b/firebase-devservices/deployment/pom.xml index f065ab42..e930eca7 100644 --- a/firebase-devservices/deployment/pom.xml +++ b/firebase-devservices/deployment/pom.xml @@ -139,7 +139,7 @@ quarkus-google-cloud-common-grpc and Quarkus includes the netty library --> 1.2.2 ${basedir}/src/main/schema - io.quarkiverse.googlecloudservices.firebase.deployment.firebase.json + io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.json jackson2 true diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java index 6b3a5e91..d39a1d29 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java @@ -3,7 +3,6 @@ import java.io.File; import java.nio.file.Path; import java.util.Map; -import java.util.Optional; import java.util.stream.Collectors; import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java index f93a7567..c59a4a6b 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java @@ -12,13 +12,24 @@ import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper; -import io.quarkiverse.googlecloudservices.firebase.deployment.firebase.json.Emulators; -import io.quarkiverse.googlecloudservices.firebase.deployment.firebase.json.FirebaseConfig; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.json.Emulators; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.json.FirebaseConfig; -public class CustomFirebaseConfigReader { +/** + * Reader for the firebase.json file to convert it to the + * {@link io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.FirebaseConfig} + */ +class CustomFirebaseConfigReader { private final ObjectMapper objectMapper = new ObjectMapper(); + /** + * Read the firebase config from a firebase.json file + * + * @param customFirebaseJson The path to the file + * @return The configuration + * @throws IOException In case the file could not be read + */ public FirebaseEmulatorContainer.FirebaseConfig readFromFirebase(Path customFirebaseJson) throws IOException { var root = readCustomFirebaseJson(customFirebaseJson); @@ -26,6 +37,7 @@ public FirebaseEmulatorContainer.FirebaseConfig readFromFirebase(Path customFire readHosting(root.getHosting()), readStorage(root.getStorage()), readFirestore(root.getFirestore()), + readFunctions(root.getFunctions()), readEmulators(root.getEmulators())); } @@ -125,9 +137,7 @@ private FirebaseEmulatorContainer.FirestoreConfig readFirestore(Object firestore rulesFile, indexesFile); } else { - return new FirebaseEmulatorContainer.FirestoreConfig( - Optional.empty(), - Optional.empty()); + return FirebaseEmulatorContainer.FirestoreConfig.DEFAULT; } } @@ -143,8 +153,7 @@ private FirebaseEmulatorContainer.HostingConfig readHosting(Object hosting) { return new FirebaseEmulatorContainer.HostingConfig( publicDir); } else { - return new FirebaseEmulatorContainer.HostingConfig( - Optional.empty()); + return FirebaseEmulatorContainer.HostingConfig.DEFAULT; } } @@ -160,8 +169,30 @@ private FirebaseEmulatorContainer.StorageConfig readStorage(Object storage) { return new FirebaseEmulatorContainer.StorageConfig( rulesFile); } else { - return new FirebaseEmulatorContainer.StorageConfig( - Optional.empty()); + return FirebaseEmulatorContainer.StorageConfig.DEFAULT; + } + } + + private FirebaseEmulatorContainer.FunctionsConfig readFunctions(Object functions) { + if (functions instanceof Map) { + @SuppressWarnings("unchecked") + Map functionsMap = (Map) functions; + + var functionsPath = Optional + .ofNullable(functionsMap.get("source")) + .map(String.class::cast) + .map(this::resolvePath); + + var ignores = Optional + .ofNullable(functionsMap.get("ignores")) + .map(String[].class::cast) + .orElse(new String[0]); + + return new FirebaseEmulatorContainer.FunctionsConfig( + functionsPath, + ignores); + } else { + return FirebaseEmulatorContainer.FunctionsConfig.DEFAULT; } } diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java index c1846efc..173ba9b4 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java @@ -1,13 +1,18 @@ package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; +import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.util.*; +import java.util.function.Consumer; import java.util.stream.Collectors; -import org.jboss.logging.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.event.Level; import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.output.OutputFrame; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.images.builder.dockerfile.DockerfileBuilder; @@ -17,12 +22,12 @@ */ public class FirebaseEmulatorContainer extends GenericContainer { - private static final Logger LOGGER = Logger.getLogger(FirebaseEmulatorContainer.class.getName()); + private static final Logger LOGGER = LoggerFactory.getLogger(FirebaseEmulatorContainer.class); - public static final String FIREBASE_ROOT = "/srv/firebase"; - public static final String FIREBASE_HOSTING_PATH = FIREBASE_ROOT + "/public"; - public static final String EMULATOR_DATA_PATH = FIREBASE_ROOT + "/data"; - public static final String EMULATOR_EXPORT_PATH = EMULATOR_DATA_PATH + "/emulator-data"; + private static final String FIREBASE_ROOT = "/srv/firebase"; + private static final String FIREBASE_HOSTING_PATH = FIREBASE_ROOT + "/" + FirebaseJsonBuilder.FIREBASE_HOSTING_SUBPATH; + private static final String EMULATOR_DATA_PATH = FIREBASE_ROOT + "/data"; + private static final String EMULATOR_EXPORT_PATH = EMULATOR_DATA_PATH + "/emulator-data"; /** * Set of possible emulators (or components/services). @@ -113,9 +118,12 @@ public enum Emulator { "pubsub", "pubsub"); + /** + * The default port on which the emulator is running. + */ public final int internalPort; - public final String configProperty; - public final String emulatorName; + final String configProperty; + final String emulatorName; Emulator(int internalPort, String configProperty, String onlyArgument) { this.internalPort = internalPort; @@ -132,7 +140,9 @@ public enum Emulator { */ public record ExposedPort(Integer fixedPort) { - public boolean isFixed() { + public static final ExposedPort RANDOM_PORT = new ExposedPort(null); + + boolean isFixed() { return fixedPort != null; } } @@ -143,11 +153,90 @@ public boolean isFixed() { * @param imageName The name of the docker image * @param userId The user id to run the docker image * @param groupId The group id to run the docker image + * @param followStdOut Pipe stdout of the container to stdout of the host + * @param followStdErr Pipe stderr of the container to stderr of the host + * @param afterStart Callback to handle additional logic after the container has started. */ public record DockerConfig( String imageName, Optional userId, - Optional groupId) { + Optional groupId, + boolean followStdOut, + boolean followStdErr, + Consumer afterStart) { + + /** + * Default settings + */ + public static final DockerConfig DEFAULT = new DockerConfig( + DEFAULT_IMAGE_NAME, + Optional.empty(), + Optional.empty(), + true, + true, + null); + } + + /** + * Record to hold the argument for the CLI executable. + * + * @param projectId The project ID, needed when running with the auth emulator + * @param token The Google Cloud CLI token to use for authentication. Needed for firebase hosting + * @param javaToolOptions The options to pass to the java based emulators + * @param emulatorData The path to the directory where to store the emulator data + * @param importExport Specify whether to import, export or do both with the emulator data + * @param debug Whether to run with the --debug flag + */ + public record CliArgumentsConfig( + Optional projectId, + Optional token, + Optional javaToolOptions, + Optional emulatorData, + ImportExport importExport, + boolean debug) { + public static final CliArgumentsConfig DEFAULT = new CliArgumentsConfig( + Optional.empty(), + Optional.empty(), + Optional.empty(), + Optional.empty(), + ImportExport.IMPORT_EXPORT, + false); + } + + /** + * Behaviour of the import/export data. + */ + public enum ImportExport { + /** + * Only import the data + */ + IMPORT_ONLY(true, false), + + /** + * Only export the data + */ + EXPORT_ONLY(false, true), + + /** + * Both import and export the data. + */ + IMPORT_EXPORT(true, true); + + private final boolean doImport; + private final boolean doExport; + + ImportExport(boolean doImport, boolean doExport) { + this.doImport = doImport; + this.doExport = doExport; + } + + boolean isDoImport() { + return doImport; + } + + boolean isDoExport() { + return doExport; + } } /** @@ -157,6 +246,9 @@ public record DockerConfig( */ public record HostingConfig( Optional hostingContentDir) { + + public static final HostingConfig DEFAULT = new HostingConfig( + Optional.empty()); } /** @@ -166,6 +258,9 @@ public record HostingConfig( */ public record StorageConfig( Optional rulesFile) { + + public static final StorageConfig DEFAULT = new StorageConfig( + Optional.empty()); } /** @@ -177,19 +272,42 @@ public record StorageConfig( public record FirestoreConfig( Optional rulesFile, Optional indexesFile) { + + public static final FirestoreConfig DEFAULT = new FirestoreConfig( + Optional.empty(), + Optional.empty()); + } + + /** + * Functions configuration + * + * @param functionsPath The location for the functions sources + * @param ignores The files to ignore when creating the function + */ + public record FunctionsConfig( + Optional functionsPath, + String[] ignores) { + + public static FunctionsConfig DEFAULT = new FunctionsConfig( + Optional.empty(), + new String[0]); } /** + * The firebase configuration, this record mimics the various items which can be configured using the + * firebase.json file. * * @param hostingConfig The firebase hosting configuration * @param storageConfig The storage configuration * @param firestoreConfig The firestore configuration + * @param functionsConfig The functions configuration * @param services The exposed services configuration */ public record FirebaseConfig( HostingConfig hostingConfig, StorageConfig storageConfig, FirestoreConfig firestoreConfig, + FunctionsConfig functionsConfig, Map services) { } @@ -198,25 +316,581 @@ public record FirebaseConfig( * * @param dockerConfig The docker configuration * @param firebaseVersion The firebase version to use - * @param projectId The project ID, needed when running with the auth emulator - * @param token The Google Cloud CLI token to use for authentication. Needed for firebase hosting + * @param cliArguments The arguments to the CLI * @param customFirebaseJson The path to a custom firebase - * @param javaToolOptions The options to pass to the java based emulators - * @param emulatorData The path to the directory where to store the emulator data * @param firebaseConfig The firebase configuration */ public record EmulatorConfig( DockerConfig dockerConfig, String firebaseVersion, - Optional projectId, - Optional token, + CliArgumentsConfig cliArguments, Optional customFirebaseJson, - Optional javaToolOptions, - Optional emulatorData, FirebaseConfig firebaseConfig) { } + // Use node:20 for now because of https://github.com/firebase/firebase-tools/issues/7173 + /** + * The default image to use for building the docker image. + */ + public static final String DEFAULT_IMAGE_NAME = "node:20-alpine"; + /** + * The default version of the firebase tools to install. + */ + public static final String DEFAULT_FIREBASE_VERSION = "latest"; + + /** + * Builder for the {@link FirebaseEmulatorContainer} configuration. + */ + public static class Builder { + + private DockerConfig dockerConfig = DockerConfig.DEFAULT; + private String firebaseVersion = DEFAULT_FIREBASE_VERSION; + private CliArgumentsConfig cliArguments = CliArgumentsConfig.DEFAULT; + + private Path customFirebaseJson; + private FirebaseConfig firebaseConfig; + + private Builder() { + } + + /** + * Configure the docker options + * + * @return THe docker config builder + */ + public DockerConfigBuilder withDockerConfig() { + return new DockerConfigBuilder(); + } + + /** + * Configure the firebase version + * + * @param firebaseVersion The firebase version + * @return The builder + */ + public Builder withFirebaseVersion(String firebaseVersion) { + this.firebaseVersion = firebaseVersion; + return this; + } + + /** + * Configure the CLI argument options + * + * @return The CLI Builder + */ + public CliBuilder withCliArguments() { + return new CliBuilder(); + } + + /** + * Read the configuration from the custom firebase.json file. + * + * @param customFirebaseJson The path to the custom firebase json + * @return The builder + * @throws IOException In case the file could not be read. + */ + public Builder readFromFirebaseJson(Path customFirebaseJson) throws IOException { + var reader = new CustomFirebaseConfigReader(); + this.firebaseConfig = reader.readFromFirebase(customFirebaseJson); + this.customFirebaseJson = customFirebaseJson; + return this; + } + + /** + * Configure the firebase emulators + * + * @return The firebase config builder + */ + public FirebaseConfigBuilder withFirebaseConfig() { + return new FirebaseConfigBuilder(); + } + + /** + * Build the configuration + * + * @return The emulator configuration. + */ + protected EmulatorConfig buildConfig() { + if (firebaseConfig == null) { + // Try to autoload the firebase.json configuration + var defaultFirebaseJson = new File("firebase.json").toPath(); + + try { + readFromFirebaseJson(defaultFirebaseJson); + } catch (IOException e) { + throw new IllegalStateException( + "Firebase was not configured and could not auto-read from " + defaultFirebaseJson); + } + } + + return new EmulatorConfig( + dockerConfig, + firebaseVersion, + cliArguments, + Optional.ofNullable(customFirebaseJson), + firebaseConfig); + } + + /** + * Build the final configuration + * + * @return the final configuration. + */ + public FirebaseEmulatorContainer build() { + return new FirebaseEmulatorContainer(buildConfig()); + } + + /** + * Builder for the docker configuration. + */ + public class DockerConfigBuilder { + + private DockerConfigBuilder() { + } + + /** + * Configure the base image to use + * + * @param imageName The image name + * @return The builder + */ + public DockerConfigBuilder withImage(String imageName) { + Builder.this.dockerConfig = new DockerConfig( + imageName, + Builder.this.dockerConfig.userId(), + Builder.this.dockerConfig.groupId(), + Builder.this.dockerConfig.followStdOut(), + Builder.this.dockerConfig.followStdErr(), + Builder.this.dockerConfig.afterStart()); + return this; + } + + /** + * Configure the user id to use within docker + * + * @param userId The user id + * @return The builder + */ + public DockerConfigBuilder withUserId(int userId) { + return withUserId(Optional.of(userId)); + } + + /** + * Try to configure the user id to use within docker from an environment variable. + * + * @param env The environment variable + * @return The builder + */ + public DockerConfigBuilder withUserIdFromEnv(String env) { + return withUserId(readIdFromEnv(env)); + } + + private DockerConfigBuilder withUserId(Optional userId) { + Builder.this.dockerConfig = new DockerConfig( + Builder.this.dockerConfig.imageName(), + userId, + Builder.this.dockerConfig.groupId(), + Builder.this.dockerConfig.followStdOut(), + Builder.this.dockerConfig.followStdErr(), + Builder.this.dockerConfig.afterStart()); + return this; + } + + /** + * Configure the group id to use within docker + * + * @param groupId The group id + * @return The builder + */ + public DockerConfigBuilder withGroupId(int groupId) { + return withGroupId(Optional.of(groupId)); + } + + /** + * Try to configure the group id to use within docker from an environment variable. + * + * @param env The environment variable + * @return The builder + */ + public DockerConfigBuilder withGroupIdFromEnv(String env) { + return withGroupId(readIdFromEnv(env)); + } + + private DockerConfigBuilder withGroupId(Optional groupId) { + Builder.this.dockerConfig = new DockerConfig( + Builder.this.dockerConfig.imageName(), + Builder.this.dockerConfig.userId(), + groupId, + Builder.this.dockerConfig.followStdOut(), + Builder.this.dockerConfig.followStdErr(), + Builder.this.dockerConfig.afterStart()); + return this; + } + + /** + * Pipe the container stdout to the host stdout. This can ease debugging of container issues. + * + * @param followStdOut Whether to pipe the container stdout to the host stdout + * @return The builder + */ + public DockerConfigBuilder followStdOut(boolean followStdOut) { + Builder.this.dockerConfig = new DockerConfig( + Builder.this.dockerConfig.imageName(), + Builder.this.dockerConfig.userId(), + Builder.this.dockerConfig.groupId(), + followStdOut, + Builder.this.dockerConfig.followStdErr(), + Builder.this.dockerConfig.afterStart()); + return this; + } + + /** + * Pipe the container stdout to the host stderr. This can ease debugging of container issues. + * + * @param followStdErr Whether to pipe the container stderr to the host stdout + * @return The builder + */ + public DockerConfigBuilder followStdErr(boolean followStdErr) { + Builder.this.dockerConfig = new DockerConfig( + Builder.this.dockerConfig.imageName(), + Builder.this.dockerConfig.userId(), + Builder.this.dockerConfig.groupId(), + Builder.this.dockerConfig.followStdOut(), + followStdErr, + Builder.this.dockerConfig.afterStart()); + return this; + } + + /** + * Set a callback to run after the container has started. + * + * @param afterStart Callback to be executed after the container has started + * @return The builder + */ + public DockerConfigBuilder afterStart(Consumer afterStart) { + Builder.this.dockerConfig = new DockerConfig( + Builder.this.dockerConfig.imageName(), + Builder.this.dockerConfig.userId(), + Builder.this.dockerConfig.groupId(), + Builder.this.dockerConfig.followStdOut(), + Builder.this.dockerConfig.followStdErr(), + afterStart); + return this; + } + + /** + * Finish the docker configuration + * + * @return The primary builder + */ + public Builder done() { + return Builder.this; + } + + private Optional readIdFromEnv(String env) { + try { + return Optional + .ofNullable(System.getenv(env)) + .map(Integer::valueOf); + } catch (NumberFormatException e) { + return Optional.empty(); + } + } + } + + /** + * Builder for the CLI Arguments configuration + */ + public class CliBuilder { + private String projectId; + private String token; + private String javaToolOptions; + private Path emulatorData; + private ImportExport importExport; + private boolean debug; + + /** + * The CLI Builder constructor + */ + private CliBuilder() { + this.projectId = Builder.this.cliArguments.projectId.orElse(null); + this.token = Builder.this.cliArguments.token.orElse(null); + this.javaToolOptions = Builder.this.cliArguments.javaToolOptions.orElse(null); + this.emulatorData = Builder.this.cliArguments.emulatorData.orElse(null); + this.importExport = Builder.this.cliArguments.importExport; + this.debug = Builder.this.cliArguments.debug; + } + + /** + * Configure the project id + * + * @param projectId The project id + * @return The builder + */ + public CliBuilder withProjectId(String projectId) { + this.projectId = projectId; + return this; + } + + /** + * Configure the Google auth token to use + * + * @param token The token + * @return The builder + */ + public CliBuilder withToken(String token) { + this.token = token; + return this; + } + + /** + * Configure the java tool options + * + * @param javaToolOptions The java tool options + * @return The builder + */ + public CliBuilder withJavaToolOptions(String javaToolOptions) { + this.javaToolOptions = javaToolOptions; + return this; + } + + /** + * Configure the location to import/export the emulator data + * + * @param emulatorData The emulator data + * @return The builder + */ + public CliBuilder withEmulatorData(Path emulatorData) { + this.emulatorData = emulatorData; + return this; + } + + /** + * Set the import/export behaviour for the specified emulator data. This setting is inactive unless + * {@link #withEmulatorData(Path)} is set. + * + * @param importExport The import/export setting + * @return The builder + */ + public CliBuilder withImportExport(ImportExport importExport) { + this.importExport = importExport; + return this; + } + + /** + * Run the firebase tools with a debug flag + * + * @param debug Whether to run with debug or not + * @return The builder + */ + public CliBuilder withDebug(boolean debug) { + this.debug = debug; + return this; + } + + /** + * Finish the builder + * + * @return The parent builder + */ + public Builder done() { + Builder.this.cliArguments = new CliArgumentsConfig( + Optional.ofNullable(this.projectId), + Optional.ofNullable(this.token), + Optional.ofNullable(this.javaToolOptions), + Optional.ofNullable(this.emulatorData), + this.importExport, + this.debug); + return Builder.this; + } + } + + /** + * Builder for the Firebase configuration + */ + public class FirebaseConfigBuilder { + + private HostingConfig hostingConfig = HostingConfig.DEFAULT; + private StorageConfig storageConfig = StorageConfig.DEFAULT; + private FirestoreConfig firestoreConfig = FirestoreConfig.DEFAULT; + private FunctionsConfig functionsConfig = FunctionsConfig.DEFAULT; + private final Map services = new HashMap<>(); + + /** + * Create a new builder + */ + public FirebaseConfigBuilder() { + } + + /** + * Configure the directory where to find the hosting files + * + * @param hostingContentDir The hosting directory + * @return The builder + */ + public FirebaseConfigBuilder withHostingPath(Path hostingContentDir) { + this.hostingConfig = new HostingConfig( + Optional.of(hostingContentDir)); + return this; + } + + /** + * Configure the Google Cloud storage rules file + * + * @param rulesFile The rules file. + * @return The builder + */ + public FirebaseConfigBuilder withStorageRules(Path rulesFile) { + this.storageConfig = new StorageConfig( + Optional.of(rulesFile)); + return this; + } + + /** + * Configure the Firestore rules file + * + * @param rulesFile The rules file + * @return The builder + */ + public FirebaseConfigBuilder withFirestoreRules(Path rulesFile) { + this.firestoreConfig = new FirestoreConfig( + Optional.of(rulesFile), + this.firestoreConfig.indexesFile); + return this; + } + + /** + * Configure the firestore indexes file + * + * @param indexes The indexes file + * @return The builder + */ + public FirebaseConfigBuilder withFirestoreIndexes(Path indexes) { + this.firestoreConfig = new FirestoreConfig( + this.firestoreConfig.rulesFile(), + Optional.of(indexes)); + return this; + } + + /** + * Configure the input directory for the functions + * + * @param functions The path to the functions + * @return The builder + */ + public FirebaseConfigBuilder withFunctionsFromPath(Path functions) { + this.functionsConfig = new FunctionsConfig( + Optional.of(functions), + this.functionsConfig.ignores()); + return this; + } + + /** + * Configure the ignores for the functions directory + * + * @param ignores The ignores + * @return The builder + */ + public FirebaseConfigBuilder withFunctionIgnores(String[] ignores) { + this.functionsConfig = new FunctionsConfig( + this.functionsConfig.functionsPath, + ignores); + return this; + } + + /** + * Include an emulator on a random port + * + * @param emulator The emulator + * @return The builder + */ + public FirebaseConfigBuilder withEmulator(Emulator emulator) { + this.services.put(emulator, ExposedPort.RANDOM_PORT); + return this; + } + + /** + * Include emulators on a random port + * + * @param emulators The emulators + * @return The builder + */ + public FirebaseConfigBuilder withEmulators(Emulator... emulators) { + for (Emulator emulator : emulators) { + withEmulator(emulator); + } + return this; + } + + /** + * Include an emulator on a fixed port + * + * @param emulator The emulator + * @param port The port to expose on + * @return The builder + */ + public FirebaseConfigBuilder withEmulatorOnFixedPort(Emulator emulator, int port) { + this.services.put(emulator, new ExposedPort(port)); + return this; + } + + /** + * Include emulators on fixed ports + * + * @param emulatorsAndPorts Alternating the {@link Emulator} and the {@link Integer} port. + * @return The builder + * @throws IllegalArgumentException In case the arguments don't alternate between Emulator and Port. + */ + public FirebaseConfigBuilder withEmulatorsOnPorts(Object... emulatorsAndPorts) { + if (emulatorsAndPorts.length % 2 != 0) { + throw new IllegalArgumentException("Emulators and ports must both be specified alternating"); + } + + try { + for (int i = 0; i < emulatorsAndPorts.length; i += 2) { + var emulator = (Emulator) emulatorsAndPorts[i]; + var port = (Integer) emulatorsAndPorts[i + 1]; + withEmulatorOnFixedPort(emulator, port); + } + } catch (ClassCastException e) { + throw new IllegalArgumentException("Emulators and ports must be specified alternating"); + } + + return this; + } + + /** + * Finish the firebase configuration + * + * @return The primary builder + */ + public Builder done() { + Builder.this.firebaseConfig = new FirebaseConfig( + hostingConfig, + storageConfig, + firestoreConfig, + functionsConfig, + services); + Builder.this.customFirebaseJson = null; + + return Builder.this; + } + } + } + private final Map services; + private final boolean followStdOut; + private final boolean followStdErr; + private final Consumer afterStart; + + /** + * Create the builder for the emulator container + * + * @return The builder + */ + public static Builder builder() { + return new Builder(); + } /** * Creates a new Firebase Emulator container @@ -226,18 +900,63 @@ public record EmulatorConfig( public FirebaseEmulatorContainer(EmulatorConfig emulatorConfig) { super(new FirebaseDockerBuilder(emulatorConfig).build()); - emulatorConfig.emulatorData().ifPresent(path -> { + this.services = emulatorConfig.firebaseConfig().services; + this.followStdOut = emulatorConfig.dockerConfig().followStdOut(); + this.followStdErr = emulatorConfig.dockerConfig().followStdErr(); + this.afterStart = emulatorConfig.dockerConfig().afterStart(); + + emulatorConfig.cliArguments().emulatorData().ifPresent(path -> { // https://firebase.google.com/docs/emulator-suite/install_and_configure#export_and_import_emulator_data // Mount the volume to the specified path this.withFileSystemBind(path.toString(), EMULATOR_DATA_PATH, BindMode.READ_WRITE); }); - emulatorConfig.firebaseConfig().hostingConfig().hostingContentDir().ifPresent(hostingPath -> { + if (this.services.containsKey(Emulator.FIREBASE_HOSTING)) { + var hostingPath = emulatorConfig + .firebaseConfig() + .hostingConfig() + .hostingContentDir() + .map(Path::toString) + .orElse(new File(FirebaseJsonBuilder.FIREBASE_HOSTING_SUBPATH).getAbsolutePath()); + // Mount volume for static hosting content - this.withFileSystemBind(hostingPath.toString(), FIREBASE_HOSTING_PATH, BindMode.READ_ONLY); - }); + this.withFileSystemBind(hostingPath, containerHostingPath(emulatorConfig), BindMode.READ_ONLY); + } - this.services = emulatorConfig.firebaseConfig().services; + if (this.services.containsKey(Emulator.CLOUD_FUNCTIONS)) { + var functionsPath = emulatorConfig + .firebaseConfig() + .functionsConfig() + .functionsPath() + .map(Path::toString) + .orElse(new File(FirebaseJsonBuilder.FIREBASE_FUNCTIONS_SUBPATH).getAbsolutePath()); + + // Mount volume for functions + this.withFileSystemBind(functionsPath, containerFunctionsPath(emulatorConfig), BindMode.READ_ONLY); + } + } + + static String containerHostingPath(EmulatorConfig emulatorConfig) { + var hostingPath = emulatorConfig.firebaseConfig().hostingConfig().hostingContentDir(); + + return hostingPath + .map(Path::isAbsolute) + .map(absolute -> { + if (absolute) { + return FIREBASE_HOSTING_PATH; + } else { + return FIREBASE_ROOT + "/" + hostingPath.get(); + } + }).orElse(FIREBASE_HOSTING_PATH); + } + + static String containerFunctionsPath(EmulatorConfig emulatorConfig) { + return FIREBASE_ROOT + "/" + emulatorConfig + .firebaseConfig() + .functionsConfig() + .functionsPath() + .map(Path::toString) + .orElse(FirebaseJsonBuilder.FIREBASE_FUNCTIONS_SUBPATH); } private static class FirebaseDockerBuilder { @@ -277,13 +996,14 @@ public ImageFromDockerfile build() { this.includeStorageFiles(); this.setupDataImportExport(); this.setupHosting(); + this.setupFunctions(); this.runExecutable(); return result; } private void validateConfiguration() { - if (isEmulatorEnabled(Emulator.AUTHENTICATION) && emulatorConfig.projectId().isEmpty()) { + if (isEmulatorEnabled(Emulator.AUTHENTICATION) && emulatorConfig.cliArguments().projectId().isEmpty()) { throw new IllegalStateException("Can't create Firebase Auth emulator. Google Project id is required"); } @@ -306,6 +1026,39 @@ private void validateConfiguration() { } } + if (emulatorConfig.customFirebaseJson.isPresent()) { + var hostingDirIsAbsolute = emulatorConfig.firebaseConfig.hostingConfig.hostingContentDir + .map(Path::isAbsolute) + .orElse(false); + + if (hostingDirIsAbsolute) { + throw new IllegalStateException( + "When using a custom firebase.json, the hosting path must be relative to the firebase.json file"); + } + + var firebasePath = emulatorConfig.customFirebaseJson.get().toAbsolutePath().getParent(); + + var hostingDirIsChildOfFirebaseJsonParent = emulatorConfig.firebaseConfig.hostingConfig.hostingContentDir + .map(Path::toAbsolutePath) + .map(h -> h.startsWith(firebasePath)) + .orElse(true); + + if (!hostingDirIsChildOfFirebaseJsonParent) { + throw new IllegalStateException( + "When using a custom firebase.json, the hosting path must be in the same subtree as the firebase.json file"); + } + } + + if (emulatorConfig.firebaseConfig.functionsConfig.functionsPath.isPresent()) { + var functionsDirIsAbsolute = emulatorConfig.firebaseConfig.functionsConfig.functionsPath + .map(Path::isAbsolute) + .orElse(false); + + if (functionsDirIsAbsolute) { + throw new IllegalStateException("Functions path cannot be absolute"); + } + } + // TODO: Validate if a custom firebase.json is defined, that the hosts are defined as 0.0.0.0 } @@ -315,12 +1068,12 @@ private void configureBaseImage() { private void initialSetup() { dockerBuilder - .run("apk --no-cache add openjdk11-jre bash curl openssl gettext nano nginx sudo && " + + .run("apk --no-cache add openjdk17-jre bash curl openssl gettext nano nginx sudo && " + "npm cache clean --force && " + "npm i -g firebase-tools@" + emulatorConfig.firebaseVersion() + " && " + "deluser nginx && delgroup abuild && delgroup ping && " + "mkdir -p " + FIREBASE_ROOT + " && " + - "mkdir -p " + FIREBASE_HOSTING_PATH + " && " + + "mkdir -p " + EMULATOR_DATA_PATH + " && " + "mkdir -p " + EMULATOR_EXPORT_PATH + " && " + "chmod 777 -R /srv/*"); @@ -346,11 +1099,13 @@ private String downloadEmulatorCommand(Emulator emulator, String downloadId) { } private void authenticateToFirebase() { - emulatorConfig.token().ifPresent(token -> dockerBuilder.env("FIREBASE_TOKEN", token)); + emulatorConfig.cliArguments().token().ifPresent( + token -> dockerBuilder.env("FIREBASE_TOKEN", token)); } private void setupJavaToolOptions() { - emulatorConfig.javaToolOptions().ifPresent(toolOptions -> dockerBuilder.env("JAVA_TOOL_OPTIONS", toolOptions)); + emulatorConfig.cliArguments().javaToolOptions().ifPresent( + toolOptions -> dockerBuilder.env("JAVA_TOOL_OPTIONS", toolOptions)); } private void addFirebaseJson() { @@ -401,13 +1156,22 @@ private void generateFirebaseJson() { } private void setupDataImportExport() { - emulatorConfig.emulatorData().ifPresent(emulator -> this.dockerBuilder.volume(EMULATOR_DATA_PATH)); + emulatorConfig.cliArguments().emulatorData().ifPresent( + emulator -> this.dockerBuilder.volume(EMULATOR_DATA_PATH)); } private void setupHosting() { // Specify public directory if hosting is enabled if (emulatorConfig.firebaseConfig().hostingConfig().hostingContentDir().isPresent()) { - this.dockerBuilder.volume(FIREBASE_HOSTING_PATH); + this.dockerBuilder.run("mkdir -p " + containerHostingPath(emulatorConfig)); + this.dockerBuilder.volume(containerHostingPath(emulatorConfig)); + } + } + + private void setupFunctions() { + if (emulatorConfig.firebaseConfig().functionsConfig().functionsPath.isPresent()) { + this.dockerBuilder.run("mkdir -p " + containerFunctionsPath(emulatorConfig)); + this.dockerBuilder.volume(containerFunctionsPath(emulatorConfig)); } } @@ -428,6 +1192,8 @@ private void setupUserAndGroup() { var runCmd = String.join(" && ", commands); + LOGGER.info("Running docker container as user/group: {}:{}", user, group); + dockerBuilder .run(runCmd) .user(user + ":" + group); @@ -446,31 +1212,52 @@ private void runExecutable() { arguments.add("emulators:start"); - emulatorConfig.projectId() + emulatorConfig.cliArguments().projectId() .map(id -> "--project") .ifPresent(arguments::add); - emulatorConfig.projectId() + emulatorConfig.cliArguments().projectId() .ifPresent(arguments::add); - emulatorConfig - .emulatorData() - .map(path -> "--import") - .ifPresent(arguments::add); + if (emulatorConfig.cliArguments().debug) { + arguments.add("--debug"); + } - /* - * We write the data to a subdirectory of the mount point. The firebase emulator tries to remove and - * recreate the mount-point directory, which will obviously fail. By using a subdirectory, export succeeds. - */ - emulatorConfig - .emulatorData() - .map(path -> EMULATOR_EXPORT_PATH) - .ifPresent(arguments::add); + if (emulatorConfig.cliArguments().importExport.isDoExport()) { + emulatorConfig + .cliArguments() + .emulatorData() + .map(path -> "--import") + .ifPresent(arguments::add); + + /* + * We write the data to a subdirectory of the mount point. The firebase emulator tries to remove and + * recreate the mount-point directory, which will obviously fail. By using a subdirectory, export succeeds. + */ + emulatorConfig + .cliArguments() + .emulatorData() + .map(path -> EMULATOR_EXPORT_PATH) + .ifPresent(arguments::add); + } - emulatorConfig - .emulatorData() - .map(path -> "--export-on-exit") - .ifPresent(arguments::add); + if (emulatorConfig.cliArguments().importExport.isDoExport()) { + emulatorConfig + .cliArguments() + .emulatorData() + .map(path -> "--export-on-exit") + .ifPresent(arguments::add); + + /* + * We write the data to a subdirectory of the mount point. The firebase emulator tries to remove and + * recreate the mount-point directory, which will obviously fail. By using a subdirectory, export succeeds. + */ + emulatorConfig + .cliArguments() + .emulatorData() + .map(path -> EMULATOR_EXPORT_PATH) + .ifPresent(arguments::add); + } dockerBuilder.entryPoint(new String[] { "/usr/local/bin/firebase" }); dockerBuilder.cmd(arguments.toArray(new String[0])); @@ -481,6 +1268,26 @@ private boolean isEmulatorEnabled(Emulator emulator) { } } + /** + * Override start to handle logging redirection + */ + @Override + public void start() { + super.start(); + + if (followStdOut) { + followOutput(this::writeToStdOut, OutputFrame.OutputType.STDOUT); + } + + if (followStdErr) { + followOutput(this::writeToStdErr, OutputFrame.OutputType.STDERR); + } + + if (afterStart != null) { + afterStart.accept(this); + } + } + @Override public void stop() { /* @@ -514,6 +1321,11 @@ public void configure() { waitingFor(Wait.forLogMessage(".*Emulator Hub running at.*", 1)); } + /** + * Get the various endpoints for the emulators. The map values are in the form of a string "host:port". + * + * @return The emulator endpoints + */ public Map emulatorEndpoints() { return services.keySet() .stream() @@ -522,6 +1334,12 @@ public Map emulatorEndpoints() { this::getEmulatorEndpoint)); } + /** + * Return the TCP port an emulator is listening on. + * + * @param emulator The emulator + * @return The TC Port + */ public Integer emulatorPort(Emulator emulator) { var exposedPort = services.get(emulator); if (exposedPort.isFixed()) { @@ -531,6 +1349,11 @@ public Integer emulatorPort(Emulator emulator) { } } + /** + * Get the ports on which the emulators are running. + * + * @return A map {@link Emulator} -> {@link Integer} indicating the TCP port the emulator is running on. + */ public Map emulatorPorts() { return services.keySet() .stream() @@ -539,6 +1362,18 @@ public Map emulatorPorts() { this::emulatorPort)); } + private void writeToStdOut(OutputFrame frame) { + writeOutputFrame(frame, Level.INFO); + } + + private void writeToStdErr(OutputFrame frame) { + writeOutputFrame(frame, Level.ERROR); + } + + private void writeOutputFrame(OutputFrame frame, Level level) { + LOGGER.atLevel(level).log(frame.getUtf8StringWithoutLineEnding()); + } + private String getEmulatorEndpoint(Emulator emulator) { return this.getHost() + ":" + emulatorPort(emulator); } diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java index 15737742..70057563 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseJsonBuilder.java @@ -1,6 +1,7 @@ package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; -import java.io.*; +import java.io.IOException; +import java.io.StringWriter; import java.nio.file.Path; import java.util.HashMap; import java.util.Optional; @@ -8,14 +9,16 @@ import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper; -import io.quarkiverse.googlecloudservices.firebase.deployment.firebase.json.*; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.json.*; /** * This class is responsible to generate the Firebase.json file which controls the emulators. */ -public class FirebaseJsonBuilder { +class FirebaseJsonBuilder { private static final String ALL_IP = "0.0.0.0"; + public static final String FIREBASE_HOSTING_SUBPATH = "public"; + public static final String FIREBASE_FUNCTIONS_SUBPATH = "functions"; private final ObjectMapper objectMapper = new ObjectMapper(); private final FirebaseEmulatorContainer.EmulatorConfig emulatorConfig; @@ -40,8 +43,8 @@ private void generateFirebaseConfig() { configureEmulator(); // private ExtensionsConfig extensions; configureFirestore(); - // private Object functions; - // private Object hosting; + configureFunctions(); + configureHosting(); // private Remoteconfig remoteconfig; configureStorage(); } @@ -163,6 +166,39 @@ private void configureFirestore() { } } + private void configureFunctions() { + if (isEmulatorEnabled(FirebaseEmulatorContainer.Emulator.CLOUD_FUNCTIONS)) { + var functions = new HashMap(); + root.setFunctions(functions); + + var functionsPath = emulatorConfig + .firebaseConfig() + .functionsConfig() + .functionsPath() + .map(Path::toString) + .orElseThrow(); + + functions.put("source", functionsPath); + functions.put("ignores", new String[] { "node_modules" }); + } + } + + private void configureHosting() { + if (isEmulatorEnabled(FirebaseEmulatorContainer.Emulator.FIREBASE_HOSTING)) { + var hosting = new HashMap(); + root.setHosting(hosting); + + var hostingPath = emulatorConfig + .firebaseConfig() + .hostingConfig() + .hostingContentDir() + .map(path -> path.isAbsolute() ? FIREBASE_HOSTING_SUBPATH : path.toString()) + .orElseThrow(); + + hosting.put("public", hostingPath); + } + } + private void configureStorage() { if (isEmulatorEnabled(FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE)) { emulatorConfig.firebaseConfig().storageConfig().rulesFile().ifPresent(rules -> { diff --git a/firebase-devservices/deployment/src/test/functions/.gitignore b/firebase-devservices/deployment/src/test/functions/.gitignore new file mode 100644 index 00000000..b512c09d --- /dev/null +++ b/firebase-devservices/deployment/src/test/functions/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/firebase-devservices/deployment/src/test/functions/index.js b/firebase-devservices/deployment/src/test/functions/index.js new file mode 100644 index 00000000..890feb44 --- /dev/null +++ b/firebase-devservices/deployment/src/test/functions/index.js @@ -0,0 +1,8 @@ +// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers. +const {logger} = require("firebase-functions"); +const {onRequest} = require("firebase-functions/v2/https"); + +exports.helloworld = onRequest(async (req, res) => { + logger.log("Received hello world request"); + res.send("Hello world"); +}); diff --git a/firebase-devservices/deployment/src/test/functions/package-lock.json b/firebase-devservices/deployment/src/test/functions/package-lock.json new file mode 100644 index 00000000..fc4671b0 --- /dev/null +++ b/firebase-devservices/deployment/src/test/functions/package-lock.json @@ -0,0 +1,2694 @@ +{ + "name": "functions", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "functions", + "version": "1.0.0", + "license": "Apache-2.0", + "dependencies": { + "firebase-admin": "^13.0.1", + "firebase-functions": "^6.1.2" + }, + "engines": { + "node": "20" + } + }, + "node_modules/@fastify/busboy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.0.tgz", + "integrity": "sha512-yHmUtGwEbW6HsKpPqT140/L6GpHtquHogRLgtanJFep3UAfDkE0fQfC49U+F9irCAoJVlv3M7VSp4rrtO4LnfA==", + "license": "MIT" + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/component": { + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", + "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.10.2", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.10.tgz", + "integrity": "sha512-sWp2g92u7xT4BojGbTXZ80iaSIaL6GAL0pwvM0CO/hb0nHSnABAqsH7AhnWGsGvXuEvbPr7blZylPaR9J+GSuQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.1.tgz", + "integrity": "sha512-IsFivOjdE1GrjTeKoBU/ZMenESKDXidFDzZzHBPQ/4P20ptGdrl3oLlWrV/QJqJ9lND4IidE3z4Xr5JyfUW1vg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.11", + "@firebase/database": "1.0.10", + "@firebase/database-types": "1.0.7", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.7.tgz", + "integrity": "sha512-I7zcLfJXrM0WM+ksFmFdAMdlq/DFmpeMNa+/GNsLyFo5u/lX5zzkPzGe3srVWqaBQBY5KprylDGxOsP6ETfL0A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.10.2" + } + }, + "node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/util": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", + "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@google-cloud/firestore": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.0.tgz", + "integrity": "sha512-88uZ+jLsp1aVMj7gh3EKYH1aulTAMFAp8sH/v5a9w8q8iqSG27RiWLoxSAFr/XocZ9hGiWH1kEnBw+zl3xAgNA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@opentelemetry/api": "^1.3.0", + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^4.3.3", + "protobufjs": "^7.2.6" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/paginator": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", + "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/projectify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.14.0.tgz", + "integrity": "sha512-H41bPL2cMfSi4EEnFzKvg7XSb7T67ocSXrmF7MPjfgFB0L6CKGzfIYJheAZi1iqXjz6XaCT1OBf6HCG5vDBTOQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@google-cloud/paginator": "^5.0.0", + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "^4.0.0", + "abort-controller": "^3.0.0", + "async-retry": "^1.3.3", + "duplexify": "^4.1.3", + "fast-xml-parser": "^4.4.1", + "gaxios": "^6.0.2", + "google-auth-library": "^9.6.3", + "html-entities": "^2.5.2", + "mime": "^3.0.0", + "p-limit": "^3.0.1", + "retry-request": "^7.0.0", + "teeny-request": "^9.0.0", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.4.tgz", + "integrity": "sha512-NBhrxEWnFh0FxeA0d//YP95lRFsSx2TNLEUQg4/W+5f/BMxcCjgOOIT24iD+ZB/tZw057j44DaIxja7w4XMrhg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/caseless": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "license": "MIT" + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", + "integrity": "sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/qs": { + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/request": { + "version": "2.48.12", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", + "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "license": "MIT", + "optional": true + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "optional": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "optional": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "license": "MIT", + "optional": true, + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT", + "optional": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.2.tgz", + "integrity": "sha512-0lk0PHFe/uz0vl527fG9CgdE9WdafjDbCXvBbs+LUv000TVt2Jjhqbs4Jwm8gz070w8xXyEAxrPOMullsxXeGg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "get-intrinsic": "^1.2.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT", + "optional": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "optional": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", + "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexify": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "license": "MIT", + "optional": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.2" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT", + "optional": true + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/farmhash-modern": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", + "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT", + "optional": true + }, + "node_modules/fast-xml-parser": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", + "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/firebase-admin": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.0.1.tgz", + "integrity": "sha512-sKQ/Yw8o/WdC9qTKvuLMBjTbdcBISIXW4+M9PXk0bNjxEbZf1Er7EVq47eRb5+bnKof10xlns6zAIbj4tmSexg==", + "license": "Apache-2.0", + "dependencies": { + "@fastify/busboy": "^3.0.0", + "@firebase/database-compat": "^2.0.0", + "@firebase/database-types": "^1.0.6", + "@types/node": "^22.8.7", + "farmhash-modern": "^1.1.0", + "google-auth-library": "^9.14.2", + "jsonwebtoken": "^9.0.0", + "jwks-rsa": "^3.1.0", + "node-forge": "^1.3.1", + "uuid": "^11.0.2" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@google-cloud/firestore": "^7.10.0", + "@google-cloud/storage": "^7.14.0" + } + }, + "node_modules/firebase-functions": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-6.1.2.tgz", + "integrity": "sha512-1ZKLLOs4YhpzfWOZo0wsqNBusy9113GUfRs89BF6yOlmkxlcJxdJzZEs/ygWeXVJKquZhW2K1Gm10Gir4RJxGQ==", + "license": "MIT", + "dependencies": { + "@types/cors": "^2.8.5", + "@types/express": "^4.17.21", + "cors": "^2.8.5", + "express": "^4.21.0", + "protobufjs": "^7.2.2" + }, + "bin": { + "firebase-functions": "lib/bin/firebase-functions.js" + }, + "engines": { + "node": ">=14.10.0" + }, + "peerDependencies": { + "firebase-admin": "^11.10.0 || ^12.0.0 || ^13.0.0" + } + }, + "node_modules/form-data": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.2.tgz", + "integrity": "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "license": "MIT", + "optional": true + }, + "node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gaxios/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "optional": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", + "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/google-auth-library": { + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz", + "integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.4.1.tgz", + "integrity": "sha512-Phyp9fMfA00J3sZbJxbbB4jC55b7DBjE3F6poyL3wKMEBVKA79q6BGuHcTiM28yOzVql0NDbRL8MLLh8Iwk9Dg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@grpc/grpc-js": "^1.10.9", + "@grpc/proto-loader": "^0.7.13", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "google-auth-library": "^9.3.0", + "node-fetch": "^2.7.0", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^2.0.2", + "protobufjs": "^7.3.2", + "retry-request": "^7.0.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "license": "MIT", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "license": "MIT" + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT", + "optional": true + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwks-rsa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", + "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", + "license": "MIT", + "dependencies": { + "@types/express": "^4.17.17", + "@types/jsonwebtoken": "^9.0.2", + "debug": "^4.3.4", + "jose": "^4.14.6", + "limiter": "^1.1.5", + "lru-memoizer": "^2.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jwks-rsa/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/jwks-rsa/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT", + "optional": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-memoizer": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", + "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", + "license": "MIT", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "6.0.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz", + "integrity": "sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/proto3-json-serializer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", + "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", + "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/request": "^2.48.8", + "extend": "^3.0.2", + "teeny-request": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "license": "MIT", + "optional": true, + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "license": "MIT", + "optional": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "optional": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "license": "MIT", + "optional": true + }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "license": "MIT", + "optional": true + }, + "node_modules/teeny-request": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", + "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.9", + "stream-events": "^1.0.5", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/teeny-request/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/teeny-request/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/teeny-request/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/teeny-request/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT", + "optional": true + }, + "node_modules/teeny-request/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT", + "optional": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz", + "integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC", + "optional": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "optional": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/firebase-devservices/deployment/src/test/functions/package.json b/firebase-devservices/deployment/src/test/functions/package.json new file mode 100644 index 00000000..a43fa9cc --- /dev/null +++ b/firebase-devservices/deployment/src/test/functions/package.json @@ -0,0 +1,18 @@ +{ + "name": "functions", + "version": "1.0.0", + "description": "Test functions for TestContainers Firebase", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Jeroen Benckhuijsen (jeroen.benckhuijsen@group9.nl)", + "license": "Apache-2.0", + "engines": { + "node": "20" + }, + "dependencies": { + "firebase-admin": "^13.0.1", + "firebase-functions": "^6.1.2" + } +} diff --git a/firebase-devservices/deployment/src/test/hosting/test.me b/firebase-devservices/deployment/src/test/hosting/test.me new file mode 100644 index 00000000..003eae77 --- /dev/null +++ b/firebase-devservices/deployment/src/test/hosting/test.me @@ -0,0 +1 @@ +This is a test file for hosting \ No newline at end of file diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java index 9896efc4..848cc62c 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java @@ -1,18 +1,21 @@ -package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; +package nl.group9.testcontainers.firebase; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.nio.file.Files; -import java.util.Optional; import org.junit.jupiter.api.Test; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import com.google.firebase.FirebaseOptions; - @Testcontainers public class FirebaseEmulatorContainerCustomConfigTest { @@ -22,25 +25,13 @@ public class FirebaseEmulatorContainerCustomConfigTest { try { // Create a temporary directory for emulator data tempEmulatorDataDir = Files.createTempDirectory("firebase-emulator-data").toFile(); - firebaseContainer = new TestableFirebaseEmulatorContainer( - new FirebaseEmulatorContainer.EmulatorConfig( - new FirebaseEmulatorContainer.DockerConfig( - "node:23-alpine", - TestableFirebaseEmulatorContainer.user, - TestableFirebaseEmulatorContainer.group), - "latest", // Firebase version - Optional.of("demo-test-project"), - Optional.empty(), - Optional.of(new File("firebase.json").toPath()), - Optional.empty(), - Optional.of(tempEmulatorDataDir.toPath()), - new CustomFirebaseConfigReader().readFromFirebase(new File("firebase.json").toPath())), - "FirebaseEmulatorContainerCustomConfigTest") { - - @Override - protected void createFirebaseOptions(FirebaseOptions.Builder builder) { - } - }; + var testContainer = new TestableFirebaseEmulatorContainer("FirebaseEmulatorContainerCustomConfigTest"); + firebaseContainer = testContainer.testBuilder() + .withCliArguments() + .withEmulatorData(tempEmulatorDataDir.toPath()) + .done() + .readFromFirebaseJson(new File("firebase.json").toPath()) + .build(); } catch (IOException e) { throw new IllegalStateException(e); @@ -70,4 +61,30 @@ public void testStorageRules() throws IOException, InterruptedException { "Expected storage.rules to be present in the container"); } + @Test + public void testHosting() throws IOException, InterruptedException, URISyntaxException { + try (HttpClient httpClient = HttpClient.newHttpClient()) { + var request = HttpRequest.newBuilder() + .GET() + .uri(new URI("http://localhost:7006/test.me")) + .build(); + var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + var body = response.body(); + assertEquals("This is a test file for hosting", body); + } + } + + @Test + public void testFunctions() throws IOException, InterruptedException, URISyntaxException { + try (HttpClient httpClient = HttpClient.newHttpClient()) { + var request = HttpRequest.newBuilder() + .GET() + .uri(new URI("http://localhost:7007/demo-test-project/us-central1/helloworld")) + .build(); + var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + var body = response.body(); + assertEquals("Hello world", body); + } + } + } diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java index e6437f56..33fb2501 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java @@ -1,14 +1,19 @@ -package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; +package nl.group9.testcontainers.firebase; import static org.junit.jupiter.api.Assertions.*; import java.io.*; import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.Map; -import java.util.Optional; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -42,9 +47,6 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; -import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.Emulator; -import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.EmulatorConfig; -import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer.ExposedPort; @Testcontainers public class FirebaseEmulatorContainerIntegrationTest { @@ -60,7 +62,7 @@ public class FirebaseEmulatorContainerIntegrationTest { // Create a static HTML file in the hosting directory File indexFile = new File(tempHostingContentDir, "index.html"); - try (FileWriter writer = new FileWriter(indexFile)) { + try (FileWriter writer = new FileWriter(indexFile, Charset.defaultCharset())) { writer.write("

Hello, Firebase Hosting!

"); } @@ -69,50 +71,39 @@ public class FirebaseEmulatorContainerIntegrationTest { } } - private static final Map SERVICES = Map.of( - Emulator.AUTHENTICATION, new ExposedPort(6000), - Emulator.REALTIME_DATABASE, new ExposedPort(6001), - Emulator.CLOUD_FIRESTORE, new ExposedPort(6002), - Emulator.CLOUD_FIRESTORE_WS, new ExposedPort(6003), - Emulator.PUB_SUB, new ExposedPort(6004), - Emulator.CLOUD_STORAGE, new ExposedPort(6005), - // Emulators.FIREBASE_HOSTING, new ExposedPort(6006), - // Emulators.CLOUD_FUNCTIONS, new ExposedPort(6007), - // Emulators.EVENT_ARC, new ExposedPort(6008), - Emulator.EMULATOR_SUITE_UI, new ExposedPort(6009), - Emulator.EMULATOR_HUB, new ExposedPort(6010), - Emulator.LOGGING, new ExposedPort(6011)); - - private static final TestableFirebaseEmulatorContainer firebaseContainer = new TestableFirebaseEmulatorContainer( - new EmulatorConfig( - new FirebaseEmulatorContainer.DockerConfig( - "node:23-alpine", - TestableFirebaseEmulatorContainer.user, - TestableFirebaseEmulatorContainer.group), - "latest", // Firebase version - Optional.of("demo-test-project"), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(tempEmulatorDataDir.toPath()), - new FirebaseEmulatorContainer.FirebaseConfig( - new FirebaseEmulatorContainer.HostingConfig( - Optional.of(tempHostingContentDir.toPath())), - new FirebaseEmulatorContainer.StorageConfig( - Optional.empty()), - new FirebaseEmulatorContainer.FirestoreConfig( - Optional.empty(), - Optional.empty()), - SERVICES)), - "FirebaseEmulatorContainerIntegrationTest") { - @Override - protected void createFirebaseOptions(FirebaseOptions.Builder builder) { - var emulatorHost = firebaseContainer.getHost(); - var dbPort = firebaseContainer.emulatorPort(Emulator.REALTIME_DATABASE); - - builder.setDatabaseUrl("http://" + emulatorHost + ":" + dbPort + "?ns=demo-test-project"); - } - }; + private static final TestableFirebaseEmulatorContainer testContainer = new TestableFirebaseEmulatorContainer( + "FirebaseEmulatorContainerIntegrationTest", + FirebaseEmulatorContainerIntegrationTest::customizeFirebaseOptions); + + private static final FirebaseEmulatorContainer firebaseContainer = testContainer.testBuilder() + .withCliArguments() + .withEmulatorData(tempEmulatorDataDir.toPath()) + .done() + .withFirebaseConfig() + .withHostingPath(tempHostingContentDir.toPath()) + .withFunctionsFromPath(new File("src/test/functions").toPath()) + .withEmulatorsOnPorts( + FirebaseEmulatorContainer.Emulator.AUTHENTICATION, 6000, + FirebaseEmulatorContainer.Emulator.REALTIME_DATABASE, 6001, + FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE, 6002, + FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE_WS, 6003, + FirebaseEmulatorContainer.Emulator.PUB_SUB, 6004, + FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE, 6005, + FirebaseEmulatorContainer.Emulator.FIREBASE_HOSTING, 6006, + FirebaseEmulatorContainer.Emulator.CLOUD_FUNCTIONS, 6007, + // Emulator.EVENT_ARC, 6008, + FirebaseEmulatorContainer.Emulator.EMULATOR_SUITE_UI, 6009, + FirebaseEmulatorContainer.Emulator.EMULATOR_HUB, 6010, + FirebaseEmulatorContainer.Emulator.LOGGING, 6011) + .done() + .build(); + + private static void customizeFirebaseOptions(FirebaseOptions.Builder builder) { + var emulatorHost = firebaseContainer.getHost(); + var dbPort = firebaseContainer.emulatorPort(FirebaseEmulatorContainer.Emulator.REALTIME_DATABASE); + + builder.setDatabaseUrl("http://" + emulatorHost + ":" + dbPort + "?ns=demo-test-project"); + } @BeforeAll public static void setup() { @@ -165,10 +156,10 @@ private static void validateEmulatorDataWritten() { @Disabled public void testFirebaseHostingEmulatorConnection() throws Exception { // Validate that the static HTML file is accessible via HTTP - int hostingPort = firebaseContainer.emulatorPort(Emulator.FIREBASE_HOSTING); + int hostingPort = firebaseContainer.emulatorPort(FirebaseEmulatorContainer.Emulator.FIREBASE_HOSTING); // Construct URL for the hosted file - URL url = new URL("http://" + firebaseContainer.getHost() + ":" + hostingPort + "/index.html"); + URL url = new URI("http://" + firebaseContainer.getHost() + ":" + hostingPort + "/index.html").toURL(); // Fetch content from the URL HttpURLConnection connection = (HttpURLConnection) url.openConnection(); @@ -177,7 +168,8 @@ public void testFirebaseHostingEmulatorConnection() throws Exception { assertEquals(200, responseCode, "Expected HTTP status 200 for index.html"); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(connection.getInputStream(), Charset.defaultCharset()))) { String line = reader.readLine(); assertTrue(line.contains("Hello, Firebase Hosting!"), "Expected content in index.html"); } @@ -186,13 +178,13 @@ public void testFirebaseHostingEmulatorConnection() throws Exception { @Test public void testFirebaseAuthenticationEmulatorConnection() throws FirebaseAuthException { // Retrieve the host and port for the Authentication emulator - int authPort = firebaseContainer.emulatorPort(Emulator.AUTHENTICATION); + int authPort = firebaseContainer.emulatorPort(FirebaseEmulatorContainer.Emulator.AUTHENTICATION); // Set the environment variable for the Firebase Authentication emulator FirebaseProcessEnvironment.setenv("FIREBASE_AUTH_EMULATOR_HOST", firebaseContainer.getHost() + ":" + authPort); // Initialize FirebaseOptions without setting the auth emulator host directly - FirebaseAuth auth = FirebaseAuth.getInstance(firebaseContainer.getApp()); + FirebaseAuth auth = FirebaseAuth.getInstance(testContainer.getApp()); // Create a test user and verify it UserRecord.CreateRequest request = new UserRecord.CreateRequest() @@ -208,27 +200,28 @@ public void testFirebaseAuthenticationEmulatorConnection() throws FirebaseAuthEx } @Test - public void testFirestoreEmulatorConnection() throws ExecutionException, InterruptedException { - int firestorePort = firebaseContainer.emulatorPort(Emulator.CLOUD_FIRESTORE); + public void testFirestoreEmulatorConnection() throws Exception { + int firestorePort = firebaseContainer.emulatorPort(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE); FirestoreOptions options = FirestoreOptions.newBuilder() .setProjectId("demo-test-project") .setEmulatorHost(firebaseContainer.getHost() + ":" + firestorePort) .setCredentials(new EmulatorCredentials()) .build(); - Firestore firestore = options.getService(); - DocumentReference docRef = firestore.collection("testCollection").document("testDoc"); - ApiFuture result = docRef.set(Map.of("field", "value")); + try (Firestore firestore = options.getService()) { + DocumentReference docRef = firestore.collection("testCollection").document("testDoc"); + ApiFuture result = docRef.set(Map.of("field", "value")); - assertNotNull(result.get()); - DocumentSnapshot snapshot = docRef.get().get(); - assertEquals("value", snapshot.getString("field")); + assertNotNull(result.get()); + DocumentSnapshot snapshot = docRef.get().get(); + assertEquals("value", snapshot.getString("field")); + } } @Test public void testRealtimeDatabaseEmulatorConnection() throws ExecutionException, InterruptedException { - DatabaseReference ref = FirebaseDatabase.getInstance(firebaseContainer.getApp()).getReference("testData"); + DatabaseReference ref = FirebaseDatabase.getInstance(testContainer.getApp()).getReference("testData"); // Write data to the database ref.setValueAsync("testValue").get(); @@ -258,7 +251,7 @@ public void onCancelled(DatabaseError error) { @Test public void testPubSubEmulatorConnection() throws Exception { // Retrieve the host and port for the Pub/Sub emulator - int pubSubPort = firebaseContainer.emulatorPort(Emulator.PUB_SUB); + int pubSubPort = firebaseContainer.emulatorPort(FirebaseEmulatorContainer.Emulator.PUB_SUB); // Set up a gRPC channel to the Pub/Sub emulator ManagedChannel channel = ManagedChannelBuilder.forAddress(firebaseContainer.getHost(), pubSubPort) @@ -296,7 +289,7 @@ public void testPubSubEmulatorConnection() throws Exception { @Test @Disabled public void testStorageEmulatorConnection() { - int storagePort = firebaseContainer.emulatorPort(Emulator.CLOUD_STORAGE); + int storagePort = firebaseContainer.emulatorPort(FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE); Storage storage = StorageOptions.newBuilder() .setHost("http://" + firebaseContainer.getHost() + ":" + storagePort) @@ -313,20 +306,21 @@ public void testStorageEmulatorConnection() { bucket.create("hello.txt", "{\"success\": true}".getBytes(StandardCharsets.UTF_8)); BlobInfo blobInfo = BlobInfo.newBuilder(bucketName, "test-upload").build(); - storage.create(blobInfo, "test".getBytes()); + storage.create(blobInfo, "test".getBytes(StandardCharsets.UTF_8)); // Verify the content of the uploaded file Blob blob = bucket.get("hello.txt"); - assertEquals("{\"success\": true}", new String(blob.getContent()), "Expected blob content to match"); + assertEquals("{\"success\": true}", new String(blob.getContent(), Charset.defaultCharset()), + "Expected blob content to match"); } @Test public void testEmulatorUIReachable() throws Exception { // Get the host and port for the Emulator UI - int uiPort = firebaseContainer.emulatorPort(Emulator.EMULATOR_SUITE_UI); + int uiPort = firebaseContainer.emulatorPort(FirebaseEmulatorContainer.Emulator.EMULATOR_SUITE_UI); // Construct the URL for the Emulator UI root (where index.html would be served) - URL url = new URL("http://" + firebaseContainer.getHost() + ":" + uiPort + "/"); + URL url = new URI("http://" + firebaseContainer.getHost() + ":" + uiPort + "/").toURL(); // Open a connection and send an HTTP GET request HttpURLConnection connection = (HttpURLConnection) url.openConnection(); @@ -343,10 +337,10 @@ public void testEmulatorUIReachable() throws Exception { @Test public void testEmulatorHub() throws Exception { // Get the host and port for the Emulator UI - int uiPort = firebaseContainer.emulatorPort(Emulator.EMULATOR_HUB); + int uiPort = firebaseContainer.emulatorPort(FirebaseEmulatorContainer.Emulator.EMULATOR_HUB); // Construct the URL for the Emulator UI root (where index.html would be served) - URL url = new URL("http://" + firebaseContainer.getHost() + ":" + uiPort + "/emulators"); + URL url = new URI("http://" + firebaseContainer.getHost() + ":" + uiPort + "/emulators").toURL(); // Open a connection and send an HTTP GET request HttpURLConnection connection = (HttpURLConnection) url.openConnection(); @@ -360,14 +354,30 @@ public void testEmulatorHub() throws Exception { connection.disconnect(); } - /* - * CLOUD_FUNCTIONS( - * 5001, - * "quarkus.google.cloud.functions.emulator-host", - * "functions"), - * EVENT_ARC( - * 9299, - * "quarkus.google.cloud.eventarc.emulator-host", - * "eventarc"), - */ + @Test + public void testHosting() throws IOException, InterruptedException, URISyntaxException { + try (HttpClient httpClient = HttpClient.newHttpClient()) { + var request = HttpRequest.newBuilder() + .GET() + .uri(new URI("http://localhost:6006/index.html")) + .build(); + var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + var body = response.body(); + assertEquals("

Hello, Firebase Hosting!

", body); + } + } + + @Test + public void testFunctions() throws IOException, InterruptedException, URISyntaxException { + try (HttpClient httpClient = HttpClient.newHttpClient()) { + var request = HttpRequest.newBuilder() + .GET() + .uri(new URI("http://localhost:6007/demo-test-project/us-central1/helloworld")) + .build(); + var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + var body = response.body(); + assertEquals("Hello world", body); + } + } + } diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/TestableFirebaseEmulatorContainer.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/TestableFirebaseEmulatorContainer.java index a1c10aef..a4ff64f9 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/TestableFirebaseEmulatorContainer.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/TestableFirebaseEmulatorContainer.java @@ -1,9 +1,6 @@ -package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; +package nl.group9.testcontainers.firebase; -import java.io.PrintStream; -import java.util.Optional; - -import org.testcontainers.containers.output.OutputFrame; +import java.util.function.Consumer; import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; @@ -13,70 +10,68 @@ * Subclass of {@link FirebaseEmulatorContainer} which has some extra facilities to ease testing. Functionally * this class is equivalent of its superclass with respect to the testing we need to perform. */ -public abstract class TestableFirebaseEmulatorContainer extends FirebaseEmulatorContainer { - - /* - * We determine the current group and user using an env variable. This is set by the GitHub Actions runner. - * The user and group are used to set the user/group for the user in the docker container run by - * TestContainers for the Firebase Emulators. This way, the data exported by the Firebase Emulators - * can be read from the build. - */ - protected static Optional user = Optional - .ofNullable(System.getenv("CURRENT_USER")) - .map(Integer::valueOf); - protected static Optional group = Optional - .ofNullable(System.getenv("CURRENT_GROUP")) - .map(Integer::valueOf); - - static { - System.out.println("Running as user " + user + " and group " + group); - } +public class TestableFirebaseEmulatorContainer { private final String name; + private final Consumer options; private FirebaseApp app; /** * Creates a new Firebase Emulator container * - * @param firebaseConfig The generic configuration of the firebase emulators * @param name The name of the firebase app (must be unique across the JVM). + * @param options Consumer to handle additional changes to the FirebaseOptions.Builder. */ - public TestableFirebaseEmulatorContainer(EmulatorConfig firebaseConfig, String name) { - super(firebaseConfig); + public TestableFirebaseEmulatorContainer(String name, Consumer options) { this.name = name; + this.options = options; } - @Override - public void start() { - super.start(); + /** + * Creates a new Firebase Emulator container + * + * @param name The name of the firebase app (must be unique across the JVM). + */ + public TestableFirebaseEmulatorContainer(String name) { + this.name = name; + this.options = null; + } - followOutput(this::writeToStdOut, OutputFrame.OutputType.STDOUT); - followOutput(this::writeToStdErr, OutputFrame.OutputType.STDERR); + public FirebaseEmulatorContainer.Builder testBuilder() { + var builder = FirebaseEmulatorContainer.builder(); + + /* + * We determine the current group and user using an env variable. This is set by the GitHub Actions runner. + * The user and group are used to set the user/group for the user in the docker container run by + * TestContainers for the Firebase Emulators. This way, the data exported by the Firebase Emulators + * can be read from the build. + */ + builder.withDockerConfig() + .withUserIdFromEnv("CURRENT_USER") + .withGroupIdFromEnv("CURRENT_GROUP") + .afterStart(this::afterStart) + .done() + .withFirebaseVersion("latest") + .withCliArguments() + .withProjectId("demo-test-project") + .done(); + + return builder; + } + private void afterStart(FirebaseEmulatorContainer container) { var firebaseBuilder = FirebaseOptions.builder() .setProjectId("demo-test-project") .setCredentials(new EmulatorCredentials()); - createFirebaseOptions(firebaseBuilder); + if (options != null) { + options.accept(firebaseBuilder); + } FirebaseOptions options = firebaseBuilder.build(); app = FirebaseApp.initializeApp(options, name); } - protected abstract void createFirebaseOptions(FirebaseOptions.Builder builder); - - private void writeToStdOut(OutputFrame frame) { - writeOutputFrame(frame, System.out); - } - - private void writeToStdErr(OutputFrame frame) { - writeOutputFrame(frame, System.err); - } - - private void writeOutputFrame(OutputFrame frame, PrintStream output) { - output.println(frame.getUtf8StringWithoutLineEnding()); - } - public FirebaseApp getApp() { return app; } From 01fb94742cff39dbf03ff88f644f7b6083c87f81 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sun, 15 Dec 2024 21:39:33 +0100 Subject: [PATCH 070/101] Update docs/modules/ROOT/pages/firebase.adoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Mathieu --- docs/modules/ROOT/pages/firebase.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/firebase.adoc b/docs/modules/ROOT/pages/firebase.adoc index 32ee7661..8dee708c 100644 --- a/docs/modules/ROOT/pages/firebase.adoc +++ b/docs/modules/ROOT/pages/firebase.adoc @@ -1,4 +1,4 @@ -= Google Cloud Services - Firebase += Google Cloud Services - Firebase Dev Services This extension implements DevServices for applications developed on with the Google Firebase platform. The DevService runs the appropriate emulators of the Firebase platform based on your configuration. From b5f81b055d7b4dd024b9966602dfd7ad6f14abef Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sun, 15 Dec 2024 21:40:33 +0100 Subject: [PATCH 071/101] Update docs/modules/ROOT/pages/firebase.adoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Mathieu --- docs/modules/ROOT/pages/firebase.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/firebase.adoc b/docs/modules/ROOT/pages/firebase.adoc index 8dee708c..f10b70b8 100644 --- a/docs/modules/ROOT/pages/firebase.adoc +++ b/docs/modules/ROOT/pages/firebase.adoc @@ -36,7 +36,7 @@ First, we need a new project. Create a new project with the following command (r mvn io.quarkus:quarkus-maven-plugin:${quarkusVersion}:create \ -DprojectGroupId=org.acme \ -DprojectArtifactId=firebase-admin-quickstart \ - -Dextensions="quarkus-google-cloud-firebase" + -Dextensions="quarkus-google-cloud-firebase-devservices" cd firebase-admin-quickstart ---- From ee2dc6aba9932a14a3a05dcac3a347474f6fb111 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sun, 15 Dec 2024 21:41:56 +0100 Subject: [PATCH 072/101] Update configuration --- docs/modules/ROOT/pages/firebase-devservices.adoc | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/modules/ROOT/pages/firebase-devservices.adoc b/docs/modules/ROOT/pages/firebase-devservices.adoc index f10b70b8..40464819 100644 --- a/docs/modules/ROOT/pages/firebase-devservices.adoc +++ b/docs/modules/ROOT/pages/firebase-devservices.adoc @@ -14,9 +14,6 @@ The following emulators have been verified to work: * Realtime Database * PubSub * Cloud Storage - -The following emulators need additional work: - * Firebase Hosting * Functions From 365401cf8812ca5ec358cd00a4109b1625dbcbfa Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sun, 15 Dec 2024 21:50:32 +0100 Subject: [PATCH 073/101] Fixes from copying from main module --- ...baseEmulatorContainerCustomConfigTest.java | 36 +++++++++---------- ...ebaseEmulatorContainerIntegrationTest.java | 36 +++++++++---------- .../TestableFirebaseEmulatorContainer.java | 2 +- 3 files changed, 35 insertions(+), 39 deletions(-) diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java index 848cc62c..67b58877 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java @@ -1,4 +1,4 @@ -package nl.group9.testcontainers.firebase; +package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -63,28 +63,26 @@ public void testStorageRules() throws IOException, InterruptedException { @Test public void testHosting() throws IOException, InterruptedException, URISyntaxException { - try (HttpClient httpClient = HttpClient.newHttpClient()) { - var request = HttpRequest.newBuilder() - .GET() - .uri(new URI("http://localhost:7006/test.me")) - .build(); - var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - var body = response.body(); - assertEquals("This is a test file for hosting", body); - } + HttpClient httpClient = HttpClient.newHttpClient(); + var request = HttpRequest.newBuilder() + .GET() + .uri(new URI("http://localhost:7006/test.me")) + .build(); + var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + var body = response.body(); + assertEquals("This is a test file for hosting", body); } @Test public void testFunctions() throws IOException, InterruptedException, URISyntaxException { - try (HttpClient httpClient = HttpClient.newHttpClient()) { - var request = HttpRequest.newBuilder() - .GET() - .uri(new URI("http://localhost:7007/demo-test-project/us-central1/helloworld")) - .build(); - var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - var body = response.body(); - assertEquals("Hello world", body); - } + HttpClient httpClient = HttpClient.newHttpClient(); + var request = HttpRequest.newBuilder() + .GET() + .uri(new URI("http://localhost:7007/demo-test-project/us-central1/helloworld")) + .build(); + var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + var body = response.body(); + assertEquals("Hello world", body); } } diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java index 33fb2501..be149938 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java @@ -1,4 +1,4 @@ -package nl.group9.testcontainers.firebase; +package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; import static org.junit.jupiter.api.Assertions.*; @@ -356,28 +356,26 @@ public void testEmulatorHub() throws Exception { @Test public void testHosting() throws IOException, InterruptedException, URISyntaxException { - try (HttpClient httpClient = HttpClient.newHttpClient()) { - var request = HttpRequest.newBuilder() - .GET() - .uri(new URI("http://localhost:6006/index.html")) - .build(); - var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - var body = response.body(); - assertEquals("

Hello, Firebase Hosting!

", body); - } + HttpClient httpClient = HttpClient.newHttpClient(); + var request = HttpRequest.newBuilder() + .GET() + .uri(new URI("http://localhost:6006/index.html")) + .build(); + var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + var body = response.body(); + assertEquals("

Hello, Firebase Hosting!

", body); } @Test public void testFunctions() throws IOException, InterruptedException, URISyntaxException { - try (HttpClient httpClient = HttpClient.newHttpClient()) { - var request = HttpRequest.newBuilder() - .GET() - .uri(new URI("http://localhost:6007/demo-test-project/us-central1/helloworld")) - .build(); - var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - var body = response.body(); - assertEquals("Hello world", body); - } + HttpClient httpClient = HttpClient.newHttpClient(); + var request = HttpRequest.newBuilder() + .GET() + .uri(new URI("http://localhost:6007/demo-test-project/us-central1/helloworld")) + .build(); + var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + var body = response.body(); + assertEquals("Hello world", body); } } diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/TestableFirebaseEmulatorContainer.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/TestableFirebaseEmulatorContainer.java index a4ff64f9..f43be657 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/TestableFirebaseEmulatorContainer.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/TestableFirebaseEmulatorContainer.java @@ -1,4 +1,4 @@ -package nl.group9.testcontainers.firebase; +package io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers; import java.util.function.Consumer; From 3743decf5786a760b77694424e0194eed98b63e3 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sun, 15 Dec 2024 23:37:51 +0100 Subject: [PATCH 074/101] Refactored config setup and connected to new builder for FirebaseEmulatorContainer. --- .../deployment/FirebaseDevServiceConfig.java | 255 +++++++++--------- .../FirebaseDevServiceProcessor.java | 15 +- .../FirebaseDevServiceProjectConfig.java | 20 ++ .../FirebaseEmulatorConfigBuilder.java | 197 +++++++++----- .../FirebaseEmulatorContainer.java | 2 +- .../FirebaseEmulatorConfigBuilderTest.java | 202 ++++++++------ 6 files changed, 398 insertions(+), 293 deletions(-) create mode 100644 firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProjectConfig.java diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index 89b093ee..87dca6f8 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -2,6 +2,7 @@ import java.util.Optional; +import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; import io.quarkus.runtime.annotations.ConfigRoot; import io.smallrye.config.ConfigMapping; import io.smallrye.config.WithDefault; @@ -20,109 +21,83 @@ * quarkus.google.cloud.pubsub.devservice.emulatorPort = 8085 # optional * */ -@ConfigMapping(prefix = "quarkus.google.cloud") +@ConfigMapping(prefix = "quarkus.google.cloud.devservices") @ConfigRoot public interface FirebaseDevServiceConfig { /** - * Google Cloud project ID. The project is required to be set if you use the Firebase Auth Dev service. - */ - Optional projectId(); - - /** - * Configure the generic Firebase settings + * Configure the Firebase-based services */ Firebase firebase(); /** - * Configure the firestore + * Configuration for the Functions emulator */ - Firestore firestore(); + GenericDevService functions(); /** - * Configure google cloud functions + * Configuration for the Google Cloud PubSub emulator */ - Functions functions(); + GenericDevService pubsub(); /** - * Configure Google Cloud Pub/Sub + * Configuration for the storage emulator */ - PubSub pubsub(); - - /** - * Configure Google Cloud Storage - */ - Storage storage(); + StorageDevService storage(); interface Firebase { + /** + * Indicates to use the dev service for Firebase. The default value is true. This indicator is used + * to detect the Firebase DevService and disable the DevServices for extensions which conflict with the + * Firebase DevService. + */ + @WithDefault("true") + boolean preferFirebaseDevServices(); + /** * Configuration for the firebase emulator devservice. This is the generic configuration for the firebase * emulator. THe specifics are handled in each of the other dev services. */ - DevService devservice(); + Emulator emulator(); /** - * Configure the firebase auth settings + * Configuration for the firebase auth emulator */ - Auth auth(); + GenericDevService auth(); /** * Configure Firebase Hosting */ - Hosting hosting(); + HostingDevService hosting(); /** - * Configure the realtime database + * Configuration for the realtime database emulator */ - Database database(); - - interface DevService { - - /** - * Indicates to use the dev service for Firebase. The default value is true. This indicator is used - * to detect the Firebase DevService and disable the DevServices for extensions which conflict with the - * Firebase DevService. - */ - @WithDefault("true") - boolean preferFirebaseDevServices(); + GenericDevService database(); - /** - * Sets the Docker image name for the Google Cloud SDK. - * This image is used to emulate the Pub/Sub service in the development environment. - * The default value is 'node:23-alpine'. - *

- * See also the documentation on Custom Docker images for more info about this image. - */ - @WithDefault("node:23-alpine") - String imageName(); + /** + * Configure the firestore + */ + FirestoreDevService firestore(); - /** - * Id of the docker user to run the firebase executable. This is needed in environments where Docker - * does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker - * automatically performs this mapping and the data written by the emulator can be read by the user - * running the build. This is not the case in a regular (non-Desktop) setup, - * so you may need to set the user id and {@link #dockerGroup()}. This option is often needed in CI - * environments. - */ - Optional dockerUser(); + interface Emulator { /** - * Id of the group to which the {@link #dockerUser()} belongs. + * The version of the firebase tools to use. Default is to use the latest available version. */ - Optional dockerGroup(); + @WithDefault(FirebaseEmulatorContainer.DEFAULT_FIREBASE_VERSION) + String firebaseVersion(); /** - * The version of the firebase tools to use. Default is to use the latest available version. + * Docker specific settings */ - @WithDefault("latest") - String firebaseVersion(); + Docker docker(); /** - * The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This - * option is mandatory if you use firebase hosting. + * The ClI settings */ - Optional token(); + Cli cli(); /** * Indicate to use a custom firebase.json file instead of the automatically generated one. The custom @@ -140,25 +115,95 @@ interface DevService { Optional customFirebaseJson(); /** - * Sets the JAVA tool options for emulators based on the Java runtime environment like -Xmx. - * See also - * here + * Settings for the emulator UI */ - Optional javaToolOptions(); + UI ui(); - /** - * Allow to import and export data. Specify a path relative to the current working directory of the executable - * (for most unit tests, this is the root of the build directory) to be used for import and export of emulator - * data. The data will be written to a subdirectory called "emulator-data" of this directory. - * See also here - */ - Optional emulatorData(); + + interface Docker { + /** + * Sets the Docker image name for the Google Cloud SDK. + * This image is used to emulate the Pub/Sub service in the development environment. + * The default value is 'node:23-alpine'. + *

+ * See also the documentation on Custom Docker images for more info about this image. + */ + @WithDefault(FirebaseEmulatorContainer.DEFAULT_IMAGE_NAME) + String imageName(); + + /** + * Id of the docker user to run the firebase executable. This is needed in environments where Docker + * does not perform a mapping to the user running Docker. In a Docker Desktop setup, Docker + * automatically performs this mapping and the data written by the emulator can be read by the user + * running the build. This is not the case in a regular (non-Desktop) setup, + * so you may need to set the user id and {@link #dockerGroup()}. This option is often needed in CI + * environments. + */ + Optional dockerUser(); + + /** + * Id of the group to which the {@link #dockerUser()} belongs. + */ + Optional dockerGroup(); + + /** + * Try to read the {@link #dockerUser()} from an environment variable + */ + Optional dockerUserEnv(); + + /** + * Try to read the {@link #dockerGroup()} from an environment variable + */ + Optional dockerGroupEnv(); + /** + * Pipe Stdout of the container to the Quarkus logging + */ + Optional followStdOut(); + + /** + * Pipe Stedd of the container to the Quarkus logging + */ + Optional followStdErr(); + + } /** - * Settings for the emulator UI + * Configuration options related to the Firebase emulators CLI */ - UI ui(); + interface Cli { + /** + * The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This + * option is mandatory if you use firebase hosting. + */ + Optional token(); + + /** + * Sets the JAVA tool options for emulators based on the Java runtime environment like -Xmx. + * See also + * here + */ + Optional javaToolOptions(); + + /** + * Allow to import and export data. Specify a path relative to the current working directory of the executable + * (for most unit tests, this is the root of the build directory) to be used for import and export of emulator + * data. The data will be written to a subdirectory called "emulator-data" of this directory. + * See also here + */ + Optional emulatorData(); + + /** + * Indicate whether to import, export or both the data specified in {@link #emulatorData()} + */ + Optional importExport(); + + /** + * Enable firebase emulators debugging. + */ + Optional debug(); + + } interface UI extends GenericDevService { @@ -185,28 +230,7 @@ interface UI extends GenericDevService { } - interface Auth { - - /** - * Configuration for the firebase auth emulator - */ - GenericDevService devservice(); - } - - interface Database { - - /** - * Configuration for the realtime database emulator - */ - GenericDevService devservice(); - } - - interface Hosting { - - /** - * Configuration for the hosting emulator - */ - GenericDevService devservice(); + interface HostingDevService extends GenericDevService { /** * Path to the hosting files. @@ -214,15 +238,6 @@ interface Hosting { Optional hostingPath(); } - } - - interface Firestore { - - /** - * Configuration for the Firestore emulator - */ - FirestoreDevService devservice(); - /** * Extension for the Firestore dev service. This service can also configure the websocket port. */ @@ -246,36 +261,12 @@ interface FirestoreDevService extends GenericDevService { } } - interface Functions { + interface StorageDevService extends GenericDevService { /** - * Configuration for the Functions emulator + * Path to the storage.rules file. */ - GenericDevService devservice(); - } - - interface PubSub { - - /** - * Configuration for the pubsub emulator - */ - GenericDevService devservice(); - } - - interface Storage { - - /** - * Configuration for the storage emulator - */ - StorageDevService devservice(); - - interface StorageDevService extends GenericDevService { - - /** - * Path to the storage.rules file. - */ - Optional rulesFile(); - } + Optional rulesFile(); } /** diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java index 542cda4e..3f39cf72 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProcessor.java @@ -44,6 +44,7 @@ public class FirebaseDevServiceProcessor { @BuildStep public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildItem, + FirebaseDevServiceProjectConfig projectConfig, FirebaseDevServiceConfig firebaseBuildTimeConfig, List devServicesSharedNetworkBuildItem, Optional consoleInstalledBuildItem, @@ -66,7 +67,7 @@ public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildI // Try starting the container if conditions are met try { - devService = startContainerIfAvailable(dockerStatusBuildItem, firebaseBuildTimeConfig, + devService = startContainerIfAvailable(dockerStatusBuildItem, projectConfig, firebaseBuildTimeConfig, globalDevServicesConfig.timeout); } catch (Throwable t) { LOGGER.warn("Unable to start Firebase dev service", t); @@ -89,10 +90,11 @@ public DevServicesResultBuildItem start(DockerStatusBuildItem dockerStatusBuildI * @return Running service item, or null if the service couldn't be started */ private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(DockerStatusBuildItem dockerStatusBuildItem, + FirebaseDevServiceProjectConfig projectConfig, FirebaseDevServiceConfig config, Optional timeout) { - if (!config.firebase().devservice().preferFirebaseDevServices()) { + if (!config.firebase().preferFirebaseDevServices()) { // Firebase service explicitly disabled LOGGER.info("Not starting Dev Services for Firebase as it has been disabled in the config."); return null; @@ -109,7 +111,7 @@ private DevServicesResultBuildItem.RunningDevService startContainerIfAvailable(D return null; } - return startContainer(dockerStatusBuildItem, config, timeout); + return startContainer(dockerStatusBuildItem, projectConfig, config, timeout); } private boolean isEnabled(FirebaseDevServiceConfig config) { @@ -129,13 +131,12 @@ private boolean isEnabled(FirebaseDevServiceConfig config) { * @return Running service item, or null if the service couldn't be started */ private DevServicesResultBuildItem.RunningDevService startContainer(DockerStatusBuildItem dockerStatusBuildItem, + FirebaseDevServiceProjectConfig projectConfig, FirebaseDevServiceConfig config, Optional timeout) { - var emulatorConfig = new FirebaseEmulatorConfigBuilder(config).build(); - - // Create and configure Pub/Sub emulator container - FirebaseEmulatorContainer emulatorContainer = new FirebaseEmulatorContainer(emulatorConfig); + // Create and configure Firebase emulator container + var emulatorContainer = new FirebaseEmulatorConfigBuilder(projectConfig, config).build(); // Set container startup timeout if provided timeout.ifPresent(emulatorContainer::withStartupTimeout); diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProjectConfig.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProjectConfig.java new file mode 100644 index 00000000..71d43205 --- /dev/null +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProjectConfig.java @@ -0,0 +1,20 @@ +package io.quarkiverse.googlecloudservices.firebase.deployment; + +import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; + +import java.util.Optional; + +/** + * Temporary Config root to retrieve the project id for the Firebase Emulator Container. We will remove this interface + * in the future in favour of using the common setup. + */ +@ConfigMapping(prefix = "quarkus.google.cloud") +@ConfigRoot +public interface FirebaseDevServiceProjectConfig { + + /** + * Google Cloud project ID. The project is required to be set if you use the Firebase Auth Dev service. + */ + Optional projectId(); +} diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java index d39a1d29..dc6a783b 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java @@ -1,101 +1,168 @@ package io.quarkiverse.googlecloudservices.firebase.deployment; import java.io.File; +import java.io.IOException; import java.nio.file.Path; import java.util.Map; -import java.util.stream.Collectors; import io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.FirebaseEmulatorContainer; /** * This class translates the Quarkus Firebase extension configuration to the {@link FirebaseEmulatorContainer} - * configuration. + * instance. */ public class FirebaseEmulatorConfigBuilder { + private final FirebaseDevServiceProjectConfig projectConfig; private final FirebaseDevServiceConfig config; - public FirebaseEmulatorConfigBuilder(FirebaseDevServiceConfig config) { + public static Map devServices( + FirebaseDevServiceConfig config) { + return Map.of( + FirebaseEmulatorContainer.Emulator.AUTHENTICATION, config.firebase().auth(), + FirebaseEmulatorContainer.Emulator.EMULATOR_SUITE_UI, config.firebase().emulator().ui(), + FirebaseEmulatorContainer.Emulator.CLOUD_FUNCTIONS, config.functions(), + FirebaseEmulatorContainer.Emulator.REALTIME_DATABASE, config.firebase().database(), + FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE, config.firebase().firestore(), + FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE, config.storage(), + FirebaseEmulatorContainer.Emulator.FIREBASE_HOSTING, config.firebase().hosting(), + FirebaseEmulatorContainer.Emulator.PUB_SUB, config.pubsub()); + } + + public FirebaseEmulatorConfigBuilder(FirebaseDevServiceProjectConfig projectConfig, FirebaseDevServiceConfig config) { + this.projectConfig = projectConfig; this.config = config; } - public FirebaseEmulatorContainer.EmulatorConfig build() { - var devService = config.firebase().devservice(); - - return new FirebaseEmulatorContainer.EmulatorConfig( - new FirebaseEmulatorContainer.DockerConfig( - devService.imageName(), - devService.dockerUser(), - devService.dockerGroup()), - devService.firebaseVersion(), - config.projectId(), - devService.token(), - devService.customFirebaseJson().map(File::new).map(File::toPath), - devService.javaToolOptions(), - devService.emulatorData().map(File::new).map(File::toPath), - new FirebaseEmulatorContainer.FirebaseConfig( - new FirebaseEmulatorContainer.HostingConfig( - config.firebase().hosting().hostingPath().map(FirebaseEmulatorConfigBuilder::asPath)), - new FirebaseEmulatorContainer.StorageConfig( - config.storage().devservice().rulesFile().map(FirebaseEmulatorConfigBuilder::asPath)), - new FirebaseEmulatorContainer.FirestoreConfig( - config.firestore().devservice().rulesFile().map(FirebaseEmulatorConfigBuilder::asPath), - config.firestore().devservice().indexesFile().map(FirebaseEmulatorConfigBuilder::asPath)), - exposedEmulators(devServices(config)))); + public FirebaseEmulatorContainer build() { + return configureBuilder().build(); } - private static Path asPath(String path) { - return new File(path).toPath(); + FirebaseEmulatorContainer.EmulatorConfig buildConfig() { + return configureBuilder().buildConfig(); } - public static Map devServices( - FirebaseDevServiceConfig config) { - return Map.of( - FirebaseEmulatorContainer.Emulator.AUTHENTICATION, config.firebase().auth().devservice(), - FirebaseEmulatorContainer.Emulator.EMULATOR_SUITE_UI, config.firebase().devservice().ui(), - FirebaseEmulatorContainer.Emulator.REALTIME_DATABASE, config.firebase().database().devservice(), - FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE, config.firestore().devservice(), - FirebaseEmulatorContainer.Emulator.CLOUD_FUNCTIONS, config.functions().devservice(), - FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE, config.storage().devservice(), - FirebaseEmulatorContainer.Emulator.FIREBASE_HOSTING, config.firebase().hosting().devservice(), - FirebaseEmulatorContainer.Emulator.PUB_SUB, config.pubsub().devservice()); + private FirebaseEmulatorContainer.Builder configureBuilder() { + var builder = FirebaseEmulatorContainer.builder(); + + builder.withFirebaseVersion(config.firebase().emulator().firebaseVersion()); + + handleDockerConfig(config.firebase().emulator().docker(), builder); + handleCliConfig(config.firebase().emulator().cli(), builder); + handleEmulators(builder); + + return builder; } - private Map exposedEmulators( - Map devServices) { - var emulators = devServices - .entrySet() - .stream() - .filter(e -> e.getValue().enabled()) - .map(e -> Map.entry(e.getKey(), portForService(e.getValue()))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + private void handleDockerConfig(FirebaseDevServiceConfig.Firebase.Emulator.Docker docker, FirebaseEmulatorContainer.Builder builder) { + var dockerConfig = builder.withDockerConfig(); - var uiService = (FirebaseDevServiceConfig.Firebase.DevService.UI) devServices - .get(FirebaseEmulatorContainer.Emulator.EMULATOR_SUITE_UI); + dockerConfig.withImage(docker.imageName()); + docker.dockerUser().ifPresent(dockerConfig::withUserId); + docker.dockerGroup().ifPresent(dockerConfig::withGroupId); + docker.dockerUserEnv().ifPresent(dockerConfig::withUserIdFromEnv); + docker.dockerGroupEnv().ifPresent(dockerConfig::withGroupIdFromEnv); + docker.followStdOut().ifPresent(dockerConfig::followStdOut); + docker.followStdErr().ifPresent(dockerConfig::followStdErr); + + dockerConfig.done(); + } - uiService.hubPort().ifPresent(port -> emulators.put( - FirebaseEmulatorContainer.Emulator.EMULATOR_HUB, - new FirebaseEmulatorContainer.ExposedPort(port))); + private void handleCliConfig(FirebaseDevServiceConfig.Firebase.Emulator.Cli cli, FirebaseEmulatorContainer.Builder builder) { + var cliConfig = builder.withCliArguments(); - uiService.loggingPort().ifPresent(port -> emulators.put( - FirebaseEmulatorContainer.Emulator.LOGGING, - new FirebaseEmulatorContainer.ExposedPort(port))); + projectConfig.projectId().ifPresent(cliConfig::withProjectId); + + cli.token().ifPresent(cliConfig::withToken); + cli.javaToolOptions().ifPresent(cliConfig::withJavaToolOptions); + cli.emulatorData().map(FirebaseEmulatorConfigBuilder::asPath).ifPresent(cliConfig::withEmulatorData); + cli.importExport().ifPresent(cliConfig::withImportExport); + cli.debug().ifPresent(cliConfig::withDebug); + + cliConfig.done(); + } - var firestoreService = (FirebaseDevServiceConfig.Firestore.FirestoreDevService) devServices - .get(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE); + private void handleEmulators(FirebaseEmulatorContainer.Builder builder) { + config.firebase().emulator().customFirebaseJson().ifPresentOrElse( + (firebaseJson) -> configureCustomFirebaseJson(builder, firebaseJson), + () -> configureEmulators(builder) + ); + } - firestoreService.websocketPort().ifPresent(port -> emulators.put( - FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE_WS, - new FirebaseEmulatorContainer.ExposedPort(port))); + private void configureCustomFirebaseJson(FirebaseEmulatorContainer.Builder builder, String firebaseJson) { + try { + builder.readFromFirebaseJson(asPath(firebaseJson)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } - // TODO: Event arc? + private void configureEmulators(FirebaseEmulatorContainer.Builder builder) { + var firebaseConfigBuilder = builder.withFirebaseConfig(); + var devServices = devServices(config); - return emulators; + devServices + .entrySet() + .stream() + .filter(e -> e.getValue().enabled()) + .forEach(e -> + e.getValue().emulatorPort().ifPresentOrElse( + p -> firebaseConfigBuilder.withEmulatorOnFixedPort(e.getKey(), p), + () -> firebaseConfigBuilder.withEmulator(e.getKey()) + ) + ); + + config.firebase() + .hosting() + .hostingPath() + .map(FirebaseEmulatorConfigBuilder::asPath) + .ifPresent(firebaseConfigBuilder::withHostingPath); + + config.firebase() + .firestore() + .indexesFile() + .map(FirebaseEmulatorConfigBuilder::asPath) + .ifPresent(firebaseConfigBuilder::withFirestoreIndexes); + + config.firebase() + .firestore() + .rulesFile() + .map(FirebaseEmulatorConfigBuilder::asPath) + .ifPresent(firebaseConfigBuilder::withFirestoreRules); + + config.firebase() + .firestore() + .websocketPort() + .ifPresent(p -> + firebaseConfigBuilder.withEmulatorOnFixedPort(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE_WS, p) + ); + + config.firebase() + .emulator() + .ui() + .hubPort() + .ifPresent(p -> + firebaseConfigBuilder.withEmulatorOnFixedPort(FirebaseEmulatorContainer.Emulator.EMULATOR_HUB, p) + ); + + config.firebase() + .emulator() + .ui() + .loggingPort() + .ifPresent(p -> + firebaseConfigBuilder.withEmulatorOnFixedPort(FirebaseEmulatorContainer.Emulator.LOGGING, p) + ); + + config.storage() + .rulesFile() + .map(FirebaseEmulatorConfigBuilder::asPath) + .ifPresent(firebaseConfigBuilder::withStorageRules); + + firebaseConfigBuilder.done(); } - private static FirebaseEmulatorContainer.ExposedPort portForService(FirebaseDevServiceConfig.GenericDevService devService) { - var port = devService.emulatorPort().orElse(null); - return new FirebaseEmulatorContainer.ExposedPort(port); + private static Path asPath(String path) { + return new File(path).toPath(); } } diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java index 173ba9b4..57651675 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java @@ -410,7 +410,7 @@ public FirebaseConfigBuilder withFirebaseConfig() { * * @return The emulator configuration. */ - protected EmulatorConfig buildConfig() { + public EmulatorConfig buildConfig() { if (firebaseConfig == null) { // Try to autoload the firebase.json configuration var defaultFirebaseJson = new File("firebase.json").toPath(); diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java index ebd62ffb..cd441cc7 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java @@ -17,69 +17,96 @@ class FirebaseEmulatorConfigBuilderTest { @BeforeEach void setUp() { - // Storage - FirebaseDevServiceConfig config = new TestFirebaseDevServiceConfig( - Optional.of("my-project-id"), + var projectConfig= new TestProjectConfig( + Optional.of("my-project-id") + ); + var config = new TestFirebaseDevServiceConfig( new TestFirebase( - new TestFirebaseDevService( - true, - "node:21-alpine", - Optional.empty(), - Optional.empty(), + true, + new TestFirebaseEmulator( "11.0.0", - Optional.of("MY_TOKEN"), - Optional.of("firebase.json"), - Optional.of("-Xmx"), - Optional.of("data"), + new TestDocker( + "node:21-alpine", + Optional.of(1001), + Optional.of(1002), + Optional.empty(), + Optional.empty(), + Optional.of(false), + Optional.of(true) + ), + new TestCli( + Optional.of("MY_TOKEN"), + Optional.of("-Xmx"), + Optional.of("data"), + Optional.of(FirebaseEmulatorContainer.ImportExport.EXPORT_ONLY), + Optional.of(true) + ), + Optional.empty(), new TestUI( true, Optional.of(6000), Optional.of(6001), - Optional.of(6002))), - new TestAuth( - new TestGenericDevService(true, Optional.of(6003))), - new TestDatabase( - new TestGenericDevService( - false, - Optional.of(6005))), + Optional.of(6002) + ) + ), + new TestGenericDevService(true, Optional.of(6003)), new TestHosting( - new TestGenericDevService(true, Optional.of(6004)), - Optional.of("public"))), - new TestFirestore( + true, + Optional.of(6004), + Optional.of("public") + ), + new TestGenericDevService( + false, + Optional.of(6005) + ), new TestFirestoreDevService( true, Optional.of(6006), Optional.of(6007), Optional.of("firestore.rules"), - Optional.of("firestore.indexes.json"))), - new TestFunctions( - new TestGenericDevService( - true, - Optional.of(6008))), - new TestPubSub( - new TestGenericDevService( - true, - Optional.of(6009))), - new TestStorage( - new TestStorageDevService( - true, - Optional.empty(), - Optional.of("storage.rules")))); - configBuilder = new FirebaseEmulatorConfigBuilder(config); + Optional.of("firestore.indexes.json") + ) + ), + new TestGenericDevService( + true, + Optional.of(6008) + ), + new TestGenericDevService( + true, + Optional.of(6009) + ), + new TestStorageDevService( + true, + Optional.empty(), + Optional.of("storage.rules") + ) + ); + configBuilder = new FirebaseEmulatorConfigBuilder(projectConfig, config); } @Test void testBuild() { - FirebaseEmulatorContainer.EmulatorConfig emulatorConfig = configBuilder.build(); + FirebaseEmulatorContainer.EmulatorConfig emulatorConfig = configBuilder.buildConfig(); assertNotNull(emulatorConfig); + assertEquals("node:21-alpine", emulatorConfig.dockerConfig().imageName()); + assertEquals(1001, emulatorConfig.dockerConfig().userId().orElse(null)); + assertEquals(1002, emulatorConfig.dockerConfig().groupId().orElse(null)); + assertFalse(emulatorConfig.dockerConfig().followStdOut()); + assertTrue(emulatorConfig.dockerConfig().followStdErr()); + assertEquals("11.0.0", emulatorConfig.firebaseVersion()); - assertEquals("my-project-id", emulatorConfig.projectId().orElse(null)); - assertEquals("MY_TOKEN", emulatorConfig.token().orElse(null)); - assertPathEndsWith("firebase.json", emulatorConfig.customFirebaseJson().orElse(null)); - assertEquals("-Xmx", emulatorConfig.javaToolOptions().orElse(null)); - assertPathEndsWith("data", emulatorConfig.emulatorData().orElse(null)); + + assertEquals("my-project-id", emulatorConfig.cliArguments().projectId().orElse(null)); + assertEquals("MY_TOKEN", emulatorConfig.cliArguments().token().orElse(null)); + assertEquals("-Xmx", emulatorConfig.cliArguments().javaToolOptions().orElse(null)); + assertPathEndsWith("data", emulatorConfig.cliArguments().emulatorData().orElse(null)); + assertEquals(FirebaseEmulatorContainer.ImportExport.EXPORT_ONLY, emulatorConfig.cliArguments().importExport()); + assertTrue(emulatorConfig.cliArguments().debug()); + + assertTrue(emulatorConfig.customFirebaseJson().isEmpty()); + assertPathEndsWith("public", emulatorConfig.firebaseConfig().hostingConfig().hostingContentDir().orElse(null)); assertPathEndsWith("storage.rules", emulatorConfig.firebaseConfig().storageConfig().rulesFile().orElse(null)); assertPathEndsWith("firestore.rules", emulatorConfig.firebaseConfig().firestoreConfig().rulesFile().orElse(null)); @@ -95,7 +122,7 @@ private void assertPathEndsWith(String expected, Path path) { @Test void testExposedEmulators() { - FirebaseEmulatorContainer.EmulatorConfig emulatorConfig = configBuilder.build(); + FirebaseEmulatorContainer.EmulatorConfig emulatorConfig = configBuilder.buildConfig(); Map exposedPorts = emulatorConfig .firebaseConfig().services(); @@ -116,52 +143,62 @@ void testExposedEmulators() { } // Record implementations for interfaces + record TestProjectConfig( + Optional projectId + ) implements FirebaseDevServiceProjectConfig { + } + record TestFirebaseDevServiceConfig( - Optional projectId, - Firebase firebase, - Firestore firestore, - Functions functions, - PubSub pubsub, - Storage storage) implements FirebaseDevServiceConfig { + FirebaseDevServiceConfig.Firebase firebase, + FirebaseDevServiceConfig.GenericDevService functions, + FirebaseDevServiceConfig.GenericDevService pubsub, + FirebaseDevServiceConfig.StorageDevService storage) implements FirebaseDevServiceConfig { } record TestFirebase( - DevService devservice, - FirebaseDevServiceConfig.Firebase.Auth auth, - FirebaseDevServiceConfig.Firebase.Database database, - FirebaseDevServiceConfig.Firebase.Hosting hosting) implements FirebaseDevServiceConfig.Firebase { + boolean preferFirebaseDevServices, + Emulator emulator, + FirebaseDevServiceConfig.GenericDevService auth, + FirebaseDevServiceConfig.Firebase.HostingDevService hosting, + FirebaseDevServiceConfig.GenericDevService database, + FirebaseDevServiceConfig.Firebase.FirestoreDevService firestore + ) implements FirebaseDevServiceConfig.Firebase { + } - record TestFirebaseDevService( - boolean preferFirebaseDevServices, + record TestFirebaseEmulator( + String firebaseVersion, + FirebaseDevServiceConfig.Firebase.Emulator.Docker docker, + FirebaseDevServiceConfig.Firebase.Emulator.Cli cli, + Optional customFirebaseJson, + UI ui) implements FirebaseDevServiceConfig.Firebase.Emulator { + } + + record TestDocker( String imageName, Optional dockerUser, Optional dockerGroup, - String firebaseVersion, + Optional dockerUserEnv, + Optional dockerGroupEnv, + Optional followStdOut, + Optional followStdErr + ) implements FirebaseDevServiceConfig.Firebase.Emulator.Docker { + } + + record TestCli( Optional token, - Optional customFirebaseJson, Optional javaToolOptions, Optional emulatorData, - UI ui) implements FirebaseDevServiceConfig.Firebase.DevService { + Optional importExport, + Optional debug + ) implements FirebaseDevServiceConfig.Firebase.Emulator.Cli { } record TestUI( boolean enabled, Optional emulatorPort, Optional loggingPort, - Optional hubPort) implements FirebaseDevServiceConfig.Firebase.DevService.UI { - } - - record TestAuth( - FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.Firebase.Auth { - } - - record TestDatabase( - FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.Firebase.Database { - } - - record TestFirestore( - FirestoreDevService devservice) implements FirebaseDevServiceConfig.Firestore { + Optional hubPort) implements FirebaseDevServiceConfig.Firebase.Emulator.UI { } record TestFirestoreDevService( @@ -169,30 +206,19 @@ record TestFirestoreDevService( Optional emulatorPort, Optional websocketPort, Optional rulesFile, - Optional indexesFile) implements FirebaseDevServiceConfig.Firestore.FirestoreDevService { - } - - record TestFunctions( - FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.Functions { + Optional indexesFile) implements FirebaseDevServiceConfig.Firebase.FirestoreDevService { } record TestHosting( - FirebaseDevServiceConfig.GenericDevService devservice, - Optional hostingPath) implements FirebaseDevServiceConfig.Firebase.Hosting { - } - - record TestPubSub( - FirebaseDevServiceConfig.GenericDevService devservice) implements FirebaseDevServiceConfig.PubSub { - } - - record TestStorage( - FirebaseDevServiceConfig.Storage.StorageDevService devservice) implements FirebaseDevServiceConfig.Storage { + boolean enabled, + Optional emulatorPort, + Optional hostingPath) implements FirebaseDevServiceConfig.Firebase.HostingDevService { } record TestStorageDevService( boolean enabled, Optional emulatorPort, - Optional rulesFile) implements FirebaseDevServiceConfig.Storage.StorageDevService { + Optional rulesFile) implements FirebaseDevServiceConfig.StorageDevService { } From 4277e408386c1036ce8f1530b0de9c55c996fdd5 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sun, 15 Dec 2024 23:40:04 +0100 Subject: [PATCH 075/101] Fix properties based on changed config setup --- .../src/main/resources/application.properties | 3 +-- .../firebase/src/main/resources/application.properties | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/integration-tests/firebase-admin/src/main/resources/application.properties b/integration-tests/firebase-admin/src/main/resources/application.properties index 04f83286..5432e1aa 100644 --- a/integration-tests/firebase-admin/src/main/resources/application.properties +++ b/integration-tests/firebase-admin/src/main/resources/application.properties @@ -1,5 +1,4 @@ # Set the project ID with the demo- prefix to use an emulated service. # When the emulator is started with this project ID, non-emulated services access will fail. quarkus.google.cloud.project-id=demo-test-project-id -quarkus.google.cloud.firebase.auth.enabled=true -quarkus.google.cloud.firebase.auth.devservice.enabled=true +quarkus.google.cloud.devservices.firebase.auth.enabled=true diff --git a/integration-tests/firebase/src/main/resources/application.properties b/integration-tests/firebase/src/main/resources/application.properties index 6e885816..3b498334 100644 --- a/integration-tests/firebase/src/main/resources/application.properties +++ b/integration-tests/firebase/src/main/resources/application.properties @@ -2,7 +2,6 @@ # When the emulator is started with this project ID, non-emulated services access will fail. quarkus.google.cloud.project-id=demo-test-project-id quarkus.google.cloud.access-token-enabled=false -quarkus.google.cloud.firebase.auth.enabled=true -quarkus.google.cloud.firebase.auth.devservice.enabled=true -quarkus.google.cloud.pubsub.devservice.enabled=true -quarkus.google.cloud.firestore.devservice.enabled=true +quarkus.google.cloud.devservices.firebase.auth.enabled=true +quarkus.google.cloud.devservices.firebase.firestore.enabled=true +quarkus.google.cloud.devservices.pubsub.enabled=true From 9e529e3646659577d4a2370e5f5a43674472ab9c Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sun, 15 Dec 2024 23:45:31 +0100 Subject: [PATCH 076/101] Formatting fixes --- .../deployment/FirebaseDevServiceConfig.java | 5 +- .../FirebaseDevServiceProjectConfig.java | 4 +- .../FirebaseEmulatorConfigBuilder.java | 32 ++++------ .../FirebaseEmulatorConfigBuilderTest.java | 61 +++++++------------ 4 files changed, 40 insertions(+), 62 deletions(-) diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java index 87dca6f8..08b58ab6 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceConfig.java @@ -119,7 +119,6 @@ interface Emulator { */ UI ui(); - interface Docker { /** * Sets the Docker image name for the Google Cloud SDK. @@ -155,6 +154,7 @@ interface Docker { * Try to read the {@link #dockerGroup()} from an environment variable */ Optional dockerGroupEnv(); + /** * Pipe Stdout of the container to the Quarkus logging */ @@ -180,7 +180,8 @@ interface Cli { /** * Sets the JAVA tool options for emulators based on the Java runtime environment like -Xmx. * See also - * here + * here */ Optional javaToolOptions(); diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProjectConfig.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProjectConfig.java index 71d43205..83c58a0e 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProjectConfig.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProjectConfig.java @@ -1,10 +1,10 @@ package io.quarkiverse.googlecloudservices.firebase.deployment; +import java.util.Optional; + import io.quarkus.runtime.annotations.ConfigRoot; import io.smallrye.config.ConfigMapping; -import java.util.Optional; - /** * Temporary Config root to retrieve the project id for the Firebase Emulator Container. We will remove this interface * in the future in favour of using the common setup. diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java index dc6a783b..6150b15e 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java @@ -54,7 +54,8 @@ private FirebaseEmulatorContainer.Builder configureBuilder() { return builder; } - private void handleDockerConfig(FirebaseDevServiceConfig.Firebase.Emulator.Docker docker, FirebaseEmulatorContainer.Builder builder) { + private void handleDockerConfig(FirebaseDevServiceConfig.Firebase.Emulator.Docker docker, + FirebaseEmulatorContainer.Builder builder) { var dockerConfig = builder.withDockerConfig(); dockerConfig.withImage(docker.imageName()); @@ -68,7 +69,8 @@ private void handleDockerConfig(FirebaseDevServiceConfig.Firebase.Emulator.Docke dockerConfig.done(); } - private void handleCliConfig(FirebaseDevServiceConfig.Firebase.Emulator.Cli cli, FirebaseEmulatorContainer.Builder builder) { + private void handleCliConfig(FirebaseDevServiceConfig.Firebase.Emulator.Cli cli, + FirebaseEmulatorContainer.Builder builder) { var cliConfig = builder.withCliArguments(); projectConfig.projectId().ifPresent(cliConfig::withProjectId); @@ -85,8 +87,7 @@ private void handleCliConfig(FirebaseDevServiceConfig.Firebase.Emulator.Cli cli, private void handleEmulators(FirebaseEmulatorContainer.Builder builder) { config.firebase().emulator().customFirebaseJson().ifPresentOrElse( (firebaseJson) -> configureCustomFirebaseJson(builder, firebaseJson), - () -> configureEmulators(builder) - ); + () -> configureEmulators(builder)); } private void configureCustomFirebaseJson(FirebaseEmulatorContainer.Builder builder, String firebaseJson) { @@ -105,12 +106,9 @@ private void configureEmulators(FirebaseEmulatorContainer.Builder builder) { .entrySet() .stream() .filter(e -> e.getValue().enabled()) - .forEach(e -> - e.getValue().emulatorPort().ifPresentOrElse( - p -> firebaseConfigBuilder.withEmulatorOnFixedPort(e.getKey(), p), - () -> firebaseConfigBuilder.withEmulator(e.getKey()) - ) - ); + .forEach(e -> e.getValue().emulatorPort().ifPresentOrElse( + p -> firebaseConfigBuilder.withEmulatorOnFixedPort(e.getKey(), p), + () -> firebaseConfigBuilder.withEmulator(e.getKey()))); config.firebase() .hosting() @@ -133,25 +131,21 @@ private void configureEmulators(FirebaseEmulatorContainer.Builder builder) { config.firebase() .firestore() .websocketPort() - .ifPresent(p -> - firebaseConfigBuilder.withEmulatorOnFixedPort(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE_WS, p) - ); + .ifPresent(p -> firebaseConfigBuilder + .withEmulatorOnFixedPort(FirebaseEmulatorContainer.Emulator.CLOUD_FIRESTORE_WS, p)); config.firebase() .emulator() .ui() .hubPort() - .ifPresent(p -> - firebaseConfigBuilder.withEmulatorOnFixedPort(FirebaseEmulatorContainer.Emulator.EMULATOR_HUB, p) - ); + .ifPresent( + p -> firebaseConfigBuilder.withEmulatorOnFixedPort(FirebaseEmulatorContainer.Emulator.EMULATOR_HUB, p)); config.firebase() .emulator() .ui() .loggingPort() - .ifPresent(p -> - firebaseConfigBuilder.withEmulatorOnFixedPort(FirebaseEmulatorContainer.Emulator.LOGGING, p) - ); + .ifPresent(p -> firebaseConfigBuilder.withEmulatorOnFixedPort(FirebaseEmulatorContainer.Emulator.LOGGING, p)); config.storage() .rulesFile() diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java index cd441cc7..49397aca 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilderTest.java @@ -17,9 +17,8 @@ class FirebaseEmulatorConfigBuilderTest { @BeforeEach void setUp() { - var projectConfig= new TestProjectConfig( - Optional.of("my-project-id") - ); + var projectConfig = new TestProjectConfig( + Optional.of("my-project-id")); var config = new TestFirebaseDevServiceConfig( new TestFirebase( true, @@ -32,55 +31,43 @@ void setUp() { Optional.empty(), Optional.empty(), Optional.of(false), - Optional.of(true) - ), + Optional.of(true)), new TestCli( Optional.of("MY_TOKEN"), Optional.of("-Xmx"), Optional.of("data"), Optional.of(FirebaseEmulatorContainer.ImportExport.EXPORT_ONLY), - Optional.of(true) - ), + Optional.of(true)), Optional.empty(), new TestUI( true, Optional.of(6000), Optional.of(6001), - Optional.of(6002) - ) - ), + Optional.of(6002))), new TestGenericDevService(true, Optional.of(6003)), new TestHosting( true, Optional.of(6004), - Optional.of("public") - ), + Optional.of("public")), new TestGenericDevService( false, - Optional.of(6005) - ), + Optional.of(6005)), new TestFirestoreDevService( true, Optional.of(6006), Optional.of(6007), Optional.of("firestore.rules"), - Optional.of("firestore.indexes.json") - ) - ), - new TestGenericDevService( - true, - Optional.of(6008) - ), - new TestGenericDevService( - true, - Optional.of(6009) - ), - new TestStorageDevService( - true, - Optional.empty(), - Optional.of("storage.rules") - ) - ); + Optional.of("firestore.indexes.json"))), + new TestGenericDevService( + true, + Optional.of(6008)), + new TestGenericDevService( + true, + Optional.of(6009)), + new TestStorageDevService( + true, + Optional.empty(), + Optional.of("storage.rules"))); configBuilder = new FirebaseEmulatorConfigBuilder(projectConfig, config); } @@ -144,8 +131,7 @@ void testExposedEmulators() { // Record implementations for interfaces record TestProjectConfig( - Optional projectId - ) implements FirebaseDevServiceProjectConfig { + Optional projectId) implements FirebaseDevServiceProjectConfig { } record TestFirebaseDevServiceConfig( @@ -161,8 +147,7 @@ record TestFirebase( FirebaseDevServiceConfig.GenericDevService auth, FirebaseDevServiceConfig.Firebase.HostingDevService hosting, FirebaseDevServiceConfig.GenericDevService database, - FirebaseDevServiceConfig.Firebase.FirestoreDevService firestore - ) implements FirebaseDevServiceConfig.Firebase { + FirebaseDevServiceConfig.Firebase.FirestoreDevService firestore) implements FirebaseDevServiceConfig.Firebase { } @@ -181,8 +166,7 @@ record TestDocker( Optional dockerUserEnv, Optional dockerGroupEnv, Optional followStdOut, - Optional followStdErr - ) implements FirebaseDevServiceConfig.Firebase.Emulator.Docker { + Optional followStdErr) implements FirebaseDevServiceConfig.Firebase.Emulator.Docker { } record TestCli( @@ -190,8 +174,7 @@ record TestCli( Optional javaToolOptions, Optional emulatorData, Optional importExport, - Optional debug - ) implements FirebaseDevServiceConfig.Firebase.Emulator.Cli { + Optional debug) implements FirebaseDevServiceConfig.Firebase.Emulator.Cli { } record TestUI( From dda79bf492ac811cfbdd7beb1d7377f2ffcf8eaa Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Sun, 15 Dec 2024 23:45:43 +0100 Subject: [PATCH 077/101] Removed obsolete test --- ...ebaseEmulatorContainerIntegrationTest.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java index be149938..ceefe665 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java @@ -152,29 +152,6 @@ private static void validateEmulatorDataWritten() { assertTrue(files.length > 0, "Expected files to be present in the emulator data directory"); } - @Test - @Disabled - public void testFirebaseHostingEmulatorConnection() throws Exception { - // Validate that the static HTML file is accessible via HTTP - int hostingPort = firebaseContainer.emulatorPort(FirebaseEmulatorContainer.Emulator.FIREBASE_HOSTING); - - // Construct URL for the hosted file - URL url = new URI("http://" + firebaseContainer.getHost() + ":" + hostingPort + "/index.html").toURL(); - - // Fetch content from the URL - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - int responseCode = connection.getResponseCode(); - - assertEquals(200, responseCode, "Expected HTTP status 200 for index.html"); - - try (BufferedReader reader = new BufferedReader( - new InputStreamReader(connection.getInputStream(), Charset.defaultCharset()))) { - String line = reader.readLine(); - assertTrue(line.contains("Hello, Firebase Hosting!"), "Expected content in index.html"); - } - } - @Test public void testFirebaseAuthenticationEmulatorConnection() throws FirebaseAuthException { // Retrieve the host and port for the Authentication emulator From be35c0ee962973c300f1f6461120b0114be8159a Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Mon, 16 Dec 2024 17:27:42 +0100 Subject: [PATCH 078/101] Fix storage unit test --- ...ebaseEmulatorContainerIntegrationTest.java | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java index ceefe665..68d7d7eb 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java @@ -10,6 +10,8 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -264,8 +266,7 @@ public void testPubSubEmulatorConnection() throws Exception { } @Test - @Disabled - public void testStorageEmulatorConnection() { + public void testStorageEmulatorConnection() throws IOException { int storagePort = firebaseContainer.emulatorPort(FirebaseEmulatorContainer.Emulator.CLOUD_STORAGE); Storage storage = StorageOptions.newBuilder() @@ -274,21 +275,23 @@ public void testStorageEmulatorConnection() { .setCredentials(NoCredentials.getInstance()) .build().getService(); - var bucketName = "quarkus-hello"; + var bucketName = "demo-test-project.appspot.com"; - Bucket bucket = storage.get(bucketName); - if (bucket == null) { - bucket = storage.create(BucketInfo.newBuilder(bucketName).build()); - } - bucket.create("hello.txt", "{\"success\": true}".getBytes(StandardCharsets.UTF_8)); + BlobInfo blobInfo = BlobInfo.newBuilder(bucketName, "test-upload") + .setContentType("application/json") + .setContentDisposition("attachment; filename=\"test-upload\"") + .build(); - BlobInfo blobInfo = BlobInfo.newBuilder(bucketName, "test-upload").build(); - storage.create(blobInfo, "test".getBytes(StandardCharsets.UTF_8)); + try (var writer = storage.writer(blobInfo)) { + writer.write(ByteBuffer.wrap( "{\"test\": 1}".getBytes(StandardCharsets.UTF_8))); + } - // Verify the content of the uploaded file - Blob blob = bucket.get("hello.txt"); - assertEquals("{\"success\": true}", new String(blob.getContent(), Charset.defaultCharset()), - "Expected blob content to match"); + try (var reader = storage.reader(blobInfo.getBlobId())) { + try (var bufReader = new BufferedReader(Channels.newReader(reader, StandardCharsets.UTF_8))) { + var contents = bufReader.readLine(); + assertEquals("{\"test\": 1}", contents, "Expected blob content to match"); + } + } } @Test From e9de6dc7ab296205dc23f9b9a152d0d1e569d77f Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Mon, 16 Dec 2024 20:18:50 +0100 Subject: [PATCH 079/101] Merge in main --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 024175b6..b0d4b19d 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -19,7 +19,7 @@ UTF-8 26.50.0 - 9.4.1 + 9.4.2 0.31.1 From 4592f1180442d3151225a3eee99b1cf97903d42b Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Tue, 17 Dec 2024 11:19:14 +0100 Subject: [PATCH 080/101] Fix config mapping to match mapping in quarkus.extension.yaml --- .../admin/runtime/FirebaseAdminProducer.java | 5 +-- .../admin/runtime/FirebaseAuthConfig.java | 34 ++++++++++++------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java index 4d160977..f3246012 100644 --- a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java +++ b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAdminProducer.java @@ -38,7 +38,8 @@ public class FirebaseAdminProducer { public FirebaseAuth firestoreAuth(@ConfigMapping FirebaseAuthConfig firebaseAuthConfig, FirebaseApp firebaseApp) { // Configure the Firebase emulator to use. - firebaseAuthConfig.emulatorHost().ifPresent(host -> FirebaseProcessEnvironment.setenv(Utils.AUTH_EMULATOR_HOST, host)); + firebaseAuthConfig.auth().emulatorHost() + .ifPresent(host -> FirebaseProcessEnvironment.setenv(Utils.AUTH_EMULATOR_HOST, host)); return FirebaseAuth.getInstance(firebaseApp); } @@ -61,7 +62,7 @@ public FirebaseApp getFirebaseApp() { } private GoogleCredentials googleCredentials() { - if (firebaseAuthConfig.emulatorHost().isPresent() && firebaseAuthConfig.useEmulatorCredentials()) { + if (firebaseAuthConfig.auth().emulatorHost().isPresent() && firebaseAuthConfig.auth().useEmulatorCredentials()) { return new EmulatorCredentials(); } else { return (GoogleCredentials) googleCredentials.get(); diff --git a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java index d6032f23..03dddb46 100644 --- a/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java +++ b/firebase-admin/runtime/src/main/java/io/quarkiverse/googlecloudservices/firebase/admin/runtime/FirebaseAuthConfig.java @@ -14,24 +14,32 @@ * Emulator is running. * */ -@ConfigMapping(prefix = "quarkus.google.cloud.firebase.auth") +@ConfigMapping(prefix = "quarkus.google.cloud.firebase") @ConfigRoot(phase = ConfigPhase.RUN_TIME) public interface FirebaseAuthConfig { /** - * Sets the emulator host to use. + * Returns the auth configuration */ - Optional emulatorHost(); + AuthConfig auth(); - /** - * Forces the usage of emulator credentials. The logic automatically uses emulator credentials in case - * the emulatorHost is set. - *

    - *
  • If true: force usage of emulator credentials
  • - *
  • If false: force not using emulator credentials
  • - *
- */ - @WithDefault("true") - boolean useEmulatorCredentials(); + public interface AuthConfig { + /** + * Sets the emulator host to use. + */ + Optional emulatorHost(); + + /** + * Forces the usage of emulator credentials. The logic automatically uses emulator credentials in case + * the emulatorHost is set. + *
    + *
  • If true: force usage of emulator credentials
  • + *
  • If false: force not using emulator credentials
  • + *
+ */ + @WithDefault("true") + boolean useEmulatorCredentials(); + + } } From 06957c130b18083201a32ba63e65e22f4cc63b53 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Tue, 17 Dec 2024 11:19:43 +0100 Subject: [PATCH 081/101] Formatting fixed --- .../FirebaseEmulatorContainerIntegrationTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java index 68d7d7eb..2db357fb 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java @@ -22,7 +22,6 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.testcontainers.junit.jupiter.Testcontainers; @@ -36,7 +35,6 @@ import com.google.cloud.pubsub.v1.TopicAdminClient; import com.google.cloud.pubsub.v1.TopicAdminSettings; import com.google.cloud.storage.*; -import com.google.cloud.storage.Blob; import com.google.firebase.FirebaseOptions; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseAuthException; @@ -283,7 +281,7 @@ public void testStorageEmulatorConnection() throws IOException { .build(); try (var writer = storage.writer(blobInfo)) { - writer.write(ByteBuffer.wrap( "{\"test\": 1}".getBytes(StandardCharsets.UTF_8))); + writer.write(ByteBuffer.wrap("{\"test\": 1}".getBytes(StandardCharsets.UTF_8))); } try (var reader = storage.reader(blobInfo.getBlobId())) { From a2547bde13fd3e2308cb09fbba1166e229f9303c Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Tue, 17 Dec 2024 11:19:54 +0100 Subject: [PATCH 082/101] Documentation regenerated --- ...kus-google-cloud-firebase-devservices.adoc | 314 ++++++++++++------ ...d-firebase-devservices_quarkus.google.adoc | 314 ++++++++++++------ 2 files changed, 416 insertions(+), 212 deletions(-) diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc index c7fb8c0c..d180a2b2 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices.adoc @@ -24,7 +24,7 @@ endif::add-copy-button-to-env-var[] |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services[`quarkus.google.cloud.firebase.devservice.prefer-firebase-dev-services`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-prefer-firebase-dev-services[`quarkus.google.cloud.devservices.firebase.prefer-firebase-dev-services`]## [.description] -- @@ -32,16 +32,33 @@ Indicates to use the dev service for Firebase. The default value is true. This i ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_PREFER_FIREBASE_DEV_SERVICES+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_PREFER_FIREBASE_DEV_SERVICES+++` endif::add-copy-button-to-env-var[] -- |boolean |`true` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-image-name]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-image-name[`quarkus.google.cloud.firebase.devservice.image-name`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-firebase-version]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-firebase-version[`quarkus.google.cloud.devservices.firebase.emulator.firebase-version`]## + +[.description] +-- +The version of the firebase tools to use. Default is to use the latest available version. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_FIREBASE_VERSION+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_FIREBASE_VERSION+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`latest` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-image-name]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-image-name[`quarkus.google.cloud.devservices.firebase.emulator.docker.image-name`]## [.description] -- @@ -51,16 +68,16 @@ See also the documentation on Custom Docker images for more info about this imag ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_IMAGE_NAME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_IMAGE_NAME+++` endif::add-copy-button-to-env-var[] -- |string -|`node:23-alpine` +|`node:20-alpine` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-user]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-user[`quarkus.google.cloud.firebase.devservice.docker-user`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-user]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-user[`quarkus.google.cloud.devservices.firebase.emulator.docker.docker-user`]## [.description] -- @@ -68,16 +85,16 @@ Id of the docker user to run the firebase executable. This is needed in environm ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_USER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_USER+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-group]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-group[`quarkus.google.cloud.firebase.devservice.docker-group`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-group]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-group[`quarkus.google.cloud.devservices.firebase.emulator.docker.docker-group`]## [.description] -- @@ -85,75 +102,101 @@ Id of the group to which the `docker-user()` belongs. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_GROUP+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_GROUP+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-firebase-version]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-firebase-version[`quarkus.google.cloud.firebase.devservice.firebase-version`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-user-env]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-user-env[`quarkus.google.cloud.devservices.firebase.emulator.docker.docker-user-env`]## [.description] -- -The version of the firebase tools to use. Default is to use the latest available version. +Try to read the `docker-user()` from an environment variable ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_USER_ENV+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_USER_ENV+++` endif::add-copy-button-to-env-var[] -- |string -|`latest` +| -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-token]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-token[`quarkus.google.cloud.firebase.devservice.token`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-group-env]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-group-env[`quarkus.google.cloud.devservices.firebase.emulator.docker.docker-group-env`]## [.description] -- -The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This option is mandatory if you use firebase hosting. +Try to read the `docker-group()` from an environment variable ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_GROUP_ENV+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_GROUP_ENV+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-custom-firebase-json]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-custom-firebase-json[`quarkus.google.cloud.firebase.devservice.custom-firebase-json`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-follow-std-out]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-follow-std-out[`quarkus.google.cloud.devservices.firebase.emulator.docker.follow-std-out`]## [.description] -- -Indicate to use a custom firebase.json file instead of the automatically generated one. The custom firebase.json file MUST include a setting of +Pipe Stdout of the container to the Quarkus logging -``` -"host" : "0.0.0.0" -``` -to ensure the ports of the emulator are exposed correctly at the docker container level. +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_FOLLOW_STD_OUT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_FOLLOW_STD_OUT+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| -See the section on Custom Firebase Json in the docs for more info. +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-follow-std-err]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-follow-std-err[`quarkus.google.cloud.devservices.firebase.emulator.docker.follow-std-err`]## + +[.description] +-- +Pipe Stedd of the container to the Quarkus logging + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_FOLLOW_STD_ERR+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_FOLLOW_STD_ERR+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-token]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-token[`quarkus.google.cloud.devservices.firebase.emulator.cli.token`]## + +[.description] +-- +The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This option is mandatory if you use firebase hosting. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_TOKEN+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_TOKEN+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-java-tool-options]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-java-tool-options[`quarkus.google.cloud.firebase.devservice.java-tool-options`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-java-tool-options]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-java-tool-options[`quarkus.google.cloud.devservices.firebase.emulator.cli.java-tool-options`]## [.description] -- @@ -161,16 +204,16 @@ Sets the JAVA tool options for emulators based on the Java runtime environment l ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_JAVA_TOOL_OPTIONS+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_JAVA_TOOL_OPTIONS+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-emulator-data]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-emulator-data[`quarkus.google.cloud.firebase.devservice.emulator-data`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-emulator-data]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-emulator-data[`quarkus.google.cloud.devservices.firebase.emulator.cli.emulator-data`]## [.description] -- @@ -178,16 +221,75 @@ Allow to import and export data. Specify a path relative to the current working ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_EMULATOR_DATA+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_EMULATOR_DATA+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-import-export]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-import-export[`quarkus.google.cloud.devservices.firebase.emulator.cli.import-export`]## + +[.description] +-- +Indicate whether to import, export or both the data specified in `emulator-data()` + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_IMPORT_EXPORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_IMPORT_EXPORT+++` +endif::add-copy-button-to-env-var[] +-- +a|`import-only`, `export-only`, `import-export` +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-debug]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-debug[`quarkus.google.cloud.devservices.firebase.emulator.cli.debug`]## + +[.description] +-- +Enable firebase emulators debugging. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_DEBUG+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_DEBUG+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-custom-firebase-json]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-custom-firebase-json[`quarkus.google.cloud.devservices.firebase.emulator.custom-firebase-json`]## + +[.description] +-- +Indicate to use a custom firebase.json file instead of the automatically generated one. The custom firebase.json file MUST include a setting of + +``` +"host" : "0.0.0.0" +``` + +to ensure the ports of the emulator are exposed correctly at the docker container level. + +See the section on Custom Firebase Json in the docs for more info. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CUSTOM_FIREBASE_JSON+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CUSTOM_FIREBASE_JSON+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-enabled[`quarkus.google.cloud.firebase.devservice.ui.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-enabled[`quarkus.google.cloud.devservices.firebase.emulator.ui.enabled`]## [.description] -- @@ -195,16 +297,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`true` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-emulator-port[`quarkus.google.cloud.firebase.devservice.ui.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-emulator-port[`quarkus.google.cloud.devservices.firebase.emulator.ui.emulator-port`]## [.description] -- @@ -212,16 +314,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-logging-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-logging-port[`quarkus.google.cloud.firebase.devservice.ui.logging-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-logging-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-logging-port[`quarkus.google.cloud.devservices.firebase.emulator.ui.logging-port`]## [.description] -- @@ -229,16 +331,16 @@ Port on which to expose the logging endpoint port. This is needed in case you wa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_LOGGING_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_LOGGING_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-hub-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-hub-port[`quarkus.google.cloud.firebase.devservice.ui.hub-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-hub-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-hub-port[`quarkus.google.cloud.devservices.firebase.emulator.ui.hub-port`]## [.description] -- @@ -246,16 +348,16 @@ Port on which to expose the hub endpoint port. This is needed if you want to use ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_HUB_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_HUB_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-enabled[`quarkus.google.cloud.firebase.auth.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-auth-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-auth-enabled[`quarkus.google.cloud.devservices.firebase.auth.enabled`]## [.description] -- @@ -263,16 +365,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_AUTH_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_AUTH_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-emulator-port[`quarkus.google.cloud.firebase.auth.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-auth-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-auth-emulator-port[`quarkus.google.cloud.devservices.firebase.auth.emulator-port`]## [.description] -- @@ -280,16 +382,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_AUTH_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_AUTH_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-enabled[`quarkus.google.cloud.firebase.hosting.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-hosting-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-hosting-enabled[`quarkus.google.cloud.devservices.firebase.hosting.enabled`]## [.description] -- @@ -297,16 +399,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_HOSTING_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_HOSTING_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-emulator-port[`quarkus.google.cloud.firebase.hosting.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-hosting-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-hosting-emulator-port[`quarkus.google.cloud.devservices.firebase.hosting.emulator-port`]## [.description] -- @@ -314,16 +416,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_HOSTING_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_HOSTING_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-hosting-path]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-hosting-path[`quarkus.google.cloud.firebase.hosting.hosting-path`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-hosting-hosting-path]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-hosting-hosting-path[`quarkus.google.cloud.devservices.firebase.hosting.hosting-path`]## [.description] -- @@ -331,16 +433,16 @@ Path to the hosting files. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_HOSTING_HOSTING_PATH+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_HOSTING_HOSTING_PATH+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-enabled[`quarkus.google.cloud.database.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-database-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-database-enabled[`quarkus.google.cloud.devservices.firebase.database.enabled`]## [.description] -- @@ -348,16 +450,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_DATABASE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_DATABASE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-emulator-port[`quarkus.google.cloud.database.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-database-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-database-emulator-port[`quarkus.google.cloud.devservices.firebase.database.emulator-port`]## [.description] -- @@ -365,16 +467,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_DATABASE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_DATABASE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-enabled[`quarkus.google.cloud.firestore.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-enabled[`quarkus.google.cloud.devservices.firebase.firestore.enabled`]## [.description] -- @@ -382,16 +484,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-emulator-port[`quarkus.google.cloud.firestore.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-emulator-port[`quarkus.google.cloud.devservices.firebase.firestore.emulator-port`]## [.description] -- @@ -399,16 +501,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-websocket-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-websocket-port[`quarkus.google.cloud.firestore.devservice.websocket-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-websocket-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-websocket-port[`quarkus.google.cloud.devservices.firebase.firestore.websocket-port`]## [.description] -- @@ -416,16 +518,16 @@ Port on which to expose the websocket port. This is needed in case the Firestore ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_WEBSOCKET_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_WEBSOCKET_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-rules-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-rules-file[`quarkus.google.cloud.firestore.devservice.rules-file`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-rules-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-rules-file[`quarkus.google.cloud.devservices.firebase.firestore.rules-file`]## [.description] -- @@ -433,16 +535,16 @@ Path to the firestore.rules file. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_RULES_FILE+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_RULES_FILE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_RULES_FILE+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_RULES_FILE+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-indexes-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-indexes-file[`quarkus.google.cloud.firestore.devservice.indexes-file`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-indexes-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-indexes-file[`quarkus.google.cloud.devservices.firebase.firestore.indexes-file`]## [.description] -- @@ -450,16 +552,16 @@ Path to the firestore.indexes.json file. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_INDEXES_FILE+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_INDEXES_FILE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_INDEXES_FILE+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_INDEXES_FILE+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-enabled[`quarkus.google.cloud.functions.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-functions-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-functions-enabled[`quarkus.google.cloud.devservices.functions.enabled`]## [.description] -- @@ -467,16 +569,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FUNCTIONS_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FUNCTIONS_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-emulator-port[`quarkus.google.cloud.functions.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-functions-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-functions-emulator-port[`quarkus.google.cloud.devservices.functions.emulator-port`]## [.description] -- @@ -484,16 +586,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FUNCTIONS_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FUNCTIONS_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-enabled[`quarkus.google.cloud.pubsub.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-pubsub-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-pubsub-enabled[`quarkus.google.cloud.devservices.pubsub.enabled`]## [.description] -- @@ -501,16 +603,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_PUBSUB_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_PUBSUB_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-emulator-port[`quarkus.google.cloud.pubsub.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-pubsub-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-pubsub-emulator-port[`quarkus.google.cloud.devservices.pubsub.emulator-port`]## [.description] -- @@ -518,16 +620,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_PUBSUB_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_PUBSUB_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-enabled[`quarkus.google.cloud.storage.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-storage-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-storage-enabled[`quarkus.google.cloud.devservices.storage.enabled`]## [.description] -- @@ -535,16 +637,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_STORAGE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_STORAGE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-emulator-port[`quarkus.google.cloud.storage.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-storage-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-storage-emulator-port[`quarkus.google.cloud.devservices.storage.emulator-port`]## [.description] -- @@ -552,16 +654,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_STORAGE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_STORAGE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-rules-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-rules-file[`quarkus.google.cloud.storage.devservice.rules-file`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-storage-rules-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-storage-rules-file[`quarkus.google.cloud.devservices.storage.rules-file`]## [.description] -- @@ -569,10 +671,10 @@ Path to the storage.rules file. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_RULES_FILE+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_STORAGE_RULES_FILE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_RULES_FILE+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_STORAGE_RULES_FILE+++` endif::add-copy-button-to-env-var[] -- |string diff --git a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc index c7fb8c0c..d180a2b2 100644 --- a/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc +++ b/docs/modules/ROOT/pages/includes/quarkus-google-cloud-firebase-devservices_quarkus.google.adoc @@ -24,7 +24,7 @@ endif::add-copy-button-to-env-var[] |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-prefer-firebase-dev-services[`quarkus.google.cloud.firebase.devservice.prefer-firebase-dev-services`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-prefer-firebase-dev-services]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-prefer-firebase-dev-services[`quarkus.google.cloud.devservices.firebase.prefer-firebase-dev-services`]## [.description] -- @@ -32,16 +32,33 @@ Indicates to use the dev service for Firebase. The default value is true. This i ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_PREFER_FIREBASE_DEV_SERVICES+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_PREFER_FIREBASE_DEV_SERVICES+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_PREFER_FIREBASE_DEV_SERVICES+++` endif::add-copy-button-to-env-var[] -- |boolean |`true` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-image-name]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-image-name[`quarkus.google.cloud.firebase.devservice.image-name`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-firebase-version]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-firebase-version[`quarkus.google.cloud.devservices.firebase.emulator.firebase-version`]## + +[.description] +-- +The version of the firebase tools to use. Default is to use the latest available version. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_FIREBASE_VERSION+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_FIREBASE_VERSION+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`latest` + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-image-name]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-image-name[`quarkus.google.cloud.devservices.firebase.emulator.docker.image-name`]## [.description] -- @@ -51,16 +68,16 @@ See also the documentation on Custom Docker images for more info about this imag ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_IMAGE_NAME+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_IMAGE_NAME+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_IMAGE_NAME+++` endif::add-copy-button-to-env-var[] -- |string -|`node:23-alpine` +|`node:20-alpine` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-user]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-user[`quarkus.google.cloud.firebase.devservice.docker-user`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-user]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-user[`quarkus.google.cloud.devservices.firebase.emulator.docker.docker-user`]## [.description] -- @@ -68,16 +85,16 @@ Id of the docker user to run the firebase executable. This is needed in environm ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_USER+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_USER+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_USER+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-group]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-docker-group[`quarkus.google.cloud.firebase.devservice.docker-group`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-group]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-group[`quarkus.google.cloud.devservices.firebase.emulator.docker.docker-group`]## [.description] -- @@ -85,75 +102,101 @@ Id of the group to which the `docker-user()` belongs. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_GROUP+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_DOCKER_GROUP+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_GROUP+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-firebase-version]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-firebase-version[`quarkus.google.cloud.firebase.devservice.firebase-version`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-user-env]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-user-env[`quarkus.google.cloud.devservices.firebase.emulator.docker.docker-user-env`]## [.description] -- -The version of the firebase tools to use. Default is to use the latest available version. +Try to read the `docker-user()` from an environment variable ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_USER_ENV+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_FIREBASE_VERSION+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_USER_ENV+++` endif::add-copy-button-to-env-var[] -- |string -|`latest` +| -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-token]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-token[`quarkus.google.cloud.firebase.devservice.token`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-group-env]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-docker-group-env[`quarkus.google.cloud.devservices.firebase.emulator.docker.docker-group-env`]## [.description] -- -The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This option is mandatory if you use firebase hosting. +Try to read the `docker-group()` from an environment variable ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_GROUP_ENV+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_TOKEN+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_DOCKER_GROUP_ENV+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-custom-firebase-json]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-custom-firebase-json[`quarkus.google.cloud.firebase.devservice.custom-firebase-json`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-follow-std-out]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-follow-std-out[`quarkus.google.cloud.devservices.firebase.emulator.docker.follow-std-out`]## [.description] -- -Indicate to use a custom firebase.json file instead of the automatically generated one. The custom firebase.json file MUST include a setting of +Pipe Stdout of the container to the Quarkus logging -``` -"host" : "0.0.0.0" -``` -to ensure the ports of the emulator are exposed correctly at the docker container level. +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_FOLLOW_STD_OUT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_FOLLOW_STD_OUT+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| -See the section on Custom Firebase Json in the docs for more info. +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-follow-std-err]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-docker-follow-std-err[`quarkus.google.cloud.devservices.firebase.emulator.docker.follow-std-err`]## + +[.description] +-- +Pipe Stedd of the container to the Quarkus logging + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_FOLLOW_STD_ERR+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_DOCKER_FOLLOW_STD_ERR+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-token]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-token[`quarkus.google.cloud.devservices.firebase.emulator.cli.token`]## + +[.description] +-- +The token to use for firebase authentication. Run `firebase login:ci` locally to get a new token. This option is mandatory if you use firebase hosting. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_TOKEN+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_CUSTOM_FIREBASE_JSON+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_TOKEN+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-java-tool-options]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-java-tool-options[`quarkus.google.cloud.firebase.devservice.java-tool-options`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-java-tool-options]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-java-tool-options[`quarkus.google.cloud.devservices.firebase.emulator.cli.java-tool-options`]## [.description] -- @@ -161,16 +204,16 @@ Sets the JAVA tool options for emulators based on the Java runtime environment l ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_JAVA_TOOL_OPTIONS+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_JAVA_TOOL_OPTIONS+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_JAVA_TOOL_OPTIONS+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-emulator-data]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-emulator-data[`quarkus.google.cloud.firebase.devservice.emulator-data`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-emulator-data]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-emulator-data[`quarkus.google.cloud.devservices.firebase.emulator.cli.emulator-data`]## [.description] -- @@ -178,16 +221,75 @@ Allow to import and export data. Specify a path relative to the current working ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_EMULATOR_DATA+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_EMULATOR_DATA+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-import-export]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-import-export[`quarkus.google.cloud.devservices.firebase.emulator.cli.import-export`]## + +[.description] +-- +Indicate whether to import, export or both the data specified in `emulator-data()` + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_IMPORT_EXPORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_IMPORT_EXPORT+++` +endif::add-copy-button-to-env-var[] +-- +a|`import-only`, `export-only`, `import-export` +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-debug]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-cli-debug[`quarkus.google.cloud.devservices.firebase.emulator.cli.debug`]## + +[.description] +-- +Enable firebase emulators debugging. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_DEBUG+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CLI_DEBUG+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| + +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-custom-firebase-json]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-custom-firebase-json[`quarkus.google.cloud.devservices.firebase.emulator.custom-firebase-json`]## + +[.description] +-- +Indicate to use a custom firebase.json file instead of the automatically generated one. The custom firebase.json file MUST include a setting of + +``` +"host" : "0.0.0.0" +``` + +to ensure the ports of the emulator are exposed correctly at the docker container level. + +See the section on Custom Firebase Json in the docs for more info. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CUSTOM_FIREBASE_JSON+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_EMULATOR_DATA+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_CUSTOM_FIREBASE_JSON+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-enabled[`quarkus.google.cloud.firebase.devservice.ui.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-enabled[`quarkus.google.cloud.devservices.firebase.emulator.ui.enabled`]## [.description] -- @@ -195,16 +297,16 @@ Indicates whether the service should be enabled or not. The default value is 'fa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`true` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-emulator-port[`quarkus.google.cloud.firebase.devservice.ui.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-emulator-port[`quarkus.google.cloud.devservices.firebase.emulator.ui.emulator-port`]## [.description] -- @@ -212,16 +314,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-logging-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-logging-port[`quarkus.google.cloud.firebase.devservice.ui.logging-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-logging-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-logging-port[`quarkus.google.cloud.devservices.firebase.emulator.ui.logging-port`]## [.description] -- @@ -229,16 +331,16 @@ Port on which to expose the logging endpoint port. This is needed in case you wa ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_LOGGING_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_LOGGING_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_LOGGING_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-hub-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-devservice-ui-hub-port[`quarkus.google.cloud.firebase.devservice.ui.hub-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-hub-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-emulator-ui-hub-port[`quarkus.google.cloud.devservices.firebase.emulator.ui.hub-port`]## [.description] -- @@ -246,16 +348,16 @@ Port on which to expose the hub endpoint port. This is needed if you want to use ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_HUB_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_DEVSERVICE_UI_HUB_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_EMULATOR_UI_HUB_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-enabled[`quarkus.google.cloud.firebase.auth.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-auth-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-auth-enabled[`quarkus.google.cloud.devservices.firebase.auth.enabled`]## [.description] -- @@ -263,16 +365,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_AUTH_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_AUTH_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-auth-devservice-emulator-port[`quarkus.google.cloud.firebase.auth.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-auth-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-auth-emulator-port[`quarkus.google.cloud.devservices.firebase.auth.emulator-port`]## [.description] -- @@ -280,16 +382,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_AUTH_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_AUTH_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_AUTH_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-enabled[`quarkus.google.cloud.firebase.hosting.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-hosting-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-hosting-enabled[`quarkus.google.cloud.devservices.firebase.hosting.enabled`]## [.description] -- @@ -297,16 +399,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_HOSTING_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_HOSTING_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-devservice-emulator-port[`quarkus.google.cloud.firebase.hosting.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-hosting-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-hosting-emulator-port[`quarkus.google.cloud.devservices.firebase.hosting.emulator-port`]## [.description] -- @@ -314,16 +416,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_HOSTING_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_HOSTING_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-hosting-path]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firebase-hosting-hosting-path[`quarkus.google.cloud.firebase.hosting.hosting-path`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-hosting-hosting-path]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-hosting-hosting-path[`quarkus.google.cloud.devservices.firebase.hosting.hosting-path`]## [.description] -- @@ -331,16 +433,16 @@ Path to the hosting files. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_HOSTING_HOSTING_PATH+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIREBASE_HOSTING_HOSTING_PATH+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_HOSTING_HOSTING_PATH+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-enabled[`quarkus.google.cloud.database.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-database-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-database-enabled[`quarkus.google.cloud.devservices.firebase.database.enabled`]## [.description] -- @@ -348,16 +450,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_DATABASE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_DATABASE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-database-devservice-emulator-port[`quarkus.google.cloud.database.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-database-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-database-emulator-port[`quarkus.google.cloud.devservices.firebase.database.emulator-port`]## [.description] -- @@ -365,16 +467,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_DATABASE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DATABASE_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_DATABASE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-enabled[`quarkus.google.cloud.firestore.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-enabled[`quarkus.google.cloud.devservices.firebase.firestore.enabled`]## [.description] -- @@ -382,16 +484,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-emulator-port[`quarkus.google.cloud.firestore.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-emulator-port[`quarkus.google.cloud.devservices.firebase.firestore.emulator-port`]## [.description] -- @@ -399,16 +501,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-websocket-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-websocket-port[`quarkus.google.cloud.firestore.devservice.websocket-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-websocket-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-websocket-port[`quarkus.google.cloud.devservices.firebase.firestore.websocket-port`]## [.description] -- @@ -416,16 +518,16 @@ Port on which to expose the websocket port. This is needed in case the Firestore ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_WEBSOCKET_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_WEBSOCKET_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_WEBSOCKET_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-rules-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-rules-file[`quarkus.google.cloud.firestore.devservice.rules-file`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-rules-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-rules-file[`quarkus.google.cloud.devservices.firebase.firestore.rules-file`]## [.description] -- @@ -433,16 +535,16 @@ Path to the firestore.rules file. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_RULES_FILE+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_RULES_FILE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_RULES_FILE+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_RULES_FILE+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-indexes-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-firestore-devservice-indexes-file[`quarkus.google.cloud.firestore.devservice.indexes-file`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-indexes-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-firebase-firestore-indexes-file[`quarkus.google.cloud.devservices.firebase.firestore.indexes-file`]## [.description] -- @@ -450,16 +552,16 @@ Path to the firestore.indexes.json file. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_INDEXES_FILE+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_INDEXES_FILE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FIRESTORE_DEVSERVICE_INDEXES_FILE+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FIREBASE_FIRESTORE_INDEXES_FILE+++` endif::add-copy-button-to-env-var[] -- |string | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-enabled[`quarkus.google.cloud.functions.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-functions-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-functions-enabled[`quarkus.google.cloud.devservices.functions.enabled`]## [.description] -- @@ -467,16 +569,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FUNCTIONS_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FUNCTIONS_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-functions-devservice-emulator-port[`quarkus.google.cloud.functions.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-functions-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-functions-emulator-port[`quarkus.google.cloud.devservices.functions.emulator-port`]## [.description] -- @@ -484,16 +586,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FUNCTIONS_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_FUNCTIONS_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_FUNCTIONS_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-enabled[`quarkus.google.cloud.pubsub.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-pubsub-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-pubsub-enabled[`quarkus.google.cloud.devservices.pubsub.enabled`]## [.description] -- @@ -501,16 +603,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_PUBSUB_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_PUBSUB_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-pubsub-devservice-emulator-port[`quarkus.google.cloud.pubsub.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-pubsub-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-pubsub-emulator-port[`quarkus.google.cloud.devservices.pubsub.emulator-port`]## [.description] -- @@ -518,16 +620,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_PUBSUB_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_PUBSUB_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_PUBSUB_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-enabled[`quarkus.google.cloud.storage.devservice.enabled`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-storage-enabled]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-storage-enabled[`quarkus.google.cloud.devservices.storage.enabled`]## [.description] -- @@ -535,16 +637,16 @@ Indicates whether the DevService should be enabled or not. The default value is ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_STORAGE_ENABLED+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_ENABLED+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_STORAGE_ENABLED+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-emulator-port[`quarkus.google.cloud.storage.devservice.emulator-port`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-storage-emulator-port]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-storage-emulator-port[`quarkus.google.cloud.devservices.storage.emulator-port`]## [.description] -- @@ -552,16 +654,16 @@ Specifies the emulatorPort on which the service should run in the development en ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_STORAGE_EMULATOR_PORT+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_EMULATOR_PORT+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_STORAGE_EMULATOR_PORT+++` endif::add-copy-button-to-env-var[] -- |int | -a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-rules-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-storage-devservice-rules-file[`quarkus.google.cloud.storage.devservice.rules-file`]## +a|icon:lock[title=Fixed at build time] [[quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-storage-rules-file]] [.property-path]##link:#quarkus-google-cloud-firebase-devservices_quarkus-google-cloud-devservices-storage-rules-file[`quarkus.google.cloud.devservices.storage.rules-file`]## [.description] -- @@ -569,10 +671,10 @@ Path to the storage.rules file. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_RULES_FILE+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_STORAGE_RULES_FILE+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_GOOGLE_CLOUD_STORAGE_DEVSERVICE_RULES_FILE+++` +Environment variable: `+++QUARKUS_GOOGLE_CLOUD_DEVSERVICES_STORAGE_RULES_FILE+++` endif::add-copy-button-to-env-var[] -- |string From 51111909dcdd5b77dd77b7f26051a932ed212c1c Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Tue, 17 Dec 2024 11:20:50 +0100 Subject: [PATCH 083/101] Removed dependency on firebase-devservices from firebase-admin. No need to have this dependnecy. --- firebase-admin/deployment/pom.xml | 8 -------- firebase-admin/runtime/pom.xml | 4 ---- 2 files changed, 12 deletions(-) diff --git a/firebase-admin/deployment/pom.xml b/firebase-admin/deployment/pom.xml index 00764387..12597c41 100644 --- a/firebase-admin/deployment/pom.xml +++ b/firebase-admin/deployment/pom.xml @@ -38,18 +38,10 @@ io.quarkiverse.googlecloudservices quarkus-google-cloud-common-deployment - - io.quarkiverse.googlecloudservices - quarkus-google-cloud-firebase-devservices-deployment - io.quarkiverse.googlecloudservices quarkus-google-cloud-firebase-admin - - io.quarkiverse.googlecloudservices - quarkus-google-cloud-firebase-devservices - diff --git a/firebase-admin/runtime/pom.xml b/firebase-admin/runtime/pom.xml index a49e23ed..37db70ae 100644 --- a/firebase-admin/runtime/pom.xml +++ b/firebase-admin/runtime/pom.xml @@ -45,10 +45,6 @@ quarkus-google-cloud-common-grpc and Quarkus includes the netty library --> io.quarkus quarkus-security - - io.quarkiverse.googlecloudservices - quarkus-google-cloud-firebase-devservices - org.eclipse.microprofile.jwt microprofile-jwt-auth-api From 798a0dbb03bbd96434786ea3e2c6aaaaf04476b9 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Tue, 17 Dec 2024 11:21:01 +0100 Subject: [PATCH 084/101] Fixed extension definition --- .../src/main/resources/META-INF/quarkus-extension.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firebase-devservices/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/firebase-devservices/runtime/src/main/resources/META-INF/quarkus-extension.yaml index 237fa448..c04a5b47 100644 --- a/firebase-devservices/runtime/src/main/resources/META-INF/quarkus-extension.yaml +++ b/firebase-devservices/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -10,7 +10,7 @@ metadata: categories: - "cloud" - "data" - guide: "https://quarkiverse.github.io/quarkiverse-docs/quarkus-google-cloud-services/main/firebase-admin.html" + guide: "https://quarkiverse.github.io/quarkiverse-docs/quarkus-google-cloud-services/main/firebase-devservices.html" status: "experimental" config: - - "quarkus.google.cloud.firebase." + - "quarkus.google.cloud.devservices." From 874996e3853164709e634094056c333cbe58af00 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Tue, 17 Dec 2024 11:34:38 +0100 Subject: [PATCH 085/101] Update docs with getting started info --- .../ROOT/pages/firebase-devservices.adoc | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/docs/modules/ROOT/pages/firebase-devservices.adoc b/docs/modules/ROOT/pages/firebase-devservices.adoc index 40464819..ac4132bb 100644 --- a/docs/modules/ROOT/pages/firebase-devservices.adoc +++ b/docs/modules/ROOT/pages/firebase-devservices.adoc @@ -56,6 +56,47 @@ This will add the following to your pom.xml: ---- +If you already have a firebase project (which you can create using the firebase tools by running `firebase init`), you need to make the following changes to get going: +* Add `"host" : "0.0.0.0"` to all emulator entries +* Add the hub, logging and UI emulators to the emulators configuration + +[source,json] +---- +{ + + "emulators" : { + "ui": { + "port": 4000, + "enabled": true, + "host": "0.0.0.0" + }, + "hub": { + "port": 4400, + "host": "0.0.0.0" + }, + "logging": { + "port": 4500, + "host": "0.0.0.0" + } + } +} +---- + * If you use Firestore, also set the Firestore Websocket port +[source,json] +---- +{ + "emulators" : { + "firestore": { + "port": 8080, + "websocketPort" : 9150, + "host": "0.0.0.0" + } + } +} +---- + * For both entries, you can of course use your own custom ports, where needed. + + == Custom Docker image To run the emulators, a custom Docker image is build on the fly to run the Firebase emulators. This image is based on a NodeJS based image (refer to the configuration of the default value of `quarkus.google.cloud.firebase.devservice.image-name` to see the base image). @@ -64,7 +105,7 @@ You can configure a custom image if needed as base image to run the Firebase Emu * The image must support NodeJS in a version compatible with the required Firebase Tools * The image must be `alpine` based (or at least able to install the following packages using `apk`: ) -** openjdk11-jre +** openjdk17-jre ** bash ** curl ** openssl @@ -75,7 +116,7 @@ You can configure a custom image if needed as base image to run the Firebase Emu == Custom Firebase JSON -By default a `firebase.json` file is generated inside the image to configure the various emulators. You can configure the Dev Services to use your own custom firebase.json file (e.g generated using the Firebase tools CLI). The following requirements are defined for this file: +If emulators are configured via the configuration options, a `firebase.json` file is generated inside the image to configure the various emulators. You can configure the Dev Services to use your own custom firebase.json file (e.g generated using the Firebase tools CLI). The following requirements are defined for this file: * Each of the emulators must be exposed on `0.0.0.0` as host as described https://firebase.google.com/docs/emulator-suite/use_hosting#emulators-no-local-host[here]. If this is not done, the Emulators will not be reachable from the Docker host. * Emulators need to be configured to use the default ports. Customizing the ports on which they run is currently not supported (this might change in a future version). @@ -92,4 +133,5 @@ When including this module, these Dev Services will automatically be disabled, == Configuration Reference -include::./includes/quarkus-google-cloud-firebase-devservices.adoc[] \ No newline at end of file +include::./includes/quarkus-google-cloud-firebase-devservices.adoc[] +---- \ No newline at end of file From 9228063f1659874407e382779e0927e15a00f72c Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Tue, 17 Dec 2024 11:54:35 +0100 Subject: [PATCH 086/101] If no emulators are defined via configuration, make sure to fallback to auto-configuration via the custom firebase.json file. --- .../FirebaseEmulatorConfigBuilder.java | 16 +++++++++++++++- integration-tests/firebase-admin/firebase.json | 15 +++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java index 6150b15e..e3ed09aa 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseEmulatorConfigBuilder.java @@ -99,9 +99,23 @@ private void configureCustomFirebaseJson(FirebaseEmulatorContainer.Builder build } private void configureEmulators(FirebaseEmulatorContainer.Builder builder) { - var firebaseConfigBuilder = builder.withFirebaseConfig(); var devServices = devServices(config); + var noEmulatorsConfigured = devServices + .entrySet() + .stream() + .filter(e -> e.getValue().enabled()) + // Emulator Suite UI is enabled by default, so ignore it. + .filter(e -> !e.getKey().equals(FirebaseEmulatorContainer.Emulator.EMULATOR_SUITE_UI)) + .findAny() + .isEmpty(); + + // No emulators configured via configuration, we will fallback to the automatic detection of a firebase.json file. + if (noEmulatorsConfigured) { + return; + } + + var firebaseConfigBuilder = builder.withFirebaseConfig(); devServices .entrySet() .stream() diff --git a/integration-tests/firebase-admin/firebase.json b/integration-tests/firebase-admin/firebase.json index 2fb2a16b..94fd7894 100644 --- a/integration-tests/firebase-admin/firebase.json +++ b/integration-tests/firebase-admin/firebase.json @@ -1,10 +1,21 @@ { "emulators": { "auth": { - "port": 9099 + "port": 9099, + "host": "0.0.0.0" }, "ui": { - "enabled": true + "port": 4000, + "enabled": true, + "host": "0.0.0.0" + }, + "hub": { + "port": 4400, + "host": "0.0.0.0" + }, + "logging": { + "port": 4500, + "host": "0.0.0.0" }, "singleProjectMode": true } From 5e103155621f31b33ac772a371a2da5a8718c226 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Tue, 17 Dec 2024 11:54:52 +0100 Subject: [PATCH 087/101] Fix maven name of the devservices projects --- firebase-devservices/deployment/pom.xml | 2 +- firebase-devservices/pom.xml | 2 +- firebase-devservices/runtime/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/firebase-devservices/deployment/pom.xml b/firebase-devservices/deployment/pom.xml index e930eca7..33a3cfa8 100644 --- a/firebase-devservices/deployment/pom.xml +++ b/firebase-devservices/deployment/pom.xml @@ -9,7 +9,7 @@ 4.0.0 quarkus-google-cloud-firebase-devservices-deployment - Quarkus - Google Cloud Services - Firebase - Deployment + Quarkus - Google Cloud Services - Firebase Dev Services - Deployment diff --git a/firebase-devservices/pom.xml b/firebase-devservices/pom.xml index 457a28c1..0ad36293 100644 --- a/firebase-devservices/pom.xml +++ b/firebase-devservices/pom.xml @@ -9,7 +9,7 @@ 4.0.0 quarkus-google-cloud-firebase-devservices-parent - Quarkus - Google Cloud Services - Firebase + Quarkus - Google Cloud Services - Firebas Dev Services pom diff --git a/firebase-devservices/runtime/pom.xml b/firebase-devservices/runtime/pom.xml index ffa92065..c9e69e71 100644 --- a/firebase-devservices/runtime/pom.xml +++ b/firebase-devservices/runtime/pom.xml @@ -9,7 +9,7 @@ 4.0.0 quarkus-google-cloud-firebase-devservices - Quarkus - Google Cloud Services - Firebase - Runtime + Quarkus - Google Cloud Services - Firebase Dev Services - Runtime Use Google Cloud Firebase From 2a7415aec7ce4c6680fdad9014f74210ff6f9e8d Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Tue, 17 Dec 2024 11:55:18 +0100 Subject: [PATCH 088/101] Add firebase devservices as dependency --- integration-tests/firebase-admin/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/integration-tests/firebase-admin/pom.xml b/integration-tests/firebase-admin/pom.xml index 5609ae49..dac3740a 100644 --- a/integration-tests/firebase-admin/pom.xml +++ b/integration-tests/firebase-admin/pom.xml @@ -37,6 +37,10 @@ rest-assured test + + io.quarkiverse.googlecloudservices + quarkus-google-cloud-firebase-devservices + From f9f6adf1a61dec95094ae6383f45adf922748d1a Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Tue, 17 Dec 2024 11:55:45 +0100 Subject: [PATCH 089/101] Remove unneeded config option --- .../firebase-admin/src/main/resources/application.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/integration-tests/firebase-admin/src/main/resources/application.properties b/integration-tests/firebase-admin/src/main/resources/application.properties index 5432e1aa..046a02be 100644 --- a/integration-tests/firebase-admin/src/main/resources/application.properties +++ b/integration-tests/firebase-admin/src/main/resources/application.properties @@ -1,4 +1,3 @@ # Set the project ID with the demo- prefix to use an emulated service. # When the emulator is started with this project ID, non-emulated services access will fail. quarkus.google.cloud.project-id=demo-test-project-id -quarkus.google.cloud.devservices.firebase.auth.enabled=true From 249afe47f8ddcc24a3d634319363c0042dc9c13a Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Tue, 17 Dec 2024 12:58:53 +0100 Subject: [PATCH 090/101] Enable firebase auth --- .../firebase-admin/src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/integration-tests/firebase-admin/src/main/resources/application.properties b/integration-tests/firebase-admin/src/main/resources/application.properties index 046a02be..f9b81cc0 100644 --- a/integration-tests/firebase-admin/src/main/resources/application.properties +++ b/integration-tests/firebase-admin/src/main/resources/application.properties @@ -1,3 +1,4 @@ # Set the project ID with the demo- prefix to use an emulated service. # When the emulator is started with this project ID, non-emulated services access will fail. quarkus.google.cloud.project-id=demo-test-project-id +quarkus.google.cloud.firebase.auth.enabled=true \ No newline at end of file From 64d081c84fa2c45cf13f516883412704970663e4 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Tue, 17 Dec 2024 13:11:22 +0100 Subject: [PATCH 091/101] Fix doc (typo) --- docs/modules/ROOT/pages/firebase-devservices.adoc | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/modules/ROOT/pages/firebase-devservices.adoc b/docs/modules/ROOT/pages/firebase-devservices.adoc index ac4132bb..57352000 100644 --- a/docs/modules/ROOT/pages/firebase-devservices.adoc +++ b/docs/modules/ROOT/pages/firebase-devservices.adoc @@ -134,4 +134,3 @@ When including this module, these Dev Services will automatically be disabled, == Configuration Reference include::./includes/quarkus-google-cloud-firebase-devservices.adoc[] ----- \ No newline at end of file From 868e41e9a76fa513ec8876f3e472c58a873c2950 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Wed, 18 Dec 2024 00:11:01 +0100 Subject: [PATCH 092/101] Fix missing pubsub emulator parsing --- .../deployment/testcontainers/CustomFirebaseConfigReader.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java index c59a4a6b..e437fd80 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java @@ -88,6 +88,10 @@ private Map( FirebaseEmulatorContainer.Emulator.FIREBASE_HOSTING, em::getHosting, + h -> h::getPort), + new EmulatorMergeStrategy<>( + FirebaseEmulatorContainer.Emulator.PUB_SUB, + em::getPubsub, h -> h::getPort) }; From eeb5b9b11f6853354a27b43224bea570c808b307 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Wed, 18 Dec 2024 16:55:03 +0100 Subject: [PATCH 093/101] Improve reading of firebase.json file and added documentation --- docs/modules/ROOT/pages/firebase-devservices.adoc | 10 ++++++++++ .../testcontainers/FirebaseEmulatorContainer.java | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/modules/ROOT/pages/firebase-devservices.adoc b/docs/modules/ROOT/pages/firebase-devservices.adoc index 57352000..47fa12e3 100644 --- a/docs/modules/ROOT/pages/firebase-devservices.adoc +++ b/docs/modules/ROOT/pages/firebase-devservices.adoc @@ -96,6 +96,16 @@ If you already have a firebase project (which you can create using the firebase ---- * For both entries, you can of course use your own custom ports, where needed. +The extension will try to read the `firebase.json` file from the current working directory the +process was started in (it will not attempt to traverse the directory upwards to try to find the +file). In some cases you may need to specify this working directory. E.g. when using Gradle: + +[source,text] +---- +quarkusDev { + workingDirectory = rootProject.projectDir +} +---- == Custom Docker image diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java index 57651675..20d6f48c 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java @@ -413,7 +413,9 @@ public FirebaseConfigBuilder withFirebaseConfig() { public EmulatorConfig buildConfig() { if (firebaseConfig == null) { // Try to autoload the firebase.json configuration - var defaultFirebaseJson = new File("firebase.json").toPath(); + var defaultFirebaseJson = new File("firebase.json").getAbsoluteFile().toPath(); + + LOGGER.info("Trying to automatically read firebase config from {}", defaultFirebaseJson); try { readFromFirebaseJson(defaultFirebaseJson); From f353ec02dccfeac7f078988a31912697fc6f559a Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 20 Dec 2024 22:14:31 +0100 Subject: [PATCH 094/101] Run npm install for test dependencies for functions --- .github/workflows/build.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index becc40ff..3d7e6269 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,6 +24,16 @@ jobs: with: java-version: 17 + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + cache-dependency-path: src/test/functions/package-lock.json + + - uses: bahmutov/npm-install@v1 + with: + working-directory: src/test/functions + - name: Cache local Maven repository uses: actions/cache@v2 with: From bf90792a9331162b117b70bfc2225fedcc6a23ea Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 20 Dec 2024 22:29:30 +0100 Subject: [PATCH 095/101] Use specific project id --- .../firebase/deployment/FirebaseDevServiceProjectConfig.java | 2 +- .../firebase-admin/src/main/resources/application.properties | 3 ++- .../firebase/src/main/resources/application.properties | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProjectConfig.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProjectConfig.java index 83c58a0e..5ab503dd 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProjectConfig.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/FirebaseDevServiceProjectConfig.java @@ -9,7 +9,7 @@ * Temporary Config root to retrieve the project id for the Firebase Emulator Container. We will remove this interface * in the future in favour of using the common setup. */ -@ConfigMapping(prefix = "quarkus.google.cloud") +@ConfigMapping(prefix = "quarkus.google.cloud.devservices") @ConfigRoot public interface FirebaseDevServiceProjectConfig { diff --git a/integration-tests/firebase-admin/src/main/resources/application.properties b/integration-tests/firebase-admin/src/main/resources/application.properties index f9b81cc0..bac883f6 100644 --- a/integration-tests/firebase-admin/src/main/resources/application.properties +++ b/integration-tests/firebase-admin/src/main/resources/application.properties @@ -1,4 +1,5 @@ # Set the project ID with the demo- prefix to use an emulated service. # When the emulator is started with this project ID, non-emulated services access will fail. quarkus.google.cloud.project-id=demo-test-project-id -quarkus.google.cloud.firebase.auth.enabled=true \ No newline at end of file +quarkus.google.cloud.firebase.auth.enabled=true +quarkus.google.cloud.devservices.project-id=demo-test-project-id \ No newline at end of file diff --git a/integration-tests/firebase/src/main/resources/application.properties b/integration-tests/firebase/src/main/resources/application.properties index 3b498334..1e24c613 100644 --- a/integration-tests/firebase/src/main/resources/application.properties +++ b/integration-tests/firebase/src/main/resources/application.properties @@ -1,6 +1,7 @@ # Set the project ID with the demo- prefix to use an emulated service. # When the emulator is started with this project ID, non-emulated services access will fail. quarkus.google.cloud.project-id=demo-test-project-id +quarkus.google.cloud.devservices.project-id=demo-test-project-id quarkus.google.cloud.access-token-enabled=false quarkus.google.cloud.devservices.firebase.auth.enabled=true quarkus.google.cloud.devservices.firebase.firestore.enabled=true From 39608c812ccb1342ba98430c3c496cc679bf27f9 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 20 Dec 2024 22:29:46 +0100 Subject: [PATCH 096/101] Fix path to NPM package.json --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3d7e6269..241c398b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,11 +28,11 @@ jobs: with: node-version: 20 cache: 'npm' - cache-dependency-path: src/test/functions/package-lock.json + cache-dependency-path: firebase-devservices/deployment/src/test/functions/package-lock.json - uses: bahmutov/npm-install@v1 with: - working-directory: src/test/functions + working-directory: firebase-devservices/deployment/src/test/functions - name: Cache local Maven repository uses: actions/cache@v2 From 8be975cd5e09591084d38ce82ffc96178a7b69a2 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 20 Dec 2024 22:58:07 +0100 Subject: [PATCH 097/101] Move config files into the test directory --- .../CustomFirebaseConfigReader.java | 32 ++++++++-------- .../FirebaseEmulatorContainer.java | 37 ++++++++++++------- .../deployment/{ => src/test}/firebase.json | 4 +- .../{ => src/test}/firestore.indexes.json | 0 .../deployment/{ => src/test}/firestore.rules | 0 ...baseEmulatorContainerCustomConfigTest.java | 2 +- .../deployment/{ => src/test}/storage.rules | 0 7 files changed, 44 insertions(+), 31 deletions(-) rename firebase-devservices/deployment/{ => src/test}/firebase.json (90%) rename firebase-devservices/deployment/{ => src/test}/firestore.indexes.json (100%) rename firebase-devservices/deployment/{ => src/test}/firestore.rules (100%) rename firebase-devservices/deployment/{ => src/test}/storage.rules (100%) diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java index e437fd80..a7050bd9 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/CustomFirebaseConfigReader.java @@ -34,10 +34,10 @@ public FirebaseEmulatorContainer.FirebaseConfig readFromFirebase(Path customFire var root = readCustomFirebaseJson(customFirebaseJson); return new FirebaseEmulatorContainer.FirebaseConfig( - readHosting(root.getHosting()), - readStorage(root.getStorage()), - readFirestore(root.getFirestore()), - readFunctions(root.getFunctions()), + readHosting(root.getHosting(), customFirebaseJson), + readStorage(root.getStorage(), customFirebaseJson), + readFirestore(root.getFirestore(), customFirebaseJson), + readFunctions(root.getFunctions(), customFirebaseJson), readEmulators(root.getEmulators())); } @@ -125,17 +125,17 @@ private Map.Entry firestoreMap = (Map) firestore; var rulesFile = Optional .ofNullable(firestoreMap.get("rules")) - .map(this::resolvePath); + .map(f -> this.resolvePath(f, customFirebaseJson)); var indexesFile = Optional .ofNullable(firestoreMap.get("indexes")) - .map(this::resolvePath); + .map(f -> this.resolvePath(f, customFirebaseJson)); return new FirebaseEmulatorContainer.FirestoreConfig( rulesFile, @@ -145,14 +145,14 @@ private FirebaseEmulatorContainer.FirestoreConfig readFirestore(Object firestore } } - private FirebaseEmulatorContainer.HostingConfig readHosting(Object hosting) { + private FirebaseEmulatorContainer.HostingConfig readHosting(Object hosting, Path customFirebaseJson) { if (hosting instanceof Map) { @SuppressWarnings("unchecked") Map hostingMap = (Map) hosting; var publicDir = Optional .ofNullable(hostingMap.get("public")) - .map(this::resolvePath); + .map(f -> this.resolvePath(f, customFirebaseJson)); return new FirebaseEmulatorContainer.HostingConfig( publicDir); @@ -161,14 +161,14 @@ private FirebaseEmulatorContainer.HostingConfig readHosting(Object hosting) { } } - private FirebaseEmulatorContainer.StorageConfig readStorage(Object storage) { + private FirebaseEmulatorContainer.StorageConfig readStorage(Object storage, Path customFirebaseJson) { if (storage instanceof Map) { @SuppressWarnings("unchecked") Map storageMap = (Map) storage; var rulesFile = Optional .ofNullable(storageMap.get("rules")) - .map(this::resolvePath); + .map(f -> this.resolvePath(f, customFirebaseJson)); return new FirebaseEmulatorContainer.StorageConfig( rulesFile); @@ -177,7 +177,7 @@ private FirebaseEmulatorContainer.StorageConfig readStorage(Object storage) { } } - private FirebaseEmulatorContainer.FunctionsConfig readFunctions(Object functions) { + private FirebaseEmulatorContainer.FunctionsConfig readFunctions(Object functions, Path customFirebaseJson) { if (functions instanceof Map) { @SuppressWarnings("unchecked") Map functionsMap = (Map) functions; @@ -185,7 +185,7 @@ private FirebaseEmulatorContainer.FunctionsConfig readFunctions(Object functions var functionsPath = Optional .ofNullable(functionsMap.get("source")) .map(String.class::cast) - .map(this::resolvePath); + .map(f -> this.resolvePath(f, customFirebaseJson)); var ignores = Optional .ofNullable(functionsMap.get("ignores")) @@ -200,8 +200,10 @@ private FirebaseEmulatorContainer.FunctionsConfig readFunctions(Object functions } } - private Path resolvePath(String filename) { - return new File(filename).toPath(); + private Path resolvePath(String filename, Path customFirebaseJson) { + File firebaseJson = customFirebaseJson.toFile(); + File firebaseDir = firebaseJson.getParentFile(); + return new File(firebaseDir, filename).toPath(); } private FirebaseConfig readCustomFirebaseJson(Path customFirebaseJson) throws IOException { diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java index 20d6f48c..751daa68 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java @@ -940,23 +940,34 @@ public FirebaseEmulatorContainer(EmulatorConfig emulatorConfig) { static String containerHostingPath(EmulatorConfig emulatorConfig) { var hostingPath = emulatorConfig.firebaseConfig().hostingConfig().hostingContentDir(); + if (emulatorConfig.customFirebaseJson().isPresent()) { + var firebaseJsonDir = emulatorConfig.customFirebaseJson().get().getParent(); + hostingPath = hostingPath.map(path -> + path.subpath(firebaseJsonDir.getNameCount(), path.getNameCount()) + ); + } - return hostingPath - .map(Path::isAbsolute) - .map(absolute -> { - if (absolute) { - return FIREBASE_HOSTING_PATH; - } else { - return FIREBASE_ROOT + "/" + hostingPath.get(); - } - }).orElse(FIREBASE_HOSTING_PATH); + if (hostingPath.isPresent()) { + var path = hostingPath.get(); + if (path.isAbsolute()) { + return FIREBASE_HOSTING_PATH; + } else { + return FIREBASE_ROOT + "/" + hostingPath.get(); + } + } else { + return FIREBASE_HOSTING_PATH; + } } static String containerFunctionsPath(EmulatorConfig emulatorConfig) { - return FIREBASE_ROOT + "/" + emulatorConfig - .firebaseConfig() - .functionsConfig() - .functionsPath() + var functionsPath = emulatorConfig.firebaseConfig().functionsConfig().functionsPath(); + if (emulatorConfig.customFirebaseJson().isPresent()) { + var firebaseJsonDir = emulatorConfig.customFirebaseJson().get().getParent(); + functionsPath = functionsPath.map(path -> + path.subpath(firebaseJsonDir.getNameCount(), path.getNameCount()) + ); + } + return FIREBASE_ROOT + "/" + functionsPath .map(Path::toString) .orElse(FirebaseJsonBuilder.FIREBASE_FUNCTIONS_SUBPATH); } diff --git a/firebase-devservices/deployment/firebase.json b/firebase-devservices/deployment/src/test/firebase.json similarity index 90% rename from firebase-devservices/deployment/firebase.json rename to firebase-devservices/deployment/src/test/firebase.json index b57a1592..dc71457c 100644 --- a/firebase-devservices/deployment/firebase.json +++ b/firebase-devservices/deployment/src/test/firebase.json @@ -25,10 +25,10 @@ "singleProjectMode": true }, "hosting": { - "public": "src/test/hosting" + "public": "hosting" }, "functions": { - "source": "src/test/functions" + "source": "functions" }, "firestore": { "rules": "firestore.rules", diff --git a/firebase-devservices/deployment/firestore.indexes.json b/firebase-devservices/deployment/src/test/firestore.indexes.json similarity index 100% rename from firebase-devservices/deployment/firestore.indexes.json rename to firebase-devservices/deployment/src/test/firestore.indexes.json diff --git a/firebase-devservices/deployment/firestore.rules b/firebase-devservices/deployment/src/test/firestore.rules similarity index 100% rename from firebase-devservices/deployment/firestore.rules rename to firebase-devservices/deployment/src/test/firestore.rules diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java index 67b58877..bf19c23e 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java @@ -30,7 +30,7 @@ public class FirebaseEmulatorContainerCustomConfigTest { .withCliArguments() .withEmulatorData(tempEmulatorDataDir.toPath()) .done() - .readFromFirebaseJson(new File("firebase.json").toPath()) + .readFromFirebaseJson(new File("src/test/firebase.json").toPath()) .build(); } catch (IOException e) { diff --git a/firebase-devservices/deployment/storage.rules b/firebase-devservices/deployment/src/test/storage.rules similarity index 100% rename from firebase-devservices/deployment/storage.rules rename to firebase-devservices/deployment/src/test/storage.rules From 338451a8c93df85c097d2ad005e9ccdf653c0a3a Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 20 Dec 2024 23:10:14 +0100 Subject: [PATCH 098/101] Create temporary files in target (build) directory --- .../FirebaseEmulatorContainerCustomConfigTest.java | 3 ++- .../FirebaseEmulatorContainerIntegrationTest.java | 12 ++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java index bf19c23e..ca80b9f3 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java @@ -24,7 +24,8 @@ public class FirebaseEmulatorContainerCustomConfigTest { static { try { // Create a temporary directory for emulator data - tempEmulatorDataDir = Files.createTempDirectory("firebase-emulator-data").toFile(); + tempEmulatorDataDir = new File("target/firebase-emulator-container-data"); + tempEmulatorDataDir.mkdirs(); var testContainer = new TestableFirebaseEmulatorContainer("FirebaseEmulatorContainerCustomConfigTest"); firebaseContainer = testContainer.testBuilder() .withCliArguments() diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java index 2db357fb..85e9e30b 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java @@ -51,14 +51,19 @@ @Testcontainers public class FirebaseEmulatorContainerIntegrationTest { + private static final File tempDataParent; private static final File tempEmulatorDataDir; private static final File tempHostingContentDir; static { try { + tempDataParent = new File("target/firebase-emulator-it"); + // Create a temporary directory for emulator data - tempEmulatorDataDir = Files.createTempDirectory("firebase-emulator-data").toFile(); - tempHostingContentDir = Files.createTempDirectory("firebase-hosting-content").toFile(); + tempEmulatorDataDir = new File(tempDataParent, "firebase-emulator-data"); + tempEmulatorDataDir.mkdirs(); + tempHostingContentDir = new File(tempDataParent, "firebase-hosting-content"); + tempHostingContentDir.mkdirs(); // Create a static HTML file in the hosting directory File indexFile = new File(tempHostingContentDir, "index.html"); @@ -117,8 +122,7 @@ public static void tearDown() { validateEmulatorDataWritten(); // Recursively delete the contents of the directories and then delete the directories - deleteDirectoryRecursively(tempEmulatorDataDir); - deleteDirectoryRecursively(tempHostingContentDir); + deleteDirectoryRecursively(tempDataParent); } // Helper method to recursively delete all files and directories From 9c855f6f06bed61ceacfa7a5600308daa7bbec1f Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 20 Dec 2024 23:12:14 +0100 Subject: [PATCH 099/101] Move schema to META-INF --- firebase-devservices/deployment/pom.xml | 2 +- .../main/{ => resources/META-INF}/schema/firebase-config.json | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename firebase-devservices/deployment/src/main/{ => resources/META-INF}/schema/firebase-config.json (100%) diff --git a/firebase-devservices/deployment/pom.xml b/firebase-devservices/deployment/pom.xml index 33a3cfa8..f8f5b649 100644 --- a/firebase-devservices/deployment/pom.xml +++ b/firebase-devservices/deployment/pom.xml @@ -138,7 +138,7 @@ quarkus-google-cloud-common-grpc and Quarkus includes the netty library --> jsonschema2pojo-maven-plugin 1.2.2 - ${basedir}/src/main/schema + ${basedir}/src/main/resources/META-INF/schema io.quarkiverse.googlecloudservices.firebase.deployment.testcontainers.json jackson2 true diff --git a/firebase-devservices/deployment/src/main/schema/firebase-config.json b/firebase-devservices/deployment/src/main/resources/META-INF/schema/firebase-config.json similarity index 100% rename from firebase-devservices/deployment/src/main/schema/firebase-config.json rename to firebase-devservices/deployment/src/main/resources/META-INF/schema/firebase-config.json From 921ff6654733b5fcb336678480302b345dc2320c Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 20 Dec 2024 23:12:40 +0100 Subject: [PATCH 100/101] Fix formatting --- .../testcontainers/FirebaseEmulatorContainer.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java index 751daa68..31c96003 100644 --- a/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java +++ b/firebase-devservices/deployment/src/main/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainer.java @@ -942,9 +942,7 @@ static String containerHostingPath(EmulatorConfig emulatorConfig) { var hostingPath = emulatorConfig.firebaseConfig().hostingConfig().hostingContentDir(); if (emulatorConfig.customFirebaseJson().isPresent()) { var firebaseJsonDir = emulatorConfig.customFirebaseJson().get().getParent(); - hostingPath = hostingPath.map(path -> - path.subpath(firebaseJsonDir.getNameCount(), path.getNameCount()) - ); + hostingPath = hostingPath.map(path -> path.subpath(firebaseJsonDir.getNameCount(), path.getNameCount())); } if (hostingPath.isPresent()) { @@ -963,9 +961,7 @@ static String containerFunctionsPath(EmulatorConfig emulatorConfig) { var functionsPath = emulatorConfig.firebaseConfig().functionsConfig().functionsPath(); if (emulatorConfig.customFirebaseJson().isPresent()) { var firebaseJsonDir = emulatorConfig.customFirebaseJson().get().getParent(); - functionsPath = functionsPath.map(path -> - path.subpath(firebaseJsonDir.getNameCount(), path.getNameCount()) - ); + functionsPath = functionsPath.map(path -> path.subpath(firebaseJsonDir.getNameCount(), path.getNameCount())); } return FIREBASE_ROOT + "/" + functionsPath .map(Path::toString) From bc2c5a0b7d6295f950358e2d0b2b2d3e740bb627 Mon Sep 17 00:00:00 2001 From: Jeroen Benckhuijsen Date: Fri, 20 Dec 2024 23:17:49 +0100 Subject: [PATCH 101/101] Fix formatting --- .../FirebaseEmulatorContainerCustomConfigTest.java | 1 - .../testcontainers/FirebaseEmulatorContainerIntegrationTest.java | 1 - 2 files changed, 2 deletions(-) diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java index ca80b9f3..77312a87 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerCustomConfigTest.java @@ -10,7 +10,6 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -import java.nio.file.Files; import org.junit.jupiter.api.Test; import org.testcontainers.junit.jupiter.Container; diff --git a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java index 85e9e30b..122cbba3 100644 --- a/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java +++ b/firebase-devservices/deployment/src/test/java/io/quarkiverse/googlecloudservices/firebase/deployment/testcontainers/FirebaseEmulatorContainerIntegrationTest.java @@ -14,7 +14,6 @@ import java.nio.channels.Channels; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException;