Merge "Making DataStoreFactory and Google API scopes variables global"
diff --git a/src/main/java/com/android/vts/config/ObjectifyListener.java b/src/main/java/com/android/vts/config/ObjectifyListener.java
index 8beeda2..9c4a705 100644
--- a/src/main/java/com/android/vts/config/ObjectifyListener.java
+++ b/src/main/java/com/android/vts/config/ObjectifyListener.java
@@ -37,9 +37,13 @@
 import com.android.vts.entity.TestSuiteFileEntity;
 import com.android.vts.entity.TestSuiteResultEntity;
 import com.android.vts.entity.UserEntity;
+import com.google.api.client.extensions.appengine.datastore.AppEngineDataStoreFactory;
+import com.google.api.services.sheets.v4.SheetsScopes;
 import com.googlecode.objectify.ObjectifyService;
 
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.Optional;
 import java.util.function.Supplier;
 import java.util.stream.Stream;
@@ -64,6 +68,15 @@
 
     private static final Logger logger = Logger.getLogger(ObjectifyListener.class.getName());
 
+
+    /** Global instance of the DataStoreFactory. */
+    private static final AppEngineDataStoreFactory DATA_STORE_FACTORY =
+            AppEngineDataStoreFactory.getDefaultInstance();
+
+    /** Global instance of the scopes. */
+    private static final List<String> GOOGLE_API_SCOPES =
+            Collections.singletonList(SheetsScopes.SPREADSHEETS_READONLY);
+
     /**
      * Receives notification that the web application initialization process is starting. This
      * function will register Entity classes for objectify.
@@ -108,6 +121,13 @@
 
             systemConfigProp.load(defaultInputStream);
 
+            servletContextEvent
+                    .getServletContext()
+                    .setAttribute("dataStoreFactory", DATA_STORE_FACTORY);
+            servletContextEvent
+                    .getServletContext()
+                    .setAttribute("googleApiScopes", GOOGLE_API_SCOPES);
+
             String roleList = systemConfigProp.getProperty("user.roleList");
             Supplier<Stream<String>> streamSupplier = () -> Arrays.stream(roleList.split(","));
             this.createRoles(streamSupplier.get());
@@ -123,9 +143,9 @@
                 this.createAdminUser(adminEmail, adminName, adminCompany, roleName.orElse("admin"));
             }
         } catch (FileNotFoundException e) {
-            e.printStackTrace();
+            logger.log(Level.SEVERE, e.getMessage());
         } catch (IOException e) {
-            e.printStackTrace();
+            logger.log(Level.SEVERE, e.getMessage());
         }
     }
 
diff --git a/src/main/java/com/android/vts/job/VtsSpreadSheetSyncServlet.java b/src/main/java/com/android/vts/job/VtsSpreadSheetSyncServlet.java
index 079aa2d..0f1bfbc 100644
--- a/src/main/java/com/android/vts/job/VtsSpreadSheetSyncServlet.java
+++ b/src/main/java/com/android/vts/job/VtsSpreadSheetSyncServlet.java
@@ -18,6 +18,7 @@
 
 import com.android.vts.entity.ApiCoverageExcludedEntity;
 import com.google.api.client.auth.oauth2.Credential;
+import com.google.api.client.extensions.appengine.datastore.AppEngineDataStoreFactory;
 import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
 import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
 import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
@@ -26,18 +27,14 @@
 import com.google.api.client.http.javanet.NetHttpTransport;
 import com.google.api.client.json.JsonFactory;
 import com.google.api.client.json.jackson2.JacksonFactory;
-import com.google.api.client.util.store.FileDataStoreFactory;
 import com.google.api.services.sheets.v4.Sheets;
-import com.google.api.services.sheets.v4.SheetsScopes;
 import com.google.api.services.sheets.v4.model.ValueRange;
 
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.security.GeneralSecurityException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 import javax.servlet.ServletConfig;
@@ -56,14 +53,6 @@
 
     private static final String APPLICATION_NAME = "VTS Dashboard";
     private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
-    private static final String TOKENS_DIRECTORY_PATH = "tokens";
-
-    /**
-     * Global instance of the scopes. If modifying these scopes, delete your previously saved
-     * tokens/ folder.
-     */
-    private static final List<String> SCOPES =
-            Collections.singletonList(SheetsScopes.SPREADSHEETS_READONLY);
 
     private String CREDENTIALS_KEY_FILE = "";
 
@@ -103,19 +92,24 @@
      * Creates an authorized Credential object.
      *
      * @param HTTP_TRANSPORT The network HTTP Transport.
+     * @param appEngineDataStoreFactory The credential will be persisted using the Google App Engine
+     *     Data Store API.
+     * @param SCOPES Scopes are strings that enable access to particular resources, such as user
+     *     data.
      * @return An authorized Credential object.
      * @throws IOException If the credentials.json file cannot be found.
      */
-    private Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
+    private Credential getCredentials(
+            final NetHttpTransport HTTP_TRANSPORT,
+            final AppEngineDataStoreFactory appEngineDataStoreFactory,
+            final List<String> SCOPES)
+            throws IOException {
 
         // Build flow and trigger user authorization request.
-        File fileTokenDirPath = new File(TOKENS_DIRECTORY_PATH);
-        FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(fileTokenDirPath);
-
         GoogleAuthorizationCodeFlow flow =
                 new GoogleAuthorizationCodeFlow.Builder(
                                 HTTP_TRANSPORT, JSON_FACTORY, this.clientSecrets, SCOPES)
-                        .setDataStoreFactory(fileDataStoreFactory)
+                        .setDataStoreFactory(appEngineDataStoreFactory)
                         .setAccessType("offline")
                         .build();
         LocalServerReceiver localServerReceiver = new LocalServerReceiver();
@@ -128,8 +122,20 @@
         try {
             // Build a new authorized API client service.
             final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
+            final AppEngineDataStoreFactory appEngineDataStoreFactory =
+                    (AppEngineDataStoreFactory)
+                            request.getServletContext().getAttribute("dataStoreFactory");
+            final List<String> googleApiScopes =
+                    (List<String>) request.getServletContext().getAttribute("googleApiScopes");
+
             Sheets service =
-                    new Sheets.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
+                    new Sheets.Builder(
+                                    HTTP_TRANSPORT,
+                                    JSON_FACTORY,
+                                    getCredentials(
+                                            HTTP_TRANSPORT,
+                                            appEngineDataStoreFactory,
+                                            googleApiScopes))
                             .setApplicationName(APPLICATION_NAME)
                             .build();