From 1fb27fcf8eb809a353781027ec63034606626e90 Mon Sep 17 00:00:00 2001 From: Lai Jiang Date: Mon, 11 Mar 2024 12:05:44 -0400 Subject: [PATCH] Make nomulus work locally (#2349) Chose the default transaction manager based on RegistryEnvironment. This makes it possible to run nomulus on Jetty locally. Tested with the following: ```bash ./gradle :jetty:run -Penvironment=alpha curl http://localhost:8080/beta.app ``` The docker image is also updated to take an argument that specifies the environment. It runs locally as well but the container doesn't get access to locally stored credentials, so it fails to initialize the transaction manager. --- .../persistence/PersistenceComponent.java | 6 +++--- .../persistence/PersistenceModule.java | 8 +++---- .../TransactionManagerFactory.java | 21 +++---------------- jetty/Dockerfile | 6 ++---- jetty/build.gradle | 19 ++++++++++++++++- jetty/src/main/jetty-base/webapps/nomulus.xml | 7 +++++++ jetty/start.sh | 18 ++++++++++++++++ 7 files changed, 55 insertions(+), 30 deletions(-) create mode 100644 jetty/src/main/jetty-base/webapps/nomulus.xml create mode 100755 jetty/start.sh diff --git a/core/src/main/java/google/registry/persistence/PersistenceComponent.java b/core/src/main/java/google/registry/persistence/PersistenceComponent.java index 8c3a9a7b1..00e51faa6 100644 --- a/core/src/main/java/google/registry/persistence/PersistenceComponent.java +++ b/core/src/main/java/google/registry/persistence/PersistenceComponent.java @@ -18,7 +18,7 @@ import dagger.Component; import google.registry.config.CredentialModule; import google.registry.config.RegistryConfig.ConfigModule; import google.registry.keyring.secretmanager.SecretManagerKeyringModule; -import google.registry.persistence.PersistenceModule.AppEngineJpaTm; +import google.registry.persistence.PersistenceModule.DefaultJpaTm; import google.registry.persistence.PersistenceModule.ReadOnlyReplicaJpaTm; import google.registry.persistence.transaction.JpaTransactionManager; import google.registry.privileges.secretmanager.SecretManagerModule; @@ -39,8 +39,8 @@ import javax.persistence.EntityManagerFactory; }) public interface PersistenceComponent { - @AppEngineJpaTm - JpaTransactionManager appEngineJpaTransactionManager(); + @DefaultJpaTm + JpaTransactionManager jpaTransactionManager(); @ReadOnlyReplicaJpaTm JpaTransactionManager readOnlyReplicaJpaTransactionManager(); diff --git a/core/src/main/java/google/registry/persistence/PersistenceModule.java b/core/src/main/java/google/registry/persistence/PersistenceModule.java index 9b55dd45f..3471954c5 100644 --- a/core/src/main/java/google/registry/persistence/PersistenceModule.java +++ b/core/src/main/java/google/registry/persistence/PersistenceModule.java @@ -220,8 +220,8 @@ public abstract class PersistenceModule { @Provides @Singleton - @AppEngineJpaTm - static JpaTransactionManager provideAppEngineJpaTm( + @DefaultJpaTm + static JpaTransactionManager provideDefaultJpaTm( SqlCredentialStore credentialStore, @PartialCloudSqlConfigs ImmutableMap cloudSqlConfigs, Clock clock) { @@ -380,10 +380,10 @@ public abstract class PersistenceModule { @Documented public @interface SchemaManagerConnection {} - /** Dagger qualifier for {@link JpaTransactionManager} used for App Engine application. */ + /** Dagger qualifier for {@link JpaTransactionManager} used by default. */ @Qualifier @Documented - @interface AppEngineJpaTm {} + @interface DefaultJpaTm {} /** Dagger qualifier for {@link JpaTransactionManager} used inside BEAM pipelines. */ @Qualifier diff --git a/core/src/main/java/google/registry/persistence/transaction/TransactionManagerFactory.java b/core/src/main/java/google/registry/persistence/transaction/TransactionManagerFactory.java index 1da28427f..a81727bc1 100644 --- a/core/src/main/java/google/registry/persistence/transaction/TransactionManagerFactory.java +++ b/core/src/main/java/google/registry/persistence/transaction/TransactionManagerFactory.java @@ -17,8 +17,6 @@ package google.registry.persistence.transaction; import static com.google.common.base.Preconditions.checkState; import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; -import com.google.appengine.api.utils.SystemProperty; -import com.google.appengine.api.utils.SystemProperty.Environment.Value; import com.google.common.base.Suppliers; import google.registry.persistence.DaggerPersistenceComponent; import google.registry.tools.RegistryToolEnvironment; @@ -43,34 +41,21 @@ public final class TransactionManagerFactory { private static JpaTransactionManager createJpaTransactionManager() { // If we are running a nomulus command, jpaTm will be injected in RegistryCli.java // by calling setJpaTm(). - if (isInAppEngine()) { - return DaggerPersistenceComponent.create().appEngineJpaTransactionManager(); + if (RegistryEnvironment.get() != RegistryEnvironment.UNITTEST) { + return DaggerPersistenceComponent.create().jpaTransactionManager(); } else { return DummyJpaTransactionManager.create(); } } private static JpaTransactionManager createReplicaJpaTransactionManager() { - if (isInAppEngine()) { + if (RegistryEnvironment.get() != RegistryEnvironment.UNITTEST) { return DaggerPersistenceComponent.create().readOnlyReplicaJpaTransactionManager(); } else { return DummyJpaTransactionManager.create(); } } - /** - * This function uses App Engine API to determine if the current runtime environment is App - * Engine. - * - * @see App - * Engine API public doc - */ - private static boolean isInAppEngine() { - // SystemProperty.environment.value() returns null if the current runtime is local JVM - return SystemProperty.environment.value() == Value.Production; - } - /** * Returns {@link JpaTransactionManager} instance. * diff --git a/jetty/Dockerfile b/jetty/Dockerfile index 366dfe1cc..8f7c307a5 100644 --- a/jetty/Dockerfile +++ b/jetty/Dockerfile @@ -1,7 +1,5 @@ FROM jetty:12-jdk21 ADD --chown=jetty:jetty build/jetty-base /jetty-base -ENV JETTY_BASE=/jetty-base -WORKDIR "$JETTY_BASE" +ADD --chown=jetty:jetty start.sh / EXPOSE 8080 -ENTRYPOINT ["java", "-jar", "/usr/local/jetty/start.jar"] - +ENTRYPOINT ["/bin/sh", "/start.sh"] diff --git a/jetty/build.gradle b/jetty/build.gradle index 3f95f79d8..4d57325a4 100644 --- a/jetty/build.gradle +++ b/jetty/build.gradle @@ -22,7 +22,7 @@ tasks.register('copyJettyBase', Copy) { } war { - setArchiveBaseName("root") + setArchiveBaseName("nomulus") setDestinationDirectory(layout.buildDirectory.dir('jetty-base/webapps')) dependsOn(tasks.named('copyJettyBase')) } @@ -49,4 +49,21 @@ tasks.register('buildNomulusImage', Exec) { dependsOn(tasks.named('stage')) } +tasks.register('run', JavaExec) { + // We do the check when the task actually runs, not when we define it. + // This way if one doesn't set the value, one can still run other tasks. + doFirst { + def jetty_home = System.getenv('JETTY_HOME') + if (jetty_home == null) { + throw new GradleException('JETTY_HOME is not set.') + } + } + def jetty_home = System.getenv('JETTY_HOME') + def environment = rootProject.environment + workingDir(layout.buildDirectory.dir('jetty-base')) + classpath = files(jetty_home + '/start.jar') + systemProperty('google.registry.environment', environment) + dependsOn(tasks.named('stage')) +} + project.build.dependsOn(tasks.named('buildNomulusImage')) diff --git a/jetty/src/main/jetty-base/webapps/nomulus.xml b/jetty/src/main/jetty-base/webapps/nomulus.xml new file mode 100644 index 000000000..aa521fc65 --- /dev/null +++ b/jetty/src/main/jetty-base/webapps/nomulus.xml @@ -0,0 +1,7 @@ + + + + + / + ./webapps/nomulus.war + diff --git a/jetty/start.sh b/jetty/start.sh new file mode 100755 index 000000000..09968a1ff --- /dev/null +++ b/jetty/start.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# Copyright 2024 The Nomulus Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +environment=$1 +cd /jetty-base +java -jar /usr/local/jetty/start.jar -Dgoogle.registry.environment=${environment:-"alpha"}