1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you 5 * may not use this file except in compliance with the License. You may 6 * obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 * implied. See the License for the specific language governing 14 * permissions and limitations under the License. 15 */ 16 17 package com.android.vts.config; 18 19 import com.android.vts.entity.ApiCoverageEntity; 20 import com.android.vts.entity.BranchEntity; 21 import com.android.vts.entity.BuildTargetEntity; 22 import com.android.vts.entity.ApiCoverageExcludedEntity; 23 import com.android.vts.entity.CodeCoverageEntity; 24 import com.android.vts.entity.CoverageEntity; 25 import com.android.vts.entity.DeviceInfoEntity; 26 import com.android.vts.entity.HalApiEntity; 27 import com.android.vts.entity.ProfilingPointEntity; 28 import com.android.vts.entity.ProfilingPointRunEntity; 29 import com.android.vts.entity.ProfilingPointSummaryEntity; 30 import com.android.vts.entity.RoleEntity; 31 import com.android.vts.entity.TestAcknowledgmentEntity; 32 import com.android.vts.entity.TestCaseRunEntity; 33 import com.android.vts.entity.TestCoverageStatusEntity; 34 import com.android.vts.entity.TestEntity; 35 import com.android.vts.entity.TestPlanEntity; 36 import com.android.vts.entity.TestPlanRunEntity; 37 import com.android.vts.entity.TestRunEntity; 38 import com.android.vts.entity.TestStatusEntity; 39 import com.android.vts.entity.TestSuiteFileEntity; 40 import com.android.vts.entity.TestSuiteResultEntity; 41 import com.android.vts.entity.UserEntity; 42 import com.google.api.client.extensions.appengine.datastore.AppEngineDataStoreFactory; 43 import com.google.api.services.sheets.v4.SheetsScopes; 44 import com.googlecode.objectify.ObjectifyService; 45 46 import java.util.Arrays; 47 import java.util.Collections; 48 import java.util.List; 49 import java.util.Optional; 50 import java.util.function.Supplier; 51 import java.util.stream.Stream; 52 import javax.servlet.ServletContext; 53 import javax.servlet.ServletContextEvent; 54 import javax.servlet.ServletContextListener; 55 import javax.servlet.annotation.WebListener; 56 import java.io.FileNotFoundException; 57 import java.io.IOException; 58 import java.io.InputStream; 59 import java.util.Properties; 60 import java.util.logging.Level; 61 import java.util.logging.Logger; 62 63 /** The @WebListener annotation for registering a class as a listener of a web application. */ 64 @WebListener 65 /** 66 * Initializing Objectify Service at the container start up before any web components like servlet 67 * get initialized. 68 */ 69 public class ObjectifyListener implements ServletContextListener { 70 71 private static final Logger logger = Logger.getLogger(ObjectifyListener.class.getName()); 72 73 74 /** Global instance of the DataStoreFactory. */ 75 private static final AppEngineDataStoreFactory DATA_STORE_FACTORY = 76 AppEngineDataStoreFactory.getDefaultInstance(); 77 78 /** Global instance of the scopes. */ 79 private static final List<String> GOOGLE_API_SCOPES = 80 Collections.singletonList(SheetsScopes.SPREADSHEETS_READONLY); 81 82 /** 83 * Receives notification that the web application initialization process is starting. This 84 * function will register Entity classes for objectify. 85 */ 86 @Override contextInitialized(ServletContextEvent servletContextEvent)87 public void contextInitialized(ServletContextEvent servletContextEvent) { 88 ObjectifyService.init(); 89 ObjectifyService.register(BranchEntity.class); 90 ObjectifyService.register(BuildTargetEntity.class); 91 92 ObjectifyService.register(HalApiEntity.class); 93 ObjectifyService.register(ApiCoverageEntity.class); 94 ObjectifyService.register(ApiCoverageExcludedEntity.class); 95 ObjectifyService.register(CodeCoverageEntity.class); 96 ObjectifyService.register(CoverageEntity.class); 97 ObjectifyService.register(DeviceInfoEntity.class); 98 ObjectifyService.register(TestCoverageStatusEntity.class); 99 100 ObjectifyService.register(ProfilingPointEntity.class); 101 ObjectifyService.register(ProfilingPointRunEntity.class); 102 ObjectifyService.register(ProfilingPointSummaryEntity.class); 103 104 ObjectifyService.register(TestEntity.class); 105 ObjectifyService.register(TestPlanEntity.class); 106 ObjectifyService.register(TestPlanRunEntity.class); 107 ObjectifyService.register(TestRunEntity.class); 108 ObjectifyService.register(TestCaseRunEntity.class); 109 ObjectifyService.register(TestStatusEntity.class); 110 ObjectifyService.register(TestSuiteFileEntity.class); 111 ObjectifyService.register(TestSuiteResultEntity.class); 112 ObjectifyService.register(TestAcknowledgmentEntity.class); 113 ObjectifyService.register(RoleEntity.class); 114 ObjectifyService.register(UserEntity.class); 115 ObjectifyService.begin(); 116 logger.log(Level.INFO, "Value Initialized from context."); 117 118 Properties systemConfigProp = new Properties(); 119 120 try { 121 InputStream defaultInputStream = 122 ObjectifyListener.class 123 .getClassLoader() 124 .getResourceAsStream("config.properties"); 125 126 systemConfigProp.load(defaultInputStream); 127 128 servletContextEvent 129 .getServletContext() 130 .setAttribute("systemConfigProp", systemConfigProp); 131 servletContextEvent 132 .getServletContext() 133 .setAttribute("dataStoreFactory", DATA_STORE_FACTORY); 134 servletContextEvent 135 .getServletContext() 136 .setAttribute("googleApiScopes", GOOGLE_API_SCOPES); 137 138 String roleList = systemConfigProp.getProperty("user.roleList"); 139 Supplier<Stream<String>> streamSupplier = () -> Arrays.stream(roleList.split(",")); 140 this.createRoles(streamSupplier.get()); 141 142 String adminEmail = systemConfigProp.getProperty("user.adminEmail"); 143 if (adminEmail.isEmpty()) { 144 logger.log(Level.WARNING, "Admin email is not properly set. Check config file"); 145 } else { 146 String adminName = systemConfigProp.getProperty("user.adminName"); 147 String adminCompany = systemConfigProp.getProperty("user.adminCompany"); 148 Optional<String> roleName = 149 streamSupplier.get().filter(r -> r.equals("admin")).findFirst(); 150 this.createAdminUser(adminEmail, adminName, adminCompany, roleName.orElse("admin")); 151 } 152 } catch (FileNotFoundException e) { 153 logger.log(Level.SEVERE, e.getMessage()); 154 } catch (IOException e) { 155 logger.log(Level.SEVERE, e.getMessage()); 156 } 157 } 158 159 /** Receives notification that the ServletContext is about to be shut down. */ 160 @Override contextDestroyed(ServletContextEvent servletContextEvent)161 public void contextDestroyed(ServletContextEvent servletContextEvent) { 162 ServletContext servletContext = servletContextEvent.getServletContext(); 163 logger.log(Level.INFO, "Value deleted from context."); 164 } 165 createRoles(Stream<String> roleStream)166 private void createRoles(Stream<String> roleStream) { 167 roleStream 168 .map(role -> role.trim()) 169 .forEach( 170 roleName -> { 171 RoleEntity roleEntity = new RoleEntity(roleName); 172 roleEntity.save(); 173 }); 174 } 175 createAdminUser(String email, String name, String company, String role)176 private void createAdminUser(String email, String name, String company, String role) { 177 Optional<UserEntity> adminUserEntityOptional = 178 Optional.ofNullable(UserEntity.getAdminUser(email)); 179 if (adminUserEntityOptional.isPresent()) { 180 logger.log(Level.INFO, "The user is already registered."); 181 } else { 182 UserEntity userEntity = new UserEntity(email, name, company, role); 183 userEntity.setIsAdmin(true); 184 userEntity.save(); 185 logger.log(Level.INFO, "The user is saved successfully."); 186 } 187 } 188 } 189