diff options
21 files changed, 684 insertions, 416 deletions
@@ -5,6 +5,10 @@ appengine-generated/ src/main/resources/keys/ src/main/resources/bug_tracking_system/**/*.tpl +# Gradle +.gradle/ +build/ + # Java *.class diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..784950e --- /dev/null +++ b/build.gradle @@ -0,0 +1,236 @@ +import org.apache.tools.ant.filters.ReplaceTokens +import com.google.cloud.tools.gradle.appengine.core.DeployTask + +buildscript { + ext { + springBootVersion = '1.5.13.RELEASE' + objectifyVersion = '6.0' + googleCloudVersion = '0.47.0-alpha' + googleJavaFormatVersion = '0.7-SNAPSHOT' + } + repositories { + jcenter() + mavenCentral() + maven { + url 'https://oss.sonatype.org/content/repositories/snapshots/' + } + } + dependencies { + classpath 'com.google.cloud.tools:appengine-gradle-plugin:+' // latest App Engine Gradle tasks + classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" + classpath "com.github.sherter.googlejavaformatgradleplugin:google-java-format-gradle-plugin:${googleJavaFormatVersion}" + } +} + +apply plugin: 'java' +apply plugin: 'war' // standard Web Archive plugin +apply plugin: 'com.google.cloud.tools.appengine' // App Engine tasks +apply plugin: 'com.github.sherter.google-java-format' +apply from: rootProject.file('gradle/profiles.gradle') + +group = 'com.android.vts' +version = '4' + +description = "" + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + + +repositories { + maven { + url 'https://oss.sonatype.org/content/repositories/snapshots' // SNAPSHOT repository (if needed) + } + mavenCentral() + jcenter() +} + +dependencies { + compile 'com.google.appengine:appengine-api-1.0-sdk:+' // Latest App Engine Api's + providedCompile 'javax.servlet:javax.servlet-api:3.1.0' + + compile 'jstl:jstl:1.2' + + compile group: 'commons-lang', name: 'commons-lang', version:'2.6' + compile group: 'org.apache.commons', name: 'commons-math3', version:'3.6.1' + compile group: 'commons-codec', name: 'commons-codec', version:'1.9' + compile group: 'com.google.cloud', name: 'google-cloud', version: "${googleCloudVersion}" + compile group: 'com.google.code.gson', name: 'gson', version:'2.7' + compile group: 'com.googlecode.objectify', name: 'objectify', version: "${objectifyVersion}" + compile group: 'org.json', name: 'json', version:'20180130' + compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version:'2.8.6' + compile(group: 'com.google.api-client', name: 'google-api-client', version:'1.23.0') { + exclude(module: 'guava-jdk5') + } + compile group: 'com.google.apis', name: 'google-api-services-oauth2', version:'v1-rev136-1.23.0' + + testCompile group: 'junit', name: 'junit', version:'4.12' + testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version:'5.0.3' + + testCompile 'com.google.appengine:appengine-testing:+' + testCompile 'com.google.appengine:appengine-api-stubs:+' + testCompile 'com.google.appengine:appengine-tools-sdk:+' + + providedCompile group: 'org.projectlombok', name: 'lombok', version: '1.16.20' +} + +// Always run unit tests +appengineDeploy.dependsOn test +appengineStage.dependsOn test + +googleJavaFormat { + toolVersion = '1.6' + options style: 'AOSP' + source = sourceSets*.allJava + include '**/*.java' + exclude '**/*Template.java' + exclude 'src/test/template_*' +} + +appengine { // App Engine tasks configuration + run { + environment = [ + GOOGLE_CLOUD_PROJECT: "android-vts-staging", + // DATASTORE_USE_PROJECT_ID_AS_APP_ID: "true", + ] + port = 8080 + jvmFlags = [ + "-Xdebug", + "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005", + "-Dappengine.fullscan.seconds=5" + ] + } + + deploy { // deploy configuration + + } +} + +test { + useJUnit() + testLogging.showStandardStreams = true + beforeTest { descriptor -> + logger.lifecycle("test: " + descriptor + " Running") + } + + onOutput { descriptor, event -> + logger.lifecycle("test: " + descriptor + ": " + event.message ) + } + afterTest { descriptor, result -> + logger.lifecycle("test: " + descriptor + ": " + result ) + } +} + + +tasks.addRule("Pattern: vtsGaeDeploy<ID>") { String taskName -> + if (taskName.startsWith("vtsGaeDeploy-")) { + + def projectId = taskName.replace("vtsGaeDeploy-", "") + appengine.deploy.project = projectId + project.ext.projectId = projectId + + def gcsConfigCopy = task("gcsConfigCopy${projectId}") { + doFirst { + println "============ resource folder processing ============" + + if (project.loadConfigFromGcs.toBoolean()) { + exec { + println "The resources folder will be copied from GCS!" + commandLine "gsutil", + "cp", + "-R", + "${project.gcsConfigPath}${project.mode}/dashboard/${projectId}/resources/*", + "$appengine.stage.stagingDirectory/WEB-INF/classes" + } + } else { + println "The local resource folder will be used!" + } + } + + doLast { + def propertyFilePath = "$appengine.stage.stagingDirectory/WEB-INF/classes/config.properties" + + def props = new Properties() + file(propertyFilePath).withInputStream { + props.load(it) + } + project.ext.props = props + } + } + + gcsConfigCopy.dependsOn appengineStage + + def appengineWebCopy = tasks.create(name: "appengineWebCopy${projectId}", type: Copy) { + from "$appengine.stage.sourceDirectory/WEB-INF/appengine-web.xml" + into("$appengine.stage.stagingDirectory/WEB-INF") + + doLast { + filter(ReplaceTokens, tokens: project.ext.props) + } + } + + appengineWebCopy.dependsOn gcsConfigCopy + + def vtsGaeDeployTask = task(taskName) { + + doFirst { + println "--------------> setting project id <-------------" + appengine.deploy.project = projectId + project.appengine.deploy.version = project.ext.props.getProperty("appengine.version") + } + + doLast { + appengineDeploy.execute() + def commandKeyList = [ + 'enableAppengineDeployCron': appengineDeployCron, + 'enableAppengineDeployDispatch': appengineDeployDispatch, + 'enableAppengineDeployDos': appengineDeployDos, + 'enableAppengineDeployIndex': appengineDeployIndex, + 'enableAppengineDeployQueue': appengineDeployQueue + ] + + commandKeyList.each { key, value -> + if (project.hasProperty(key) && project.getProperty(key).toBoolean()) { + println "execute command => ${key}" + value.execute() + } + } + } + } + + vtsGaeDeployTask.dependsOn appengineWebCopy + + def runAppengineTask = tasks.create(name: "runAppengineTask${projectId}", type: GradleBuild) { + + appengine.deploy.project = projectId + def taskList = ['appengineDeploy'] + def commandKeyList = [ + 'enableAppengineDeployCron': 'appengineDeployCron', + 'enableAppengineDeployDispatch': 'appengineDeployDispatch', + 'enableAppengineDeployDos': 'appengineDeployDos', + 'enableAppengineDeployIndex': 'appengineDeployIndex', + 'enableAppengineDeployQueue': 'appengineDeployQueue' + ] + + commandKeyList.each { key, value -> + if (project.hasProperty(key) && project.getProperty(key).toBoolean()) { + println "execute command => ${key}" + taskList.push(value) + } + } + tasks = taskList + } + + } +} + +task vtsGaeMultiDeploy { + dependsOn { + def taskList = [] + def projectIdList = project.property("projectIdList") + projectIdList.split(",").each { projectId -> + taskList.push(tasks.findByName("vtsGaeDeploy-${projectId.trim()}".toString())) + } + return taskList + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..95e8f7c --- /dev/null +++ b/gradle.properties @@ -0,0 +1,13 @@ + +loadConfigFromGcs=true + +mode= +gcsConfigPath= + +projectIdList= + +enableAppengineDeployCron = true +enableAppengineDeployDispatch = false +enableAppengineDeployDos = false +enableAppengineDeployIndex = true +enableAppengineDeployQueue = true diff --git a/gradle/profile_default.gradle b/gradle/profile_default.gradle new file mode 100644 index 0000000..e77dd58 --- /dev/null +++ b/gradle/profile_default.gradle @@ -0,0 +1,7 @@ +import org.apache.tools.ant.filters.ReplaceTokens + +processResources { + filter ReplaceTokens, tokens: [ + "application.version": project.property("version") + ] +} diff --git a/gradle/profile_prod.gradle b/gradle/profile_prod.gradle new file mode 100644 index 0000000..b111dcc --- /dev/null +++ b/gradle/profile_prod.gradle @@ -0,0 +1,7 @@ +import org.apache.tools.ant.filters.ReplaceTokens + +processResources { + filter ReplaceTokens, tokens: [ + "application.version": project.property("application.version") + ] +} diff --git a/gradle/profile_staging.gradle b/gradle/profile_staging.gradle new file mode 100644 index 0000000..b111dcc --- /dev/null +++ b/gradle/profile_staging.gradle @@ -0,0 +1,7 @@ +import org.apache.tools.ant.filters.ReplaceTokens + +processResources { + filter ReplaceTokens, tokens: [ + "application.version": project.property("application.version") + ] +} diff --git a/gradle/profiles.gradle b/gradle/profiles.gradle new file mode 100644 index 0000000..74855b6 --- /dev/null +++ b/gradle/profiles.gradle @@ -0,0 +1,29 @@ +// ---- +// How to use Profiles with -P arguments +// ---- +// +// Run gradle tasks with the -P argument to utilize a profile. +// + +def prodProfiles = 'prod' +def stagingProfiles = 'staging' +def defaultProfiles = 'default' +def propertyDrivenProfiles + +if (project.hasProperty('prod')) { + // Used for production environment + propertyDrivenProfiles = prodProfiles + apply from: rootProject.file('gradle/profile_prod.gradle'); + +} else if (project.hasProperty('staging')) { + // Used for local development + propertyDrivenProfiles = stagingProfiles + apply from: rootProject.file('gradle/profile_staging.gradle'); + +} else { + // Default when no profile property is specified, used for testing + propertyDrivenProfiles = defaultProfiles + apply from: rootProject.file('gradle/profile_default.gradle'); +} +println 'Using profile: "' + propertyDrivenProfiles + '" for ' + project.getName() + diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 2c2dfe4..0000000 --- a/pom.xml +++ /dev/null @@ -1,233 +0,0 @@ -<!-- - Copyright 2016 Google Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <packaging>war</packaging> - <version>1.0-SNAPSHOT</version> - <groupId>com.android.vts</groupId> - <artifactId>vts-dashboard</artifactId> - - <properties> - <app.id>android-vts-staging</app.id> - <app.version>4</app.version> - <appengine.version>1.9.63</appengine.version> - - <appengine.clientID></appengine.clientID> - <appengine.serviceClientID></appengine.serviceClientID> - <appengine.senderEmail></appengine.senderEmail> - <appengine.emailDomain></appengine.emailDomain> - <appengine.defaultEmail></appengine.defaultEmail> - <gerrit.uri></gerrit.uri> - <gerrit.scope></gerrit.scope> - <analytics.id></analytics.id> - - <gcs.projectID></gcs.projectID> - <gcs.keyFile></gcs.keyFile> - <gcs.bucketName></gcs.bucketName> - <gcs.suiteTestFolderName></gcs.suiteTestFolderName> - - <maven.compiler.target>1.8</maven.compiler.target> - <maven.compiler.source>1.8</maven.compiler.source> - <maven.war.filteringDeploymentDescriptors>true</maven.war.filteringDeploymentDescriptors> - - <failOnMissingWebXml>false</failOnMissingWebXml> - - <junit.version>4.12</junit.version> - <junit.jupiter.version>5.0.3</junit.jupiter.version> - </properties> - - - <dependencies> - - <dependency> - <groupId>javax.servlet</groupId> - <artifactId>javax.servlet-api</artifactId> - <version>3.0.1</version> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>commons-lang</groupId> - <artifactId>commons-lang</artifactId> - <version>2.6</version> - </dependency> - - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-math3</artifactId> - <version>3.6.1</version> - </dependency> - - <dependency> - <groupId>commons-codec</groupId> - <artifactId>commons-codec</artifactId> - <version>1.9</version> - </dependency> - - <dependency> - <groupId>com.google.cloud</groupId> - <artifactId>google-cloud</artifactId> - <version>0.39.0-alpha</version> - </dependency> - - <dependency> - <groupId>com.google.code.gson</groupId> - <artifactId>gson</artifactId> - <version>2.7</version> - </dependency> - - <dependency> - <groupId>com.googlecode.objectify</groupId> - <artifactId>objectify</artifactId> - <version>6.0</version> - </dependency> - - <dependency> - <groupId>org.json</groupId> - <artifactId>json</artifactId> - <version>20180130</version> - </dependency> - - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - <version>2.8.6</version> - </dependency> - - <dependency> - <groupId>com.google.api-client</groupId> - <artifactId>google-api-client</artifactId> - <version>1.23.0</version> - <exclusions> - <exclusion> - <groupId>com.google.guava</groupId> - <artifactId>guava-jdk5</artifactId> - </exclusion> - </exclusions> - </dependency> - - <dependency> - <groupId>com.google.appengine</groupId> - <artifactId>appengine-api-1.0-sdk</artifactId> - <version>${appengine.version}</version> - </dependency> - - <dependency> - <groupId>com.google.apis</groupId> - <artifactId>google-api-services-oauth2</artifactId> - <version>v1-rev136-1.23.0</version> - </dependency> - - <dependency> - <groupId>org.projectlombok</groupId> - <artifactId>lombok</artifactId> - <version>1.16.20</version> - <scope>provided</scope> - </dependency> - - <!-- Test Dependencies --> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>${junit.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.junit.jupiter</groupId> - <artifactId>junit-jupiter-api</artifactId> - <version>${junit.jupiter.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>com.google.appengine</groupId> - <artifactId>appengine-testing</artifactId> - <version>${appengine.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>com.google.appengine</groupId> - <artifactId>appengine-api-stubs</artifactId> - <version>${appengine.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>com.google.appengine</groupId> - <artifactId>appengine-tools-sdk</artifactId> - <version>${appengine.version}</version> - <scope>test</scope> - </dependency> - - </dependencies> - - - <build> - <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory> - - <resources> - <resource> - <directory>src/main/resources</directory> - <includes> - <include>**/*.properties</include> - <include>**/*.json</include> - <include>**/*.tpl</include> - </includes> - </resource> - </resources> - - <plugins> - - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-war-plugin</artifactId> - <version>2.6</version> - <configuration> - <archiveClasses>true</archiveClasses> - <failOnMissingWebXml>false</failOnMissingWebXml> - <webResources> - <resource> - <directory>${basedir}/src/main/webapp/WEB-INF</directory> - <filtering>true</filtering> - <targetPath>WEB-INF</targetPath> - </resource> - </webResources> - </configuration> - </plugin> - - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <version>3.3</version> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <source>1.8</source> - <target>1.8</target> - </configuration> - </plugin> - - <plugin> - <groupId>com.google.appengine</groupId> - <artifactId>appengine-maven-plugin</artifactId> - <version>${appengine.version}</version> - <configuration> - <appId>${app.id}</appId> - <version>${app.version}</version> - </configuration> - </plugin> - - </plugins> - </build> -</project> diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..90a0c19 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,6 @@ +rootProject.name = 'vts-dashboard' + +ext { + deployTarget = "test" + loggingProperty = "WEB-INF/logging.properties" +}
\ No newline at end of file diff --git a/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java b/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java index d2b4a61..ac69b84 100644 --- a/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java +++ b/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java @@ -17,6 +17,7 @@ package com.android.vts.api; import com.android.vts.proto.VtsReportMessage.TestReportMessage; +import com.android.vts.servlet.BaseServlet; import com.android.vts.util.DatastoreHelper; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.javanet.NetHttpTransport; @@ -25,9 +26,14 @@ import com.google.api.services.oauth2.Oauth2; import com.google.api.services.oauth2.model.Tokeninfo; import com.google.protobuf.InvalidProtocolBufferException; import java.io.BufferedReader; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -38,11 +44,33 @@ import org.json.JSONObject; /** REST endpoint for posting data JSON to the Dashboard. */ @Deprecated public class BigtableLegacyJsonServlet extends HttpServlet { - private static final String SERVICE_CLIENT_ID = System.getProperty("SERVICE_CLIENT_ID"); + private static String SERVICE_CLIENT_ID; private static final String SERVICE_NAME = "VTS Dashboard"; private static final Logger logger = Logger.getLogger(BigtableLegacyJsonServlet.class.getName()); + /** System Configuration Property class */ + protected Properties systemConfigProp = new Properties(); + + @Override + public void init(ServletConfig cfg) throws ServletException { + super.init(cfg); + + try { + InputStream defaultInputStream = + BigtableLegacyJsonServlet.class + .getClassLoader() + .getResourceAsStream("config.properties"); + systemConfigProp.load(defaultInputStream); + + SERVICE_CLIENT_ID = systemConfigProp.getProperty("appengine.serviceClientID"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { @@ -93,7 +121,8 @@ public class BigtableLegacyJsonServlet extends HttpServlet { insertData(payloadJson); break; default: - logger.log(Level.WARNING, + logger.log( + Level.WARNING, "Invalid Datastore REST verb: " + payloadJson.getString("verb")); throw new IOException("Unsupported POST verb."); } @@ -110,8 +139,7 @@ public class BigtableLegacyJsonServlet extends HttpServlet { * * @param payloadJson The JSON object representing the row to be inserted. Of the form: { * (deprecated) 'tableName' : 'table', (deprecated) 'rowKey' : 'row', (deprecated) 'family' - * : - * 'family', (deprecated) 'qualifier' : 'qualifier', 'value' : 'value' } + * : 'family', (deprecated) 'qualifier' : 'qualifier', 'value' : 'value' } * @throws IOException */ private void insertData(JSONObject payloadJson) throws IOException { diff --git a/src/main/java/com/android/vts/api/DatastoreRestServlet.java b/src/main/java/com/android/vts/api/DatastoreRestServlet.java index 8910267..42d7a60 100644 --- a/src/main/java/com/android/vts/api/DatastoreRestServlet.java +++ b/src/main/java/com/android/vts/api/DatastoreRestServlet.java @@ -19,16 +19,24 @@ package com.android.vts.api; import com.android.vts.proto.VtsReportMessage.DashboardPostMessage; import com.android.vts.proto.VtsReportMessage.TestPlanReportMessage; import com.android.vts.proto.VtsReportMessage.TestReportMessage; +import com.android.vts.servlet.BaseServlet; import com.android.vts.util.DatastoreHelper; +import com.android.vts.util.EmailHelper; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.jackson.JacksonFactory; import com.google.api.services.oauth2.Oauth2; import com.google.api.services.oauth2.model.Tokeninfo; + +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -36,10 +44,32 @@ import org.apache.commons.codec.binary.Base64; /** REST endpoint for posting data to the Dashboard. */ public class DatastoreRestServlet extends HttpServlet { - private static final String SERVICE_CLIENT_ID = System.getProperty("SERVICE_CLIENT_ID"); + private static String SERVICE_CLIENT_ID; private static final String SERVICE_NAME = "VTS Dashboard"; private static final Logger logger = Logger.getLogger(DatastoreRestServlet.class.getName()); + /** System Configuration Property class */ + protected Properties systemConfigProp = new Properties(); + + @Override + public void init(ServletConfig cfg) throws ServletException { + super.init(cfg); + + try { + InputStream defaultInputStream = + DatastoreRestServlet.class + .getClassLoader() + .getResourceAsStream("config.properties"); + systemConfigProp.load(defaultInputStream); + + SERVICE_CLIENT_ID = systemConfigProp.getProperty("appengine.serviceClientID"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { @@ -70,7 +100,8 @@ public class DatastoreRestServlet extends HttpServlet { DatastoreHelper.insertTestReport(testReportMessage); } - for (TestPlanReportMessage planReportMessage : postMessage.getTestPlanReportList()) { + for (TestPlanReportMessage planReportMessage : + postMessage.getTestPlanReportList()) { DatastoreHelper.insertTestPlanReport(planReportMessage); } diff --git a/src/main/java/com/android/vts/api/TestDataForDevServlet.java b/src/main/java/com/android/vts/api/TestDataForDevServlet.java index e6a4413..75432c7 100644 --- a/src/main/java/com/android/vts/api/TestDataForDevServlet.java +++ b/src/main/java/com/android/vts/api/TestDataForDevServlet.java @@ -32,6 +32,8 @@ import com.android.vts.entity.TestStatusEntity; import com.android.vts.entity.TestRunEntity.TestRunType; import com.android.vts.entity.TestStatusEntity.TestCaseReference; +import com.android.vts.servlet.BaseServlet; +import com.android.vts.util.EmailHelper; import com.google.appengine.api.datastore.DatastoreFailureException; import com.google.appengine.api.datastore.DatastoreService; import com.google.appengine.api.datastore.DatastoreServiceFactory; @@ -48,7 +50,10 @@ import com.google.appengine.api.users.UserServiceFactory; import com.google.appengine.api.utils.SystemProperty; import com.google.gson.Gson; import com.google.gson.GsonBuilder; + +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.nio.file.FileSystems; @@ -63,11 +68,13 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Random; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.IntStream; +import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -78,8 +85,7 @@ public class TestDataForDevServlet extends HttpServlet { protected static final Logger logger = Logger.getLogger(TestDataForDevServlet.class.getName()); /** Google Cloud Storage project's default directory name for suite test result files */ - private static final String GCS_SUITE_TEST_FOLDER_NAME = - System.getProperty("GCS_SUITE_TEST_FOLDER_NAME"); + private static String GCS_SUITE_TEST_FOLDER_NAME; /** datastore instance to save the test data into datastore through datastore library. */ private DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); @@ -89,6 +95,28 @@ public class TestDataForDevServlet extends HttpServlet { */ private Gson gson = new GsonBuilder().create(); + /** System Configuration Property class */ + protected Properties systemConfigProp = new Properties(); + + @Override + public void init(ServletConfig cfg) throws ServletException { + super.init(cfg); + + try { + InputStream defaultInputStream = + TestDataForDevServlet.class + .getClassLoader() + .getResourceAsStream("config.properties"); + systemConfigProp.load(defaultInputStream); + + GCS_SUITE_TEST_FOLDER_NAME = systemConfigProp.getProperty("gcs.suiteTestFolderName"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + /** * TestReportData class for mapping test-report-data.json. This internal class's each fields * will be automatically mapped to test-report-data.json file through Gson @@ -205,93 +233,117 @@ public class TestDataForDevServlet extends HttpServlet { "aosp_arm_a-userdebug"); branchList.forEach( branch -> - targetList.forEach( - target -> - IntStream.range(0, 10) - .forEach( - idx -> { - String year = String.format("%04d", 2010 + idx); - String month = - String.format("%02d", rand.nextInt(12)); - String day = - String.format("%02d", rand.nextInt(30)); - String fileName = - String.format( - "%02d%02d%02d.bin", - rand.nextInt(23) + 1, - rand.nextInt(59) + 1, - rand.nextInt(59) + 1); - - List<String> pathList = - Arrays.asList( - GCS_SUITE_TEST_FOLDER_NAME == "" - ? "suite_result" - : GCS_SUITE_TEST_FOLDER_NAME, - year, - month, - day, - fileName); - - Path pathInfo = - Paths.get( - String.join( - fileSeparator, - pathList)); - - TestSuiteFileEntity newTestSuiteFileEntity = - new TestSuiteFileEntity( - pathInfo.toString()); - newTestSuiteFileEntity.save(); - - com.googlecode.objectify.Key< - TestSuiteFileEntity> - testSuiteFileParent = - com.googlecode.objectify.Key - .create( + targetList.forEach( + target -> + IntStream.range(0, 10) + .forEach( + idx -> { + String year = + String.format( + "%04d", 2010 + idx); + String month = + String.format( + "%02d", + rand.nextInt(12)); + String day = + String.format( + "%02d", + rand.nextInt(30)); + String fileName = + String.format( + "%02d%02d%02d.bin", + rand.nextInt(23) + 1, + rand.nextInt(59) + 1, + rand.nextInt(59) + 1); + + List<String> pathList = + Arrays.asList( + GCS_SUITE_TEST_FOLDER_NAME + == "" + ? "suite_result" + : GCS_SUITE_TEST_FOLDER_NAME, + year, + month, + day, + fileName); + + Path pathInfo = + Paths.get( + String.join( + fileSeparator, + pathList)); + + TestSuiteFileEntity + newTestSuiteFileEntity = + new TestSuiteFileEntity( + pathInfo + .toString()); + newTestSuiteFileEntity.save(); + + com.googlecode.objectify.Key< + TestSuiteFileEntity> + testSuiteFileParent = + com.googlecode.objectify + .Key.create( TestSuiteFileEntity .class, newTestSuiteFileEntity .getFilePath()); - TestSuiteResultEntity testSuiteResultEntity = - new TestSuiteResultEntity( - testSuiteFileParent, - Instant.now() - .minus( - rand.nextInt( - 100), - ChronoUnit.DAYS) - .getEpochSecond(), - Instant.now() - .minus( - rand.nextInt( - 100), - ChronoUnit.DAYS) - .getEpochSecond(), - 1, - idx / 2 == 0 ? false : true, - pathInfo.toString(), - idx / 2 == 0 ? "/error/infra/log" : "", - "Test Place Name -" + idx, - "Suite Test Plan", - "Suite Version " + idx, - "Suite Test Name", - "Suite Build Number " + idx, - rand.nextInt(), - rand.nextInt(), - branch, - target, - Long.toString(Math.abs(rand.nextLong())), - "Build System Fingerprint " - + idx, - "Build Vendor Fingerprint " - + idx, - rand.nextInt(), - rand.nextInt()); - - testSuiteResultEntity.save(); - }) - ) - ); + TestSuiteResultEntity + testSuiteResultEntity = + new TestSuiteResultEntity( + testSuiteFileParent, + Instant.now() + .minus( + rand + .nextInt( + 100), + ChronoUnit + .DAYS) + .getEpochSecond(), + Instant.now() + .minus( + rand + .nextInt( + 100), + ChronoUnit + .DAYS) + .getEpochSecond(), + 1, + idx / 2 == 0 + ? false + : true, + pathInfo + .toString(), + idx / 2 == 0 + ? "/error/infra/log" + : "", + "Test Place Name -" + + idx, + "Suite Test Plan", + "Suite Version " + + idx, + "Suite Test Name", + "Suite Build Number " + + idx, + rand.nextInt(), + rand.nextInt(), + branch, + target, + Long.toString( + Math + .abs( + rand + .nextLong())), + "Build System Fingerprint " + + idx, + "Build Vendor Fingerprint " + + idx, + rand.nextInt(), + rand.nextInt()); + + testSuiteResultEntity.save(); + }))); resultMap.put("result", "successfully generated!"); return resultMap; } diff --git a/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java b/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java index 61931cb..9887ccd 100644 --- a/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java +++ b/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java @@ -19,6 +19,7 @@ package com.android.vts.api; import com.android.vts.entity.TestSuiteFileEntity; import com.android.vts.entity.TestSuiteResultEntity; import com.android.vts.proto.TestSuiteResultMessageProto.TestSuiteResultMessage; +import com.android.vts.servlet.BaseServlet; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.jackson.JacksonFactory; @@ -31,22 +32,49 @@ import org.apache.commons.codec.binary.Base64; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.IntStream; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; /** REST endpoint for posting test suite data to the Dashboard. */ public class TestSuiteResultRestServlet extends HttpServlet { - private static final String SERVICE_CLIENT_ID = System.getProperty("SERVICE_CLIENT_ID"); + private static String SERVICE_CLIENT_ID; private static final String SERVICE_NAME = "VTS Dashboard"; private static final Logger logger = Logger.getLogger(TestSuiteResultRestServlet.class.getName()); + /** System Configuration Property class */ + protected Properties systemConfigProp = new Properties(); + + @Override + public void init(ServletConfig cfg) throws ServletException { + super.init(cfg); + + try { + InputStream defaultInputStream = + TestSuiteResultRestServlet.class + .getClassLoader() + .getResourceAsStream("config.properties"); + systemConfigProp.load(defaultInputStream); + + SERVICE_CLIENT_ID = systemConfigProp.getProperty("appengine.serviceClientID"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { @@ -75,7 +103,8 @@ public class TestSuiteResultRestServlet extends HttpServlet { Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute(); if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) { - Key<TestSuiteFileEntity> testSuiteFileParent = Key.create(TestSuiteFileEntity.class, "suite_result/2019/04/06/132343.bin"); + Key<TestSuiteFileEntity> testSuiteFileParent = + Key.create(TestSuiteFileEntity.class, "suite_result/2019/04/06/132343.bin"); TestSuiteResultEntity testSuiteResultEntity = new TestSuiteResultEntity( testSuiteFileParent, diff --git a/src/main/java/com/android/vts/entity/TestSuiteResultEntity.java b/src/main/java/com/android/vts/entity/TestSuiteResultEntity.java index 4833eeb..40c393b 100644 --- a/src/main/java/com/android/vts/entity/TestSuiteResultEntity.java +++ b/src/main/java/com/android/vts/entity/TestSuiteResultEntity.java @@ -131,33 +131,6 @@ public class TestSuiteResultEntity { /** System Configuration Property class */ private static Properties systemConfigProp = new Properties(); - static { - try { - InputStream defaultInputStream = - TestSuiteResultEntity.class - .getClassLoader() - .getResourceAsStream("config.properties"); - systemConfigProp.load(defaultInputStream); - - String bugTrackingSystem = systemConfigProp.getProperty("bug.tracking.system"); - - if (!bugTrackingSystem.isEmpty()) { - InputStream btsInputStream = - TestSuiteResultEntity.class - .getClassLoader() - .getResourceAsStream( - "bug_tracking_system/" - + bugTrackingSystem - + "/config.properties"); - bugTrackingSystemProp.load(btsInputStream); - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - public enum TestType { UNKNOWN(0), TOT(1), @@ -320,6 +293,35 @@ public class TestSuiteResultEntity { ofy().save().entity(this).now(); } + public static void setPropertyValues(Properties newSystemConfigProp) { + systemConfigProp = newSystemConfigProp; + bugTrackingSystemProp = getBugTrackingSystemProp(newSystemConfigProp); + } + + private static Properties getBugTrackingSystemProp(Properties newSystemConfigProp) { + Properties newBugTrackingSystemProp = new Properties(); + try { + String bugTrackingSystem = newSystemConfigProp.getProperty("bug.tracking.system"); + + if (!bugTrackingSystem.isEmpty()) { + InputStream btsInputStream = + TestSuiteResultEntity.class + .getClassLoader() + .getResourceAsStream( + "bug_tracking_system/" + + bugTrackingSystem + + "/config.properties"); + newBugTrackingSystemProp.load(btsInputStream); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + return newBugTrackingSystemProp; + } + } + public static List<TestSuiteResultEntity> getTestSuitePlans() { return ofy().load() .type(TestSuiteResultEntity.class) diff --git a/src/main/java/com/android/vts/job/VtsSuiteTestJobServlet.java b/src/main/java/com/android/vts/job/VtsSuiteTestJobServlet.java index 1884513..719ba64 100644 --- a/src/main/java/com/android/vts/job/VtsSuiteTestJobServlet.java +++ b/src/main/java/com/android/vts/job/VtsSuiteTestJobServlet.java @@ -16,26 +16,12 @@ package com.android.vts.job; -import com.android.vts.entity.TestEntity; -import com.android.vts.entity.TestRunEntity; -import com.android.vts.entity.TestStatusEntity; import com.android.vts.entity.TestSuiteFileEntity; import com.android.vts.entity.TestSuiteResultEntity; import com.android.vts.proto.TestSuiteResultMessageProto; -import com.android.vts.util.EmailHelper; -import com.android.vts.util.FilterUtil; import com.android.vts.util.GcsHelper; import com.android.vts.util.TaskQueueHelper; import com.android.vts.util.TimeUtil; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.http.javanet.NetHttpTransport; -import com.google.api.client.json.jackson.JacksonFactory; -import com.google.api.services.oauth2.Oauth2; -import com.google.api.services.oauth2.model.Tokeninfo; -import com.google.appengine.api.datastore.DatastoreService; -import com.google.appengine.api.datastore.DatastoreServiceFactory; -import com.google.appengine.api.datastore.Query.Filter; -import com.google.appengine.api.datastore.Query.SortDirection; import com.google.appengine.api.memcache.ErrorHandlers; import com.google.appengine.api.memcache.MemcacheService; import com.google.appengine.api.memcache.MemcacheServiceFactory; @@ -46,36 +32,26 @@ import com.google.cloud.storage.Blob; import com.google.cloud.storage.Bucket; import com.google.cloud.storage.Storage; import com.googlecode.objectify.Key; -import com.googlecode.objectify.Result; -import org.apache.commons.codec.binary.Base64; - -import javax.mail.Message; -import javax.mail.MessagingException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.ByteArrayInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.io.UnsupportedEncodingException; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.Paths; -import java.text.SimpleDateFormat; -import java.time.Instant; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Properties; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -88,18 +64,16 @@ public class VtsSuiteTestJobServlet extends HttpServlet { private static final String SUITE_TEST_URL = "/cron/test_suite_report_gcs_monitor"; - private static final String SERVICE_CLIENT_ID = System.getProperty("SERVICE_CLIENT_ID"); private static final String SERVICE_NAME = "VTS Dashboard"; private final Logger logger = Logger.getLogger(this.getClass().getName()); /** Google Cloud Storage project's key file to access the storage */ - private static final String GCS_KEY_FILE = System.getProperty("GCS_KEY_FILE"); + private static String GCS_KEY_FILE; /** Google Cloud Storage project's default bucket name for vtslab log files */ - private static final String GCS_BUCKET_NAME = System.getProperty("GCS_BUCKET_NAME"); + private static String GCS_BUCKET_NAME; /** Google Cloud Storage project's default directory name for suite test result files */ - private static final String GCS_SUITE_TEST_FOLDER_NAME = - System.getProperty("GCS_SUITE_TEST_FOLDER_NAME"); + private static String GCS_SUITE_TEST_FOLDER_NAME; public static final String QUEUE = "suiteTestQueue"; @@ -115,23 +89,40 @@ public class VtsSuiteTestJobServlet extends HttpServlet { /** This is the instance of App Engine memcache service java library */ private MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService(); - private final DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + /** System Configuration Property class */ + protected Properties systemConfigProp = new Properties(); @Override public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); - this.keyFileInputStream = - this.getClass().getClassLoader().getResourceAsStream("keys/" + GCS_KEY_FILE); + try { + InputStream defaultInputStream = + VtsSuiteTestJobServlet.class + .getClassLoader() + .getResourceAsStream("config.properties"); + systemConfigProp.load(defaultInputStream); - Optional<Storage> optionalStorage = GcsHelper.getStorage(this.keyFileInputStream); - if (optionalStorage.isPresent()) { - this.storage = optionalStorage.get(); - } else { - logger.log(Level.SEVERE, "Error on getting storage instance!"); - throw new ServletException("Creating storage instance exception!"); + GCS_KEY_FILE = systemConfigProp.getProperty("gcs.keyFile"); + GCS_BUCKET_NAME = systemConfigProp.getProperty("gcs.bucketName"); + GCS_SUITE_TEST_FOLDER_NAME = systemConfigProp.getProperty("gcs.suiteTestFolderName"); + + this.keyFileInputStream = + this.getClass().getClassLoader().getResourceAsStream("keys/" + GCS_KEY_FILE); + + Optional<Storage> optionalStorage = GcsHelper.getStorage(this.keyFileInputStream); + if (optionalStorage.isPresent()) { + this.storage = optionalStorage.get(); + } else { + logger.log(Level.SEVERE, "Error on getting storage instance!"); + throw new ServletException("Creating storage instance exception!"); + } + syncCache.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(Level.INFO)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); } - syncCache.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(Level.INFO)); } @Override diff --git a/src/main/java/com/android/vts/servlet/BaseServlet.java b/src/main/java/com/android/vts/servlet/BaseServlet.java index 14983cc..7b4c624 100644 --- a/src/main/java/com/android/vts/servlet/BaseServlet.java +++ b/src/main/java/com/android/vts/servlet/BaseServlet.java @@ -16,18 +16,26 @@ package com.android.vts.servlet; +import com.android.vts.entity.TestSuiteResultEntity; +import com.android.vts.util.EmailHelper; +import com.android.vts.util.GcsHelper; import com.google.appengine.api.users.User; import com.google.appengine.api.users.UserService; import com.google.appengine.api.users.UserServiceFactory; import com.google.gson.Gson; + +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; +import javax.servlet.ServletConfig; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -39,10 +47,10 @@ public abstract class BaseServlet extends HttpServlet { protected String ERROR_MESSAGE_JSP = "WEB-INF/jsp/error_msg.jsp"; // Environment variables - protected static final String GERRIT_URI = System.getProperty("GERRIT_URI"); - protected static final String GERRIT_SCOPE = System.getProperty("GERRIT_SCOPE"); - protected static final String CLIENT_ID = System.getProperty("CLIENT_ID"); - protected static final String ANALYTICS_ID = System.getProperty("ANALYTICS_ID"); + protected static String GERRIT_URI; + protected static String GERRIT_SCOPE; + protected static String CLIENT_ID; + protected static String ANALYTICS_ID; protected static final String TREE_DEFAULT_PARAM = "treeDefault"; @@ -128,6 +136,35 @@ public abstract class BaseServlet extends HttpServlet { */ public abstract List<Page> getBreadcrumbLinks(HttpServletRequest request); + /** System Configuration Property class */ + protected static Properties systemConfigProp = new Properties(); + + @Override + public void init(ServletConfig cfg) throws ServletException { + super.init(cfg); + + try { + InputStream defaultInputStream = + BaseServlet.class + .getClassLoader() + .getResourceAsStream("config.properties"); + systemConfigProp.load(defaultInputStream); + + GERRIT_URI = systemConfigProp.getProperty("gerrit.uri"); + GERRIT_SCOPE = systemConfigProp.getProperty("gerrit.scope"); + CLIENT_ID = systemConfigProp.getProperty("appengine.clientID"); + ANALYTICS_ID = systemConfigProp.getProperty("analytics.id"); + + TestSuiteResultEntity.setPropertyValues(systemConfigProp); + EmailHelper.setPropertyValues(systemConfigProp); + GcsHelper.setGcsProjectId(systemConfigProp.getProperty("gcs.projectID")); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // If the user is logged out, allow them to log back in and return to the page. diff --git a/src/main/java/com/android/vts/servlet/ShowGcsLogServlet.java b/src/main/java/com/android/vts/servlet/ShowGcsLogServlet.java index 82624ce..ec332e5 100644 --- a/src/main/java/com/android/vts/servlet/ShowGcsLogServlet.java +++ b/src/main/java/com/android/vts/servlet/ShowGcsLogServlet.java @@ -56,9 +56,9 @@ public class ShowGcsLogServlet extends BaseServlet { private static final String GCS_LOG_JSP = "WEB-INF/jsp/show_gcs_log.jsp"; /** Google Cloud Storage project's key file to access the storage */ - private static final String GCS_KEY_FILE = System.getProperty("GCS_KEY_FILE"); + private static String GCS_KEY_FILE; /** Google Cloud Storage project's default bucket name for vtslab log files */ - private static final String GCS_BUCKET_NAME = System.getProperty("GCS_BUCKET_NAME"); + private static String GCS_BUCKET_NAME; /** * This is the key file to access vtslab-gcs project. It will allow the dashboard to have a full @@ -79,6 +79,9 @@ public class ShowGcsLogServlet extends BaseServlet { public void init(ServletConfig cfg) throws ServletException { super.init(cfg); + GCS_KEY_FILE = systemConfigProp.getProperty("gcs.keyFile"); + GCS_BUCKET_NAME = systemConfigProp.getProperty("gcs.bucketName"); + this.keyFileInputStream = this.getClass().getClassLoader().getResourceAsStream("keys/" + GCS_KEY_FILE); diff --git a/src/main/java/com/android/vts/util/EmailHelper.java b/src/main/java/com/android/vts/util/EmailHelper.java index cfdccd6..11bbdf5 100644 --- a/src/main/java/com/android/vts/util/EmailHelper.java +++ b/src/main/java/com/android/vts/util/EmailHelper.java @@ -44,11 +44,17 @@ import org.apache.commons.lang.StringUtils; /** EmailHelper, a helper class for building and sending emails. */ public class EmailHelper { protected static final Logger logger = Logger.getLogger(EmailHelper.class.getName()); - protected static final String DEFAULT_EMAIL = System.getProperty("DEFAULT_EMAIL"); - protected static final String EMAIL_DOMAIN = System.getProperty("EMAIL_DOMAIN"); - protected static final String SENDER_EMAIL = System.getProperty("SENDER_EMAIL"); + protected static String DEFAULT_EMAIL; + protected static String EMAIL_DOMAIN; + protected static String SENDER_EMAIL; private static final String VTS_EMAIL_NAME = "VTS Alert Bot"; + public static void setPropertyValues(Properties systemConfigProp) { + DEFAULT_EMAIL = systemConfigProp.getProperty("appengine.defaultEmail"); + EMAIL_DOMAIN = systemConfigProp.getProperty("appengine.emailDomain"); + SENDER_EMAIL = systemConfigProp.getProperty("appengine.senderEmail"); + } + /** * Create an email footer with the information from the test run. * diff --git a/src/main/java/com/android/vts/util/GcsHelper.java b/src/main/java/com/android/vts/util/GcsHelper.java index bb2b5be..4cb1811 100644 --- a/src/main/java/com/android/vts/util/GcsHelper.java +++ b/src/main/java/com/android/vts/util/GcsHelper.java @@ -16,7 +16,11 @@ public class GcsHelper { private static final Logger logger = Logger.getLogger(GcsHelper.class.getName()); /** Google Cloud Storage project ID */ - private static final String GCS_PROJECT_ID = System.getProperty("GCS_PROJECT_ID"); + private static String GCS_PROJECT_ID; + + public static void setGcsProjectId(String gcsProjectId) { + GCS_PROJECT_ID = gcsProjectId; + } public static Optional<Storage> getStorage(InputStream keyFileInputStream) { diff --git a/src/main/resources/config.properties b/src/main/resources/config.properties index 7e9010c..18e2d63 100644 --- a/src/main/resources/config.properties +++ b/src/main/resources/config.properties @@ -1,2 +1,19 @@ +appengine.version= +appengine.clientID= +appengine.serviceClientID= +appengine.senderEmail= +appengine.emailDomain= +appengine.defaultEmail= + +gerrit.uri= +gerrit.scope= + +analytics.id= + +gcs.projectID= +gcs.keyFile= +gcs.bucketName= +gcs.suiteTestFolderName= + bug.tracking.system= diff --git a/src/main/webapp/WEB-INF/appengine-web.xml b/src/main/webapp/WEB-INF/appengine-web.xml index bc527c0..d019e5c 100644 --- a/src/main/webapp/WEB-INF/appengine-web.xml +++ b/src/main/webapp/WEB-INF/appengine-web.xml @@ -18,19 +18,11 @@ <runtime>java8</runtime> <instance-class>F4_1G</instance-class> + <staging> + <enable-jar-classes>true</enable-jar-classes> + </staging> + <system-properties> - <property name="EMAIL_DOMAIN" value="${appengine.emailDomain}" /> - <property name="SENDER_EMAIL" value="${appengine.senderEmail}" /> - <property name="DEFAULT_EMAIL" value="${appengine.defaultEmail}" /> - <property name="SERVICE_CLIENT_ID" value="${appengine.serviceClientID}" /> - <property name="CLIENT_ID" value="${appengine.clientID}" /> - <property name="GERRIT_URI" value="${gerrit.uri}" /> - <property name="GERRIT_SCOPE" value="${gerrit.scope}" /> - <property name="ANALYTICS_ID" value="${analytics.id}" /> - <property name="GCS_PROJECT_ID" value="${gcs.projectID}" /> - <property name="GCS_KEY_FILE" value="${gcs.keyFile}" /> - <property name="GCS_BUCKET_NAME" value="${gcs.bucketName}" /> - <property name="GCS_SUITE_TEST_FOLDER_NAME" value="${gcs.suiteTestFolderName}" /> </system-properties> </appengine-web-app>
\ No newline at end of file |