diff options
Diffstat (limited to 'src/main/java/com/android/vts/api')
10 files changed, 0 insertions, 2340 deletions
diff --git a/src/main/java/com/android/vts/api/BaseApiServlet.java b/src/main/java/com/android/vts/api/BaseApiServlet.java deleted file mode 100644 index b7384a7..0000000 --- a/src/main/java/com/android/vts/api/BaseApiServlet.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2018 Google Inc. 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. - */ - -package com.android.vts.api; - -import com.google.apphosting.api.ApiProxy; -import java.util.Properties; -import java.util.logging.Logger; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletResponse; - -/** An abstract class to be subclassed to create API Servlet */ -public class BaseApiServlet extends HttpServlet { - - private static final Logger logger = Logger.getLogger(BaseApiServlet.class.getName()); - - /** System Configuration Property class */ - protected Properties systemConfigProp = new Properties(); - - /** Appengine server host name */ - protected String hostName; - - /** - * This variable is for maximum number of entities per transaction You can find the detail here - * (https://cloud.google.com/datastore/docs/concepts/limits) - */ - protected int MAX_ENTITY_SIZE_PER_TRANSACTION = 300; - - @Override - public void init(ServletConfig cfg) throws ServletException { - super.init(cfg); - - systemConfigProp = - Properties.class.cast(cfg.getServletContext().getAttribute("systemConfigProp")); - - this.MAX_ENTITY_SIZE_PER_TRANSACTION = - Integer.parseInt(systemConfigProp.getProperty("datastore.maxEntitySize")); - - ApiProxy.Environment env = ApiProxy.getCurrentEnvironment(); - hostName = - env.getAttributes() - .get("com.google.appengine.runtime.default_version_hostname") - .toString(); - } - - protected void setAccessControlHeaders(HttpServletResponse resp) { - resp.setHeader("Access-Control-Allow-Origin", hostName); - resp.setHeader("Access-Control-Allow-Methods", "GET, PUT, POST, OPTIONS, DELETE"); - resp.addHeader("Access-Control-Allow-Headers", "Content-Type"); - resp.addHeader("Access-Control-Max-Age", "86400"); - } -} diff --git a/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java b/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java deleted file mode 100644 index d331d4b..0000000 --- a/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2016 Google Inc. 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. - */ - -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; -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.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; -import org.apache.commons.codec.binary.Base64; -import org.json.JSONException; -import org.json.JSONObject; - -/** REST endpoint for posting data JSON to the Dashboard. */ -@Deprecated -public class BigtableLegacyJsonServlet extends HttpServlet { - 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 { - // Retrieve the params - String payload = new String(); - JSONObject payloadJson; - try { - String line = null; - BufferedReader reader = request.getReader(); - while ((line = reader.readLine()) != null) { - payload += line; - } - payloadJson = new JSONObject(payload); - } catch (IOException | JSONException e) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - logger.log(Level.WARNING, "Invalid JSON: " + payload); - return; - } - - // Verify service account access token. - boolean authorized = false; - if (payloadJson.has("accessToken")) { - String accessToken = payloadJson.getString("accessToken").trim(); - GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken); - Oauth2 oauth2 = - new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credential) - .setApplicationName(SERVICE_NAME) - .build(); - Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute(); - if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) { - authorized = true; - } - } - - if (!authorized) { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - return; - } - - // Parse the desired action and execute the command - try { - if (payloadJson.has("verb")) { - switch (payloadJson.getString("verb")) { - case "createTable": - logger.log(Level.INFO, "Deprecated verb: createTable."); - break; - case "insertRow": - insertData(payloadJson); - break; - default: - logger.log( - Level.WARNING, - "Invalid Datastore REST verb: " + payloadJson.getString("verb")); - throw new IOException("Unsupported POST verb."); - } - } - } catch (IOException e) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - return; - } - response.setStatus(HttpServletResponse.SC_OK); - } - - /** - * Inserts a data into the Cloud Datastore - * - * @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' } - * @throws IOException - */ - private void insertData(JSONObject payloadJson) throws IOException { - if (!payloadJson.has("value")) { - logger.log(Level.WARNING, "Missing attributes for datastore api insertRow()."); - return; - } - try { - byte[] value = Base64.decodeBase64(payloadJson.getString("value")); - TestReportMessage testReportMessage = TestReportMessage.parseFrom(value); - } catch (InvalidProtocolBufferException e) { - logger.log(Level.WARNING, "Invalid report posted to dashboard."); - } - } -} diff --git a/src/main/java/com/android/vts/api/CoverageRestServlet.java b/src/main/java/com/android/vts/api/CoverageRestServlet.java deleted file mode 100644 index aebd3e5..0000000 --- a/src/main/java/com/android/vts/api/CoverageRestServlet.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2018 Google Inc. 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. - */ - -package com.android.vts.api; - -import com.android.vts.entity.ApiCoverageEntity; -import com.android.vts.entity.CoverageEntity; -import com.android.vts.entity.TestCoverageStatusEntity; -import com.android.vts.entity.TestPlanRunEntity; -import com.android.vts.entity.TestRunEntity; -import com.google.gson.Gson; -import com.googlecode.objectify.Key; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import static com.googlecode.objectify.ObjectifyService.ofy; - -/** REST endpoint for posting test suite data to the Dashboard. */ -public class CoverageRestServlet extends BaseApiServlet { - - private static final Logger logger = Logger.getLogger(CoverageRestServlet.class.getName()); - - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - String pathInfo = request.getPathInfo(); - String json = ""; - if (Objects.nonNull(pathInfo)) { - if (pathInfo.equalsIgnoreCase("/api/data")) { - String key = request.getParameter("key"); - json = apiCoverageData(key); - } else { - json = "{error: 'true', message: 'unexpected path!!!'}"; - logger.log(Level.INFO, "Path Info => " + pathInfo); - logger.log(Level.WARNING, "Unknown path access!"); - } - } else { - json = "{error: 'true', message: 'the path info is not existed!!!'}"; - } - - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("application/json"); - response.setCharacterEncoding("UTF-8"); - response.getWriter().write(json); - } - - private String apiCoverageData(String key) { - ApiCoverageEntity apiCoverageEntity = ApiCoverageEntity.getByUrlSafeKey(key); - String apiCoverageEntityJson = new Gson().toJson(apiCoverageEntity); - return apiCoverageEntityJson; - } - - @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws IOException { - - String pathInfo = request.getPathInfo(); - String json = ""; - if (Objects.nonNull(pathInfo)) { - if (pathInfo.equalsIgnoreCase("/api/data")) { - String cmd = request.getParameter("cmd"); - String coverageId = request.getParameter("coverageId"); - String testName = request.getParameter("testName"); - String testRunId = request.getParameter("testRunId"); - json = postCoverageData(cmd, coverageId, testName, testRunId); - } else if (pathInfo.equalsIgnoreCase("/api/sum")) { - String urlSafeKey = request.getParameter("urlSafeKey"); - json = postCoverageDataSum(urlSafeKey); - } else { - json = "{error: 'true', message: 'unexpected path!!!'}"; - } - } else { - json = "{error: 'true', message: 'the path info is not existed!!!'}"; - } - - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("application/json"); - response.setCharacterEncoding("UTF-8"); - response.getWriter().write(json); - } - - private String postCoverageDataSum(String urlSafeKey) { - List<List<String>> allHalApiList = new ArrayList(); - List<List<String>> allCoveredHalApiList = new ArrayList(); - - Key<TestPlanRunEntity> key = Key.create(urlSafeKey); - TestPlanRunEntity testPlanRunEntity = ofy().load().key(key).safe(); - - for (Key<TestRunEntity> testRunKey : testPlanRunEntity.getTestRuns()) { - List<ApiCoverageEntity> apiCoverageEntityList = - ofy().load().type(ApiCoverageEntity.class).ancestor(testRunKey).list(); - for (ApiCoverageEntity apiCoverageEntity : apiCoverageEntityList) { - allHalApiList.add(apiCoverageEntity.getHalApi()); - allCoveredHalApiList.add(apiCoverageEntity.getCoveredHalApi()); - } - } - long totalHalApiNum = allHalApiList.stream().flatMap(Collection::stream).distinct().count(); - long totalCoveredHalApiNum = - allCoveredHalApiList.stream().flatMap(Collection::stream).distinct().count(); - if (totalHalApiNum > 0) { - testPlanRunEntity.setTotalApiCount(totalHalApiNum); - if (totalCoveredHalApiNum > 0) { - testPlanRunEntity.setCoveredApiCount(totalCoveredHalApiNum); - } - testPlanRunEntity.save(); - } - - Map<String, Long> halApiNumMap = - new HashMap<String, Long>() { - { - put("totalHalApiNum", totalHalApiNum); - put("totalCoveredHalApiNum", totalCoveredHalApiNum); - } - }; - String json = new Gson().toJson(halApiNumMap); - return json; - } - - /** - * The API to ignore the irrelevant code for calculating ratio - * - * @param cmd disable or enable command to ignore the code. - * @param coverageId the datastore ID for code coverage. - * @param testName the test name. - * @param testRunId the test run ID from datastore. - * @return success json. - */ - private String postCoverageData( - String cmd, String coverageId, String testName, String testRunId) { - - Boolean isIgnored = false; - if (cmd.equals("disable")) { - isIgnored = true; - } - CoverageEntity coverageEntity = CoverageEntity.findById(testName, testRunId, coverageId); - coverageEntity.setIsIgnored(isIgnored); - coverageEntity.save(); - - TestCoverageStatusEntity testCoverageStatusEntity = - TestCoverageStatusEntity.findById(testName); - Long newCoveredLineCount = - cmd.equals("disable") - ? testCoverageStatusEntity.getUpdatedCoveredLineCount() - - coverageEntity.getCoveredCount() - : testCoverageStatusEntity.getUpdatedCoveredLineCount() - + coverageEntity.getCoveredCount(); - Long newTotalLineCount = - cmd.equals("disable") - ? testCoverageStatusEntity.getUpdatedTotalLineCount() - - coverageEntity.getTotalCount() - : testCoverageStatusEntity.getUpdatedTotalLineCount() - + coverageEntity.getTotalCount(); - testCoverageStatusEntity.setUpdatedCoveredLineCount(newCoveredLineCount); - testCoverageStatusEntity.setUpdatedTotalLineCount(newTotalLineCount); - testCoverageStatusEntity.save(); - - String json = new Gson().toJson("Success!"); - return json; - } -} diff --git a/src/main/java/com/android/vts/api/DataRestServlet.java b/src/main/java/com/android/vts/api/DataRestServlet.java deleted file mode 100644 index 409818e..0000000 --- a/src/main/java/com/android/vts/api/DataRestServlet.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2018 Google Inc. 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. - */ - -package com.android.vts.api; - -import com.android.vts.entity.BranchEntity; -import com.android.vts.entity.TestCoverageStatusEntity; -import com.google.gson.Gson; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.List; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.android.vts.entity.BuildTargetEntity; - -/** REST endpoint for getting all branch and buildFlavors information. */ -public class DataRestServlet extends BaseApiServlet { - - private static final Logger logger = Logger.getLogger(DataRestServlet.class.getName()); - - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - String pathInfo = request.getPathInfo(); - String json = ""; - if (Objects.nonNull(pathInfo)) { - String schKey = - Objects.isNull(request.getParameter("schKey")) - ? "" - : request.getParameter("schKey"); - if (pathInfo.equalsIgnoreCase("/branch")) { - json = new Gson().toJson(BranchEntity.getByBranch(schKey)); - } else if (pathInfo.equalsIgnoreCase("/device")) { - json = new Gson().toJson(BuildTargetEntity.getByBuildTarget(schKey)); - } else if (pathInfo.startsWith("/code/coverage/status/")) { - List<TestCoverageStatusEntity> testCoverageStatusEntityList = - TestCoverageStatusEntity.getAllTestCoverage(); - if (pathInfo.endsWith("branch")) { - json = - new Gson() - .toJson( - TestCoverageStatusEntity.getBranchSet( - testCoverageStatusEntityList)); - } else { - json = - new Gson() - .toJson( - TestCoverageStatusEntity.getDeviceSet( - testCoverageStatusEntityList)); - } - } else { - json = "{error: 'true', message: 'unexpected path!!!'}"; - logger.log(Level.INFO, "Path Info => " + pathInfo); - logger.log(Level.WARNING, "Unknown path access!"); - } - } else { - json = "{error: 'true', message: 'the path info is not existed!!!'}"; - } - - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("application/json"); - response.setCharacterEncoding("UTF-8"); - response.getWriter().write(json); - } -} diff --git a/src/main/java/com/android/vts/api/DatastoreRestServlet.java b/src/main/java/com/android/vts/api/DatastoreRestServlet.java deleted file mode 100644 index fa0ae65..0000000 --- a/src/main/java/com/android/vts/api/DatastoreRestServlet.java +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Copyright (c) 2016 Google Inc. 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. - */ - -package com.android.vts.api; - -import com.android.vts.entity.ApiCoverageEntity; -import com.android.vts.entity.BranchEntity; -import com.android.vts.entity.BuildTargetEntity; -import com.android.vts.entity.CodeCoverageEntity; -import com.android.vts.entity.CoverageEntity; -import com.android.vts.entity.DashboardEntity; -import com.android.vts.entity.DeviceInfoEntity; -import com.android.vts.entity.HalApiEntity; -import com.android.vts.entity.ProfilingPointRunEntity; -import com.android.vts.entity.TestCaseRunEntity; -import com.android.vts.entity.TestEntity; -import com.android.vts.entity.TestPlanEntity; -import com.android.vts.entity.TestPlanRunEntity; -import com.android.vts.entity.TestRunEntity; -import com.android.vts.proto.VtsReportMessage; -import com.android.vts.proto.VtsReportMessage.DashboardPostMessage; -import com.android.vts.proto.VtsReportMessage.TestPlanReportMessage; -import com.android.vts.proto.VtsReportMessage.TestReportMessage; -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.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.google.appengine.api.datastore.Key; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.codec.binary.Base64; - -import static com.googlecode.objectify.ObjectifyService.ofy; - -@Slf4j -/** REST endpoint for posting data to the Dashboard. */ -public class DatastoreRestServlet extends BaseApiServlet { - private static String SERVICE_CLIENT_ID; - private static final String SERVICE_NAME = "VTS Dashboard"; - - @Override - public void init(ServletConfig cfg) throws ServletException { - super.init(cfg); - - SERVICE_CLIENT_ID = this.systemConfigProp.getProperty("appengine.serviceClientID"); - } - - @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws IOException { - // Retrieve the params - DashboardPostMessage postMessage; - try { - String payload = request.getReader().lines().collect(Collectors.joining()); - byte[] value = Base64.decodeBase64(payload); - postMessage = DashboardPostMessage.parseFrom(value); - } catch (IOException e) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - log.error("Invalid proto: " + e.getLocalizedMessage()); - return; - } - - String resultMsg = ""; - // Verify service account access token. - if (postMessage.hasAccessToken()) { - String accessToken = postMessage.getAccessToken(); - log.debug("accessToken => " + accessToken); - - GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken); - Oauth2 oauth2 = - new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credential) - .setApplicationName(SERVICE_NAME) - .build(); - Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute(); - if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) { - for (TestReportMessage testReportMessage : postMessage.getTestReportList()) { - this.insertTestReport(testReportMessage); - } - - for (TestPlanReportMessage planReportMessage : - postMessage.getTestPlanReportList()) { - this.insertTestPlanReport(planReportMessage); - } - - response.setStatus(HttpServletResponse.SC_OK); - resultMsg = "Success!!"; - } else { - log.warn("service_client_id didn't match!"); - log.debug("SERVICE_CLIENT_ID => " + tokenInfo.getIssuedTo()); - resultMsg = "Your SERVICE_CLIENT_ID is incorrect!"; - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - } - } else { - log.error("postMessage do not contain any accessToken!"); - resultMsg = "Your message do not have access token!"; - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - } - response.setContentType("application/json"); - response.setCharacterEncoding("UTF-8"); - response.getWriter().write("{'result_msg': " + resultMsg + "}"); - } - - /** - * Upload data from a test report message - * - * @param report The test report containing data to upload. - */ - private void insertTestReport(TestReportMessage report) { - - if (!report.hasStartTimestamp() - || !report.hasEndTimestamp() - || !report.hasTest() - || !report.hasHostInfo() - || !report.hasBuildInfo()) { - // missing information - log.error("Missing information in report !"); - return; - } - - List<TestEntity> testEntityList = new ArrayList<>(); - List<TestRunEntity> testRunEntityList = new ArrayList<>(); - List<BranchEntity> branchEntityList = new ArrayList<>(); - List<BuildTargetEntity> buildTargetEntityList = new ArrayList<>(); - List<CoverageEntity> coverageEntityList = new ArrayList<>(); - List<CodeCoverageEntity> codeCoverageEntityList = new ArrayList<>(); - List<DeviceInfoEntity> deviceInfoEntityList = new ArrayList<>(); - List<ProfilingPointRunEntity> profilingPointRunEntityList = new ArrayList<>(); - List<TestCaseRunEntity> testCaseRunEntityList = new ArrayList<>(); - List<ApiCoverageEntity> apiCoverageEntityList = new ArrayList<>(); - - List<?> allEntityList = - Arrays.asList( - testEntityList, - branchEntityList, - buildTargetEntityList, - coverageEntityList, - codeCoverageEntityList, - deviceInfoEntityList, - profilingPointRunEntityList, - testCaseRunEntityList, - apiCoverageEntityList, - testRunEntityList); - - long passCount = 0; - long failCount = 0; - long coveredLineCount = 0; - long totalLineCount = 0; - - Set<Key> buildTargetKeys = new HashSet<>(); - Set<Key> branchKeys = new HashSet<>(); - List<Key> profilingPointKeyList = new ArrayList<>(); - List<String> linkList = new ArrayList<>(); - - long startTimestamp = report.getStartTimestamp(); - long endTimestamp = report.getEndTimestamp(); - String testName = report.getTest().toStringUtf8(); - String testBuildId = report.getBuildInfo().getId().toStringUtf8(); - String hostName = report.getHostInfo().getHostname().toStringUtf8(); - - TestEntity testEntity = new TestEntity(testName); - - com.googlecode.objectify.Key testRunKey = - testEntity.getTestRunKey(report.getStartTimestamp()); - - testEntityList.add(testEntity); - - int testCaseRunEntityIndex = 0; - testCaseRunEntityList.add(new TestCaseRunEntity()); - // Process test cases - for (VtsReportMessage.TestCaseReportMessage testCase : report.getTestCaseList()) { - String testCaseName = testCase.getName().toStringUtf8(); - VtsReportMessage.TestCaseResult result = testCase.getTestResult(); - // Track global pass/fail counts - if (result == VtsReportMessage.TestCaseResult.TEST_CASE_RESULT_PASS) { - ++passCount; - } else if (result != VtsReportMessage.TestCaseResult.TEST_CASE_RESULT_SKIP) { - ++failCount; - } - if (testCase.getSystraceCount() > 0 - && testCase.getSystraceList().get(0).getUrlCount() > 0) { - String systraceLink = testCase.getSystraceList().get(0).getUrl(0).toStringUtf8(); - linkList.add(systraceLink); - } - - // Process coverage data for test case - for (VtsReportMessage.CoverageReportMessage coverage : testCase.getCoverageList()) { - CoverageEntity coverageEntity = - CoverageEntity.fromCoverageReport(testRunKey, testCaseName, coverage); - if (coverageEntity == null) { - log.warn("Invalid coverage report in test run " + testRunKey); - } else { - coveredLineCount += coverageEntity.getCoveredCount(); - totalLineCount += coverageEntity.getTotalCount(); - coverageEntityList.add(coverageEntity); - } - } - - // Process profiling data for test case - for (VtsReportMessage.ProfilingReportMessage profiling : testCase.getProfilingList()) { - ProfilingPointRunEntity profilingPointRunEntity = - ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling); - if (profilingPointRunEntity == null) { - log.warn("Invalid profiling report in test run " + testRunKey); - } else { - profilingPointRunEntityList.add(profilingPointRunEntity); - profilingPointKeyList.add(profilingPointRunEntity.getKey()); - testEntity.setHasProfilingData(true); - } - } - - TestCaseRunEntity testCaseRunEntity = testCaseRunEntityList.get(testCaseRunEntityIndex); - if (!testCaseRunEntity.addTestCase(testCaseName, result.getNumber())) { - testCaseRunEntity = new TestCaseRunEntity(); - testCaseRunEntity.addTestCase(testCaseName, result.getNumber()); - testCaseRunEntityList.add(testCaseRunEntity); - testCaseRunEntityIndex++; - } - } - - // Process device information - long testRunType = 0; - for (VtsReportMessage.AndroidDeviceInfoMessage device : report.getDeviceInfoList()) { - DeviceInfoEntity deviceInfoEntity = - DeviceInfoEntity.fromDeviceInfoMessage(testRunKey, device); - if (deviceInfoEntity == null) { - log.warn("Invalid device info in test run " + testRunKey); - } else { - // Run type on devices must be the same, else set to OTHER - TestRunEntity.TestRunType runType = - TestRunEntity.TestRunType.fromBuildId(deviceInfoEntity.getBuildId()); - if (runType == null) { - testRunType = TestRunEntity.TestRunType.OTHER.getNumber(); - } else { - testRunType = runType.getNumber(); - } - deviceInfoEntityList.add(deviceInfoEntity); - BuildTargetEntity target = new BuildTargetEntity(deviceInfoEntity.getBuildFlavor()); - if (buildTargetKeys.add(target.getKey())) { - buildTargetEntityList.add(target); - } - BranchEntity branch = new BranchEntity(deviceInfoEntity.getBranch()); - if (branchKeys.add(branch.getKey())) { - branchEntityList.add(branch); - } - } - } - - // Overall run type should be determined by the device builds unless test build is OTHER - if (testRunType == TestRunEntity.TestRunType.OTHER.getNumber()) { - testRunType = TestRunEntity.TestRunType.fromBuildId(testBuildId).getNumber(); - } else if (TestRunEntity.TestRunType.fromBuildId(testBuildId) - == TestRunEntity.TestRunType.OTHER) { - testRunType = TestRunEntity.TestRunType.OTHER.getNumber(); - } - - // Process global coverage data - for (VtsReportMessage.CoverageReportMessage coverage : report.getCoverageList()) { - CoverageEntity coverageEntity = - CoverageEntity.fromCoverageReport(testRunKey, new String(), coverage); - if (coverageEntity == null) { - log.warn("Invalid coverage report in test run " + testRunKey); - } else { - coveredLineCount += coverageEntity.getCoveredCount(); - totalLineCount += coverageEntity.getTotalCount(); - coverageEntityList.add(coverageEntity); - } - } - - // Process global API coverage data - for (VtsReportMessage.ApiCoverageReportMessage apiCoverage : report.getApiCoverageList()) { - VtsReportMessage.HalInterfaceMessage halInterfaceMessage = - apiCoverage.getHalInterface(); - List<String> halApiList = - apiCoverage - .getHalApiList() - .stream() - .map(h -> h.toStringUtf8()) - .collect(Collectors.toList()); - List<String> coveredHalApiList = - apiCoverage - .getCoveredHalApiList() - .stream() - .map(h -> h.toStringUtf8()) - .collect(Collectors.toList()); - ApiCoverageEntity apiCoverageEntity = - new ApiCoverageEntity( - testRunKey, - halInterfaceMessage.getHalPackageName().toStringUtf8(), - halInterfaceMessage.getHalVersionMajor(), - halInterfaceMessage.getHalVersionMinor(), - halInterfaceMessage.getHalInterfaceName().toStringUtf8(), - halApiList, - coveredHalApiList); - apiCoverageEntityList.add(apiCoverageEntity); - } - - // Process global profiling data - for (VtsReportMessage.ProfilingReportMessage profiling : report.getProfilingList()) { - ProfilingPointRunEntity profilingPointRunEntity = - ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling); - if (profilingPointRunEntity == null) { - log.warn("Invalid profiling report in test run " + testRunKey); - } else { - profilingPointRunEntityList.add(profilingPointRunEntity); - profilingPointKeyList.add(profilingPointRunEntity.getKey()); - testEntity.setHasProfilingData(true); - } - } - - // Process log data - for (VtsReportMessage.LogMessage log : report.getLogList()) { - if (log.hasUrl()) { - linkList.add(log.getUrl().toStringUtf8()); - } - } - // Process url resource - for (VtsReportMessage.UrlResourceMessage resource : report.getLinkResourceList()) { - if (resource.hasUrl()) { - linkList.add(resource.getUrl().toStringUtf8()); - } - } - - boolean hasCodeCoverage = totalLineCount > 0 && coveredLineCount >= 0; - TestRunEntity testRunEntity = - new TestRunEntity( - testEntity.getOldKey(), - testRunType, - startTimestamp, - endTimestamp, - testBuildId, - hostName, - passCount, - failCount, - hasCodeCoverage, - new ArrayList<>(), - linkList); - testRunEntityList.add(testRunEntity); - - CodeCoverageEntity codeCoverageEntity = - new CodeCoverageEntity( - testRunEntity.getId(), - testRunEntity.getKey(), - coveredLineCount, - totalLineCount); - codeCoverageEntityList.add(codeCoverageEntity); - - ofy().transact( - () -> { - List<Long> testCaseIds = new ArrayList<>(); - for (Object entity : allEntityList) { - if (entity instanceof List) { - List listEntity = (List) entity; - if (listEntity.size() > 0 - && listEntity.get(0) instanceof TestCaseRunEntity) { - Map< - com.googlecode.objectify.Key< - TestCaseRunEntity>, - TestCaseRunEntity> - testCaseRunEntityMap = - DashboardEntity.saveAll( - testCaseRunEntityList, - this - .MAX_ENTITY_SIZE_PER_TRANSACTION); - - testCaseIds = - testCaseRunEntityMap - .values() - .stream() - .map( - testCaseRunEntity -> - testCaseRunEntity.getId()) - .collect(Collectors.toList()); - } else if (listEntity.size() > 0 - && listEntity.get(0) instanceof TestRunEntity) { - testRunEntityList.get(0).setTestCaseIds(testCaseIds); - DashboardEntity.saveAll( - testRunEntityList, - this.MAX_ENTITY_SIZE_PER_TRANSACTION); - } else { - List<DashboardEntity> dashboardEntityList = - (List<DashboardEntity>) entity; - DashboardEntity.saveAll( - dashboardEntityList, - this.MAX_ENTITY_SIZE_PER_TRANSACTION); - } - } - } - }); - } - - /** - * Upload data from a test plan report message - * - * @param report The test plan report containing data to upload. - */ - private void insertTestPlanReport(TestPlanReportMessage report) { - List<DeviceInfoEntity> deviceInfoEntityList = new ArrayList<>(); - List<HalApiEntity> halApiEntityList = new ArrayList<>(); - - List allEntityList = Arrays.asList(deviceInfoEntityList, halApiEntityList); - - List<String> testModules = report.getTestModuleNameList(); - List<Long> testTimes = report.getTestModuleStartTimestampList(); - if (testModules.size() != testTimes.size() || !report.hasTestPlanName()) { - log.error("TestPlanReportMessage is missing information."); - return; - } - - String testPlanName = report.getTestPlanName(); - TestPlanEntity testPlanEntity = new TestPlanEntity(testPlanName); - List<com.googlecode.objectify.Key<TestRunEntity>> testRunKeyList = new ArrayList<>(); - for (int index = 0; index < testModules.size(); index++) { - String test = testModules.get(index); - long time = testTimes.get(index); - com.googlecode.objectify.Key testKey = - com.googlecode.objectify.Key.create(TestEntity.class, test); - com.googlecode.objectify.Key testRunKey = - com.googlecode.objectify.Key.create(testKey, TestRunEntity.class, time); - testRunKeyList.add(testRunKey); - } - - Map<com.googlecode.objectify.Key<TestRunEntity>, TestRunEntity> testRunEntityMap = - ofy().load().keys(() -> testRunKeyList.iterator()); - - long passCount = 0; - long failCount = 0; - long startTimestamp = -1; - long endTimestamp = -1; - String testBuildId = null; - long testType = -1; - Set<DeviceInfoEntity> deviceInfoEntitySet = new HashSet<>(); - for (TestRunEntity testRunEntity : testRunEntityMap.values()) { - passCount += testRunEntity.getPassCount(); - failCount += testRunEntity.getFailCount(); - if (startTimestamp < 0 || testRunEntity.getStartTimestamp() < startTimestamp) { - startTimestamp = testRunEntity.getStartTimestamp(); - } - if (endTimestamp < 0 || testRunEntity.getEndTimestamp() > endTimestamp) { - endTimestamp = testRunEntity.getEndTimestamp(); - } - testType = testRunEntity.getType(); - testBuildId = testRunEntity.getTestBuildId(); - - List<DeviceInfoEntity> deviceInfoEntityListWithTestRunKey = - ofy().load() - .type(DeviceInfoEntity.class) - .ancestor(testRunEntity.getOfyKey()) - .list(); - - for (DeviceInfoEntity deviceInfoEntity : deviceInfoEntityListWithTestRunKey) { - deviceInfoEntitySet.add(deviceInfoEntity); - } - } - - if (startTimestamp < 0 || testBuildId == null || testType == -1) { - log.debug("startTimestamp => " + startTimestamp); - log.debug("testBuildId => " + testBuildId); - log.debug("type => " + testType); - log.error("Couldn't infer test run information from runs."); - return; - } - - TestPlanRunEntity testPlanRunEntity = - new TestPlanRunEntity( - testPlanEntity.getKey(), - testPlanName, - testType, - startTimestamp, - endTimestamp, - testBuildId, - passCount, - failCount, - 0L, - 0L, - testRunKeyList); - - // Create the device infos. - for (DeviceInfoEntity device : deviceInfoEntitySet) { - deviceInfoEntityList.add(device.copyWithParent(testPlanRunEntity.getOfyKey())); - } - - // Process global HAL API coverage data - for (VtsReportMessage.ApiCoverageReportMessage apiCoverage : report.getHalApiReportList()) { - VtsReportMessage.HalInterfaceMessage halInterfaceMessage = - apiCoverage.getHalInterface(); - List<String> halApiList = - apiCoverage - .getHalApiList() - .stream() - .map(h -> h.toStringUtf8()) - .collect(Collectors.toList()); - List<String> coveredHalApiList = - apiCoverage - .getCoveredHalApiList() - .stream() - .map(h -> h.toStringUtf8()) - .collect(Collectors.toList()); - HalApiEntity halApiEntity = - new HalApiEntity( - testPlanRunEntity.getOfyKey(), - halInterfaceMessage.getHalReleaseLevel().toStringUtf8(), - halInterfaceMessage.getHalPackageName().toStringUtf8(), - halInterfaceMessage.getHalVersionMajor(), - halInterfaceMessage.getHalVersionMinor(), - halInterfaceMessage.getHalInterfaceName().toStringUtf8(), - halApiList, - coveredHalApiList); - halApiEntityList.add(halApiEntity); - } - - ofy().transact( - () -> { - testPlanEntity.save(); - testPlanRunEntity.save(); - for (Object entity : allEntityList) { - List<DashboardEntity> dashboardEntityList = - (List<DashboardEntity>) entity; - Map<com.googlecode.objectify.Key<DashboardEntity>, DashboardEntity> - mapInfo = - DashboardEntity.saveAll( - dashboardEntityList, - this.MAX_ENTITY_SIZE_PER_TRANSACTION); - } - }); - - // Add the task to calculate total number API list. - testPlanRunEntity.addCoverageApiTask(); - } -} diff --git a/src/main/java/com/android/vts/api/TestAcknowledgmentRestServlet.java b/src/main/java/com/android/vts/api/TestAcknowledgmentRestServlet.java deleted file mode 100644 index 309c3e2..0000000 --- a/src/main/java/com/android/vts/api/TestAcknowledgmentRestServlet.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * 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. - */ - -package com.android.vts.api; - -import com.android.vts.entity.TestAcknowledgmentEntity; -import com.android.vts.util.DatastoreHelper; -import com.google.appengine.api.datastore.DatastoreFailureException; -import com.google.appengine.api.datastore.DatastoreService; -import com.google.appengine.api.datastore.DatastoreServiceFactory; -import com.google.appengine.api.datastore.DatastoreTimeoutException; -import com.google.appengine.api.datastore.Entity; -import com.google.appengine.api.datastore.Key; -import com.google.appengine.api.datastore.KeyFactory; -import com.google.appengine.api.datastore.Query; -import com.google.appengine.api.datastore.Transaction; -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 com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.ConcurrentModificationException; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** Servlet for handling requests to fetch test acknowledgments. */ -public class TestAcknowledgmentRestServlet extends HttpServlet { - protected static final Logger logger = - Logger.getLogger(TestAcknowledgmentRestServlet.class.getName()); - - /** Read all test acknowledgments. */ - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); - - Query ackQuery = new Query(TestAcknowledgmentEntity.KIND); - List<JsonObject> testAcks = new ArrayList<>(); - for (Entity ackEntity : - datastore.prepare(ackQuery).asIterable(DatastoreHelper.getLargeBatchOptions())) { - TestAcknowledgmentEntity ack = TestAcknowledgmentEntity.fromEntity(ackEntity); - if (ack == null) continue; - testAcks.add(ack.toJson()); - } - response.setContentType("application/json"); - PrintWriter writer = response.getWriter(); - writer.print(new Gson().toJson(testAcks)); - writer.flush(); - } - - /** Create a test acknowledgment. */ - @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws IOException { - UserService userService = UserServiceFactory.getUserService(); - if (!userService.isUserAdmin()) { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - return; - } - User currentUser = userService.getCurrentUser(); - DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); - - StringBuilder sb = new StringBuilder(); - BufferedReader br = new BufferedReader(request.getReader()); - String str; - while ((str = br.readLine()) != null) { - sb.append(str); - } - JsonObject json; - try { - json = new JsonParser().parse(sb.toString()).getAsJsonObject(); - } catch (IllegalStateException e) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - return; - } - TestAcknowledgmentEntity ack = TestAcknowledgmentEntity.fromJson(currentUser, json); - Transaction txn = datastore.beginTransaction(); - try { - Key key = datastore.put(ack.toEntity()); - txn.commit(); - - response.setContentType("application/json"); - PrintWriter writer = response.getWriter(); - writer.print(new Gson().toJson(KeyFactory.keyToString(key))); - writer.flush(); - } catch (ConcurrentModificationException - | DatastoreFailureException - | DatastoreTimeoutException e) { - txn.rollback(); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - return; - } finally { - if (txn.isActive()) { - logger.log(Level.WARNING, "Transaction rollback forced acknowledgment post."); - txn.rollback(); - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - return; - } - } - response.setStatus(HttpServletResponse.SC_OK); - } - - /** Remove a test acknowledgment. */ - @Override - public void doDelete(HttpServletRequest request, HttpServletResponse response) - throws IOException { - UserService userService = UserServiceFactory.getUserService(); - if (!userService.isUserAdmin()) { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - return; - } - DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); - String stringKey = request.getPathInfo(); - if (stringKey == null) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - return; - } - if (stringKey.startsWith("/")) { - stringKey = stringKey.substring(1); - } - Key key = KeyFactory.stringToKey(stringKey); - if (!key.getKind().equals(TestAcknowledgmentEntity.KIND)) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - return; - } - datastore.delete(key); - response.setStatus(HttpServletResponse.SC_OK); - } -} diff --git a/src/main/java/com/android/vts/api/TestDataForDevServlet.java b/src/main/java/com/android/vts/api/TestDataForDevServlet.java deleted file mode 100644 index 2ed387b..0000000 --- a/src/main/java/com/android/vts/api/TestDataForDevServlet.java +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Copyright (c) 2017 Google Inc. 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. - */ - -package com.android.vts.api; - -import com.android.vts.entity.BranchEntity; -import com.android.vts.entity.BuildTargetEntity; -import com.android.vts.entity.CodeCoverageEntity; -import com.android.vts.entity.CoverageEntity; -import com.android.vts.entity.DeviceInfoEntity; -import com.android.vts.entity.ProfilingPointRunEntity; -import com.android.vts.entity.TestCaseRunEntity; -import com.android.vts.entity.TestEntity; -import com.android.vts.entity.TestPlanEntity; -import com.android.vts.entity.TestPlanRunEntity; -import com.android.vts.entity.TestRunEntity; -import com.android.vts.entity.TestStatusEntity; -import com.android.vts.entity.TestStatusEntity.TestCaseReference; -import com.android.vts.entity.TestSuiteFileEntity; -import com.android.vts.entity.TestSuiteResultEntity; -import com.google.appengine.api.datastore.DatastoreFailureException; -import com.google.appengine.api.datastore.DatastoreService; -import com.google.appengine.api.datastore.DatastoreServiceFactory; -import com.google.appengine.api.datastore.DatastoreTimeoutException; -import com.google.appengine.api.datastore.Entity; -import com.google.appengine.api.datastore.EntityNotFoundException; -import com.google.appengine.api.datastore.Key; -import com.google.appengine.api.datastore.KeyFactory; -import com.google.appengine.api.datastore.Query; -import com.google.appengine.api.datastore.Transaction; -import com.google.appengine.api.users.User; -import com.google.appengine.api.users.UserService; -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; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.ConcurrentModificationException; -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; -import javax.servlet.http.HttpServletResponse; - -/** Servlet for handling requests to add mock data in datastore. */ -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 String GCS_SUITE_TEST_FOLDER_NAME; - - /** datastore instance to save the test data into datastore through datastore library. */ - private DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); - /** - * Gson is a Java library that can be used to convert Java Objects into their JSON - * representation. It can also be used to convert a JSON string to an equivalent Java object. - */ - 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 - */ - private class TestReportDataObject { - private List<Test> testList; - - private class Test { - private List<TestRun> testRunList; - - private class TestRun { - private String testName; - private int type; - private long startTimestamp; - private long endTimestamp; - private String testBuildId; - private String hostName; - private long passCount; - private long failCount; - private boolean hasCoverage; - private long coveredLineCount; - private long totalLineCount; - private List<Long> testCaseIds; - private List<Long> failingTestcaseIds; - private List<Integer> failingTestcaseOffsets; - private List<String> links; - - private List<Coverage> coverageList; - private List<Profiling> profilingList; - private List<TestCaseRun> testCaseRunList; - private List<DeviceInfo> deviceInfoList; - private List<BuildTarget> buildTargetList; - private List<Branch> branchList; - - private class Coverage { - private String group; - private long coveredLineCount; - private long totalLineCount; - private String filePath; - private String projectName; - private String projectVersion; - private List<Long> lineCoverage; - } - - private class Profiling { - private String name; - private int type; - private int regressionMode; - private List<String> labels; - private List<Long> values; - private String xLabel; - private String yLabel; - private List<String> options; - } - - private class TestCaseRun { - private List<String> testCaseNames; - private List<Integer> results; - } - - private class DeviceInfo { - private String branch; - private String product; - private String buildFlavor; - private String buildId; - private String abiBitness; - private String abiName; - } - - private class BuildTarget { - private String targetName; - } - - private class Branch { - private String branchName; - } - } - } - - @Override - public String toString() { - return "(" + testList + ")"; - } - } - - private class TestPlanReportDataObject { - private List<TestPlan> testPlanList; - - private class TestPlan { - - private String testPlanName; - private List<String> testModules; - private List<Long> testTimes; - } - - @Override - public String toString() { - return "(" + testPlanList + ")"; - } - } - - private Map<String, Object> generateSuiteTestData( - HttpServletRequest request, HttpServletResponse response) { - Map<String, Object> resultMap = new HashMap<>(); - String fileSeparator = FileSystems.getDefault().getSeparator(); - Random rand = new Random(); - List<String> branchList = Arrays.asList("master", "oc_mr", "oc"); - List<String> targetList = - Arrays.asList( - "sailfish-userdebug", - "marlin-userdebug", - "taimen-userdebug", - "walleye-userdebug", - "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()); - - 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(newTestSuiteFileEntity); - }))); - resultMap.put("result", "successfully generated!"); - return resultMap; - } - - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - String requestUri = request.getRequestURI(); - String requestArgs = request.getQueryString(); - - Map<String, Object> resultMap = new HashMap<>(); - String pathInfo = requestUri.replace("/api/test_data/", ""); - switch (pathInfo) { - case "suite": - resultMap = this.generateSuiteTestData(request, response); - break; - default: - throw new IllegalArgumentException("Invalid path info of URL"); - } - - String json = new Gson().toJson(resultMap); - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("application/json"); - response.setCharacterEncoding("UTF-8"); - response.getWriter().write(json); - } - - /** Add mock data to local dev datastore. */ - @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws IOException { - if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production) { - response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE); - return; - } - - UserService userService = UserServiceFactory.getUserService(); - User currentUser = userService.getCurrentUser(); - - String pathInfo = request.getPathInfo(); - String[] pathParts = pathInfo.split("/"); - if (pathParts.length > 1) { - // Read the json output - Reader postJsonReader = new InputStreamReader(request.getInputStream()); - Gson gson = new GsonBuilder().create(); - - String testType = pathParts[1]; - if (testType.equalsIgnoreCase("report")) { - TestReportDataObject trdObj = - gson.fromJson(postJsonReader, TestReportDataObject.class); - logger.log(Level.INFO, "trdObj => " + trdObj); - trdObj.testList.forEach( - test -> { - test.testRunList.forEach( - testRun -> { - TestEntity testEntity = new TestEntity(testRun.testName); - - Key testRunKey = - KeyFactory.createKey( - testEntity.getOldKey(), - TestRunEntity.KIND, - testRun.startTimestamp); - - List<TestCaseReference> failingTestCases = - new ArrayList<>(); - for (int idx = 0; - idx < testRun.failingTestcaseIds.size(); - idx++) { - failingTestCases.add( - new TestCaseReference( - testRun.failingTestcaseIds.get(idx), - testRun.failingTestcaseOffsets.get( - idx))); - } - - TestStatusEntity testStatusEntity = - new TestStatusEntity( - testRun.testName, - testRun.startTimestamp, - (int) testRun.passCount, - failingTestCases.size(), - failingTestCases); - datastore.put(testStatusEntity.toEntity()); - - testRun.coverageList.forEach( - testRunCoverage -> { - CoverageEntity coverageEntity = - new CoverageEntity( - testRunKey, - testRunCoverage.group, - testRunCoverage - .coveredLineCount, - testRunCoverage.totalLineCount, - testRunCoverage.filePath, - testRunCoverage.projectName, - testRunCoverage.projectVersion, - testRunCoverage.lineCoverage); - datastore.put(coverageEntity.toEntity()); - }); - - testRun.profilingList.forEach( - testRunProfile -> { - ProfilingPointRunEntity profilingEntity = - new ProfilingPointRunEntity( - testRunKey, - testRunProfile.name, - testRunProfile.type, - testRunProfile.regressionMode, - testRunProfile.labels, - testRunProfile.values, - testRunProfile.xLabel, - testRunProfile.yLabel, - testRunProfile.options); - datastore.put(profilingEntity.toEntity()); - }); - - TestCaseRunEntity testCaseEntity = new TestCaseRunEntity(); - testRun.testCaseRunList.forEach( - testCaseRun -> { - for (int idx = 0; - idx < testCaseRun.testCaseNames.size(); - idx++) { - testCaseEntity.addTestCase( - testCaseRun.testCaseNames.get(idx), - testCaseRun.results.get(idx)); - } - }); - datastore.put(testCaseEntity.toEntity()); - - testRun.deviceInfoList.forEach( - deviceInfo -> { - DeviceInfoEntity deviceInfoEntity = - new DeviceInfoEntity( - testRunKey, - deviceInfo.branch, - deviceInfo.product, - deviceInfo.buildFlavor, - deviceInfo.buildId, - deviceInfo.abiBitness, - deviceInfo.abiName); - ; - datastore.put(deviceInfoEntity.toEntity()); - }); - - testRun.buildTargetList.forEach( - buildTarget -> { - BuildTargetEntity buildTargetEntity = - new BuildTargetEntity( - buildTarget.targetName); - buildTargetEntity.save(); - }); - - testRun.branchList.forEach( - branch -> { - BranchEntity branchEntity = - new BranchEntity(branch.branchName); - branchEntity.save(); - }); - - boolean hasCodeCoverage = - testRun.totalLineCount > 0 - && testRun.coveredLineCount >= 0; - TestRunEntity testRunEntity = - new TestRunEntity( - testEntity.getOldKey(), - testRun.type, - testRun.startTimestamp, - testRun.endTimestamp, - testRun.testBuildId, - testRun.hostName, - testRun.passCount, - testRun.failCount, - hasCodeCoverage, - testRun.testCaseIds, - testRun.links); - datastore.put(testRunEntity.toEntity()); - - CodeCoverageEntity codeCoverageEntity = - new CodeCoverageEntity( - testRunEntity.getKey(), - testRun.coveredLineCount, - testRun.totalLineCount); - datastore.put(codeCoverageEntity.toEntity()); - - Entity newTestEntity = testEntity.toEntity(); - - Transaction txn = datastore.beginTransaction(); - try { - // Check if test already exists in the datastore - try { - Entity oldTest = - datastore.get(testEntity.getOldKey()); - TestEntity oldTestEntity = - TestEntity.fromEntity(oldTest); - if (oldTestEntity == null - || !oldTestEntity.equals(testEntity)) { - datastore.put(newTestEntity); - } - } catch (EntityNotFoundException e) { - datastore.put(newTestEntity); - } - txn.commit(); - - } catch (ConcurrentModificationException - | DatastoreFailureException - | DatastoreTimeoutException e) { - logger.log( - Level.WARNING, - "Retrying test run insert: " - + newTestEntity.getKey()); - } finally { - if (txn.isActive()) { - logger.log( - Level.WARNING, - "Transaction rollback forced for run: " - + testRunEntity.getKey()); - txn.rollback(); - } - } - }); - }); - } else { - TestPlanReportDataObject tprdObj = - gson.fromJson(postJsonReader, TestPlanReportDataObject.class); - tprdObj.testPlanList.forEach( - testPlan -> { - Entity testPlanEntity = - new TestPlanEntity(testPlan.testPlanName).toEntity(); - List<Key> testRunKeys = new ArrayList<>(); - for (int idx = 0; idx < testPlan.testModules.size(); idx++) { - String test = testPlan.testModules.get(idx); - long time = testPlan.testTimes.get(idx); - Key parentKey = KeyFactory.createKey(TestEntity.KIND, test); - Key testRunKey = - KeyFactory.createKey(parentKey, TestRunEntity.KIND, time); - testRunKeys.add(testRunKey); - } - Map<Key, Entity> testRuns = datastore.get(testRunKeys); - long passCount = 0; - long failCount = 0; - long startTimestamp = -1; - long endTimestamp = -1; - String testBuildId = null; - long type = 0; - Set<DeviceInfoEntity> devices = new HashSet<>(); - for (Key testRunKey : testRuns.keySet()) { - TestRunEntity testRun = - TestRunEntity.fromEntity(testRuns.get(testRunKey)); - if (testRun == null) { - continue; // not a valid test run - } - passCount += testRun.getPassCount(); - failCount += testRun.getFailCount(); - if (startTimestamp < 0 || testRunKey.getId() < startTimestamp) { - startTimestamp = testRunKey.getId(); - } - if (endTimestamp < 0 || testRun.getEndTimestamp() > endTimestamp) { - endTimestamp = testRun.getEndTimestamp(); - } - type = testRun.getType(); - testBuildId = testRun.getTestBuildId(); - Query deviceInfoQuery = - new Query(DeviceInfoEntity.KIND).setAncestor(testRunKey); - for (Entity deviceInfoEntity : - datastore.prepare(deviceInfoQuery).asIterable()) { - DeviceInfoEntity device = - DeviceInfoEntity.fromEntity(deviceInfoEntity); - if (device == null) { - continue; // invalid entity - } - devices.add(device); - } - } - if (startTimestamp < 0 || testBuildId == null || type == 0) { - logger.log( - Level.WARNING, - "Couldn't infer test run information from runs."); - return; - } - TestPlanRunEntity testPlanRun = - new TestPlanRunEntity( - testPlanEntity.getKey(), - testPlan.testPlanName, - type, - startTimestamp, - endTimestamp, - testBuildId, - passCount, - failCount, - 0L, - 0L, - testRunKeys); - - // Create the device infos. - for (DeviceInfoEntity device : devices) { - datastore.put( - device.copyWithParent(testPlanRun.getOfyKey()).toEntity()); - } - datastore.put(testPlanRun.toEntity()); - - Transaction txn = datastore.beginTransaction(); - try { - // Check if test already exists in the database - try { - datastore.get(testPlanEntity.getKey()); - } catch (EntityNotFoundException e) { - datastore.put(testPlanEntity); - } - txn.commit(); - } catch (ConcurrentModificationException - | DatastoreFailureException - | DatastoreTimeoutException e) { - logger.log( - Level.WARNING, - "Retrying test plan insert: " + testPlanEntity.getKey()); - } finally { - if (txn.isActive()) { - logger.log( - Level.WARNING, - "Transaction rollback forced for plan run: " - + testPlanRun.key); - txn.rollback(); - } - } - }); - } - } else { - logger.log(Level.WARNING, "URL path parameter is omitted!"); - } - - response.setStatus(HttpServletResponse.SC_OK); - } -} diff --git a/src/main/java/com/android/vts/api/TestRunRestServlet.java b/src/main/java/com/android/vts/api/TestRunRestServlet.java deleted file mode 100644 index 90fd3f9..0000000 --- a/src/main/java/com/android/vts/api/TestRunRestServlet.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2017 Google Inc. 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. - */ - -package com.android.vts.api; - -import com.android.vts.entity.TestCaseRunEntity; -import com.android.vts.entity.TestEntity; -import com.android.vts.entity.TestRunEntity; -import com.android.vts.util.TestRunDetails; -import com.google.gson.Gson; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.logging.Logger; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import static com.googlecode.objectify.ObjectifyService.ofy; - -/** Servlet for handling requests to fetch test case results. */ -public class TestRunRestServlet extends BaseApiServlet { - private static final String LATEST = "latest"; - protected static final Logger logger = Logger.getLogger(TestRunRestServlet.class.getName()); - - /** - * Get the test case results for the specified run of the specified test. - * - * @param test The test whose test cases to get. - * @param timeString The string representation of the test run timestamp (in microseconds). - * @return A TestRunDetails object with the test case details for the specified run. - */ - private TestRunDetails getTestRunDetails(String test, String timeString) { - long timestamp; - try { - timestamp = Long.parseLong(timeString); - if (timestamp <= 0) throw new NumberFormatException(); - timestamp = timestamp > 0 ? timestamp : null; - } catch (NumberFormatException e) { - return null; - } - - TestRunEntity testRunEntity = TestRunEntity.getByTestNameId(test, timestamp); - - return getTestRunDetails(testRunEntity); - } - - /** - * Get the test case results for the latest run of the specified test. - * - * @param testName The test whose test cases to get. - * @return A TestRunDetails object with the test case details for the latest run. - */ - private TestRunDetails getLatestTestRunDetails(String testName) { - com.googlecode.objectify.Key testKey = - com.googlecode.objectify.Key.create( - TestEntity.class, testName); - - TestRunEntity testRun = ofy().load().type(TestRunEntity.class).ancestor(testKey) - .filter("type", 2).orderKey(true).first().now(); - - if (testRun == null) return null; - - return getTestRunDetails(testRun); - } - - /** - * Get TestRunDetails instance from codeCoverageEntity instance. - * - * @param testRunEntity The TestRunEntity to access testCaseId. - * @return A TestRunDetails object with the test case details for the latest run. - */ - private TestRunDetails getTestRunDetails(TestRunEntity testRunEntity) { - TestRunDetails details = new TestRunDetails(); - List<com.googlecode.objectify.Key<TestCaseRunEntity>> testCaseKeyList = new ArrayList<>(); - if ( Objects.isNull(testRunEntity.getTestCaseIds()) ) { - return details; - } else { - for (long testCaseId : testRunEntity.getTestCaseIds()) { - testCaseKeyList.add( - com.googlecode.objectify.Key.create(TestCaseRunEntity.class, testCaseId)); - } - Map<com.googlecode.objectify.Key<TestCaseRunEntity>, TestCaseRunEntity> - testCaseRunEntityKeyMap = ofy().load().keys(() -> testCaseKeyList.iterator()); - testCaseRunEntityKeyMap.forEach((key, value) -> details.addTestCase(value)); - } - return details; - } - - /** - * Get the test case details for a test run. - * - * Expected format: (1) /api/test_run?test=[test name]×tamp=[timestamp] to the details - * for a specific run, or (2) /api/test_run?test=[test name]×tamp=latest -- the details for - * the latest test run. - */ - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - String test = request.getParameter("test"); - String timeString = request.getParameter("timestamp"); - TestRunDetails details = null; - - if (timeString != null && timeString.equals(LATEST)) { - details = getLatestTestRunDetails(test); - } else if (timeString != null) { - details = getTestRunDetails(test, timeString); - } - - if (details == null) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - } else { - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("application/json"); - PrintWriter writer = response.getWriter(); - writer.print(new Gson().toJson(details.toJson())); - writer.flush(); - } - } -} diff --git a/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java b/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java deleted file mode 100644 index 38be2c0..0000000 --- a/src/main/java/com/android/vts/api/TestSuiteResultRestServlet.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2018 Google Inc. 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. - */ - -package com.android.vts.api; - -import com.android.vts.entity.TestSuiteFileEntity; -import com.android.vts.entity.TestSuiteResultEntity; -import com.android.vts.proto.TestSuiteResultMessageProto; -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.gson.Gson; -import com.googlecode.objectify.Key; -import org.apache.commons.codec.binary.Base64; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; - -/** REST endpoint for posting test suite data to the Dashboard. */ -public class TestSuiteResultRestServlet extends BaseApiServlet { - private static String SERVICE_CLIENT_ID; - private static final String SERVICE_NAME = "VTS Dashboard"; - private static final Logger logger = - Logger.getLogger(TestSuiteResultRestServlet.class.getName()); - - @Override - public void init(ServletConfig cfg) throws ServletException { - super.init(cfg); - - SERVICE_CLIENT_ID = systemConfigProp.getProperty("appengine.serviceClientID"); - } - - @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws IOException { - // Retrieve the params - TestSuiteResultMessageProto.TestSuiteResultMessage testSuiteResultMessage; - try { - String payload = request.getReader().lines().collect(Collectors.joining()); - byte[] value = Base64.decodeBase64(payload); - testSuiteResultMessage = - TestSuiteResultMessageProto.TestSuiteResultMessage.parseFrom(value); - } catch (IOException e) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - logger.log(Level.WARNING, "Invalid proto: " + e.getLocalizedMessage()); - return; - } - - Map<String, Object> resultMap = new HashMap<>(); - // Verify service account access token. - if (testSuiteResultMessage.hasAccessToken()) { - String accessToken = testSuiteResultMessage.getAccessToken(); - logger.log(Level.INFO, "accessToken => " + accessToken); - GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken); - Oauth2 oauth2 = - new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credential) - .setApplicationName(SERVICE_NAME) - .build(); - Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute(); - - if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) { - String filePath = "suite_result/2019/04/06/132343.bin"; - Key<TestSuiteFileEntity> testSuiteFileParent = - Key.create(TestSuiteFileEntity.class, filePath); - TestSuiteFileEntity newTestSuiteFileEntity = new TestSuiteFileEntity(filePath); - TestSuiteResultEntity testSuiteResultEntity = - new TestSuiteResultEntity( - testSuiteFileParent, - testSuiteResultMessage.getStartTime(), - testSuiteResultMessage.getEndTime(), - testSuiteResultMessage.getTestType(), - testSuiteResultMessage.getBootSuccess(), - testSuiteResultMessage.getResultPath(), - testSuiteResultMessage.getInfraLogPath(), - testSuiteResultMessage.getHostName(), - testSuiteResultMessage.getSuitePlan(), - testSuiteResultMessage.getSuiteVersion(), - testSuiteResultMessage.getSuiteName(), - testSuiteResultMessage.getSuiteBuildNumber(), - testSuiteResultMessage.getModulesDone(), - testSuiteResultMessage.getModulesTotal(), - testSuiteResultMessage.getBranch(), - testSuiteResultMessage.getTarget(), - testSuiteResultMessage.getBuildId(), - testSuiteResultMessage.getBuildSystemFingerprint(), - testSuiteResultMessage.getBuildVendorFingerprint(), - testSuiteResultMessage.getPassedTestCaseCount(), - testSuiteResultMessage.getFailedTestCaseCount()); - - testSuiteResultEntity.save(newTestSuiteFileEntity); - resultMap.put("result", "successfully saved!"); - } else { - logger.log(Level.WARNING, "service_client_id didn't match!"); - logger.log(Level.INFO, "SERVICE_CLIENT_ID => " + tokenInfo.getIssuedTo()); - resultMap.put("result", "Wrong Service Client ID!"); - } - } else { - logger.log(Level.WARNING, "postMessage do not contain any accessToken!"); - resultMap.put("result", "Access Token Missing!"); - } - String json = new Gson().toJson(resultMap); - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("application/json"); - response.setCharacterEncoding("UTF-8"); - response.getWriter().write(json); - } -} diff --git a/src/main/java/com/android/vts/api/UserFavoriteRestServlet.java b/src/main/java/com/android/vts/api/UserFavoriteRestServlet.java deleted file mode 100644 index 30fd649..0000000 --- a/src/main/java/com/android/vts/api/UserFavoriteRestServlet.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2017 Google Inc. 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. - */ - -package com.android.vts.api; - -import com.android.vts.entity.TestEntity; -import com.android.vts.entity.UserFavoriteEntity; -import com.google.appengine.api.datastore.DatastoreService; -import com.google.appengine.api.datastore.DatastoreServiceFactory; -import com.google.appengine.api.datastore.Entity; -import com.google.appengine.api.datastore.EntityNotFoundException; -import com.google.appengine.api.datastore.Key; -import com.google.appengine.api.datastore.KeyFactory; -import com.google.appengine.api.datastore.Query; -import com.google.appengine.api.datastore.Query.CompositeFilterOperator; -import com.google.appengine.api.datastore.Query.Filter; -import com.google.appengine.api.datastore.Query.FilterOperator; -import com.google.appengine.api.datastore.Query.FilterPredicate; -import com.google.appengine.api.datastore.Transaction; -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 com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** Servlet for handling requests to add or remove subscriptions. */ -public class UserFavoriteRestServlet extends BaseApiServlet { - protected static final Logger logger = - Logger.getLogger(UserFavoriteRestServlet.class.getName()); - - /** - * Add a new favorite entity. - * - * @param user The user for which to add a favorite. - * @param test The name of the test. - * @param muteNotifications True if the subscriber has muted notifications, false otherwise. - * @param response The servlet response object. - * @return a json object with the generated key to the new favorite entity. - * @throws IOException - */ - private static JsonObject addFavorite( - User user, String test, boolean muteNotifications, HttpServletResponse response) - throws IOException { - DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); - Key addedTestKey = KeyFactory.createKey(TestEntity.KIND, test); - // Filter the tests that exist from the set of tests to add - try { - datastore.get(addedTestKey); - } catch (EntityNotFoundException e) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - return null; - } - - Filter userFilter = - new FilterPredicate(UserFavoriteEntity.USER, FilterOperator.EQUAL, user); - Filter testFilter = - new FilterPredicate( - UserFavoriteEntity.TEST_KEY, FilterOperator.EQUAL, addedTestKey); - Query q = - new Query(UserFavoriteEntity.KIND) - .setFilter(CompositeFilterOperator.and(userFilter, testFilter)) - .setKeysOnly(); - - Key favoriteKey = null; - - Transaction txn = datastore.beginTransaction(); - try { - for (Entity e : datastore.prepare(q).asIterable()) { - favoriteKey = e.getKey(); - break; - } - if (favoriteKey == null) { - UserFavoriteEntity favorite = - new UserFavoriteEntity(user, addedTestKey, muteNotifications); - Entity entity = favorite.toEntity(); - datastore.put(entity); - favoriteKey = entity.getKey(); - } - txn.commit(); - } finally { - if (txn.isActive()) { - logger.log( - Level.WARNING, - "Transaction rollback forced for favorite creation: " + test); - txn.rollback(); - } - } - JsonObject json = new JsonObject(); - json.add("key", new JsonPrimitive(KeyFactory.keyToString(favoriteKey))); - return json; - } - - /** - * @param user The user for which to add a favorite. - * @param favoriteKey The database key to the favorite entity to update. - * @param muteNotifications True if the subscriber has muted notifications, false otherwise. - * @param response The servlet response object. - * @return a json object with the generated key to the new favorite entity. - * @throws IOException - */ - private static JsonObject updateFavorite( - User user, Key favoriteKey, boolean muteNotifications, HttpServletResponse response) - throws IOException { - DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); - Entity favoriteEntity; - try { - favoriteEntity = datastore.get(favoriteKey); - } catch (EntityNotFoundException e) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - return null; - } - UserFavoriteEntity favorite = UserFavoriteEntity.fromEntity(favoriteEntity); - if (favorite.user.getUserId() == user.getUserId()) { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - return null; - } - if (favorite.muteNotifications != muteNotifications) { - Transaction txn = datastore.beginTransaction(); - try { - favorite.muteNotifications = muteNotifications; - datastore.put(favorite.toEntity()); - txn.commit(); - } finally { - if (txn.isActive()) { - logger.log( - Level.WARNING, - "Transaction rollback forced for favorite update: " + favoriteKey); - txn.rollback(); - } - } - } - JsonObject json = new JsonObject(); - json.add("key", new JsonPrimitive(KeyFactory.keyToString(favoriteKey))); - return json; - } - - /** Add a test to the user's favorites. */ - @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws IOException { - UserService userService = UserServiceFactory.getUserService(); - User currentUser = userService.getCurrentUser(); - - boolean muteNotifications = false; - if (request.getParameter(UserFavoriteEntity.MUTE_NOTIFICATIONS) != null) { - muteNotifications = - Boolean.parseBoolean( - request.getParameter(UserFavoriteEntity.MUTE_NOTIFICATIONS)); - } - - String userFavoritesKeyString = request.getParameter("userFavoritesKey"); - String testName = request.getParameter("testName"); - - JsonObject returnData = null; - if (userFavoritesKeyString != null) { - Key userFavoritesKey = KeyFactory.stringToKey(userFavoritesKeyString); - returnData = updateFavorite(currentUser, userFavoritesKey, muteNotifications, response); - } else if (testName != null) { - returnData = addFavorite(currentUser, testName, muteNotifications, response); - } - - if (returnData != null) { - response.setContentType("application/json"); - PrintWriter writer = response.getWriter(); - writer.print(new Gson().toJson(returnData)); - writer.flush(); - } - } - - /** Remove a test from the user's favorites. */ - @Override - public void doDelete(HttpServletRequest request, HttpServletResponse response) - throws IOException { - DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); - String stringKey = request.getPathInfo(); - if (stringKey == null) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - return; - } - if (stringKey.startsWith("/")) { - stringKey = stringKey.substring(1); - } - datastore.delete(KeyFactory.stringToKey(stringKey)); - response.setStatus(HttpServletResponse.SC_OK); - } -} |