package com.ctrip.platform.dal.daogen.resource; import com.ctrip.platform.dal.daogen.domain.Status; import com.ctrip.platform.dal.daogen.entity.DalGroup; import com.ctrip.platform.dal.daogen.entity.LoginUser; import com.ctrip.platform.dal.daogen.enums.AddUser; import com.ctrip.platform.dal.daogen.enums.DatabaseType; import com.ctrip.platform.dal.daogen.enums.RoleType; import com.ctrip.platform.dal.daogen.utils.Configuration; import com.ctrip.platform.dal.daogen.utils.DataSourceUtil; import com.ctrip.platform.dal.daogen.utils.MD5Util; import com.ctrip.platform.dal.daogen.utils.SpringBeanGetter; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.jdbc.support.JdbcUtils; import javax.annotation.Resource; import javax.inject.Singleton; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import java.io.*; import java.net.URL; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.HashSet; import java.util.Properties; import java.util.Set; @Resource @Singleton @Path("setupDb") public class SetupDBResource { private static final Object LOCK = new Object(); private static ClassLoader classLoader = null; private static ObjectMapper mapper = new ObjectMapper(); private static final java.lang.String WEB_XML = "web.xml"; private static final String JDBC_PROPERTIES = "jdbc.properties"; private static final String JDBC_DRIVER_CLASS_NAME = "jdbc.driverClassName"; private static final String JDBC_URL = "jdbc.url"; private static final String JDBC_USERNAME = "jdbc.username"; private static final String JDBC_PASSWORD = "jdbc.password"; private String jdbcUrlTemplate = "jdbc:mysql://%s:%s/%s"; private static final String SCRIPT_FILE = "script.sql"; private static final String CREATE_TABLE = "CREATE TABLE"; private static boolean initialized = false; private static Boolean jdbcInitialized = null; static { synchronized (LOCK) { classLoader = Thread.currentThread().getContextClassLoader(); if (classLoader == null) { classLoader = Configuration.class.getClassLoader(); } } } public static boolean isJdbcInitialized() { if (jdbcInitialized == null) { synchronized (LOCK) { if (jdbcInitialized == null) { try { jdbcInitialized = resourceExists(JDBC_PROPERTIES) & jdbcPropertiesValid(); } catch (Exception e) { e.printStackTrace(); } } } } return jdbcInitialized.booleanValue(); } @GET @Produces(MediaType.APPLICATION_JSON) @Path("setupDbCheck") public Status setupDbCheck() throws Exception { Status status = Status.OK; if (initialized) { status.setInfo(""); return status; } try { boolean result = resourceExists(JDBC_PROPERTIES); if (result) { boolean valid = jdbcPropertiesValid(); if (!valid) { result = false; status = Status.ERROR; status.setInfo("!valid"); } } else { result = false; status = Status.ERROR; status.setInfo("!jdbc"); } if (result && !initialized) { synchronized (LOCK) { if (!initialized) { initialized = true; jdbcInitialized = true; } } status.setInfo("initialized"); initializeConfig(); } } catch (Exception e) { status = Status.ERROR; status.setInfo(e.getMessage()); } return status; } @POST @Produces(MediaType.APPLICATION_JSON) @Path("tableConsistentCheck") public Status tableConsistentCheck(@FormParam("dbaddress") String dbaddress, @FormParam("dbport") String dbport, @FormParam("dbuser") String dbuser, @FormParam("dbpassword") String dbpassword, @FormParam("dbcatalog") String dbcatalog) { Status status = Status.ERROR; try { boolean jdbcInitialized = initializeJdbcProperties(dbaddress, dbport, dbuser, dbpassword, dbcatalog); if (jdbcInitialized) { boolean result = tableConsistent(dbcatalog); if (result) { status = Status.OK; } boolean flag = clearJdbcProperties(); } } catch (Exception e) { status = Status.ERROR; status.setInfo(e.getMessage()); } return status; } @POST @Produces(MediaType.APPLICATION_JSON) @Path("initializeJdbc") public Status initializeJdbc(@FormParam("dbaddress") String dbaddress, @FormParam("dbport") String dbport, @FormParam("dbuser") String dbuser, @FormParam("dbpassword") String dbpassword, @FormParam("dbcatalog") String dbcatalog) { Status status = Status.OK; try { boolean result = initializeJdbcProperties(dbaddress, dbport, dbuser, dbpassword, dbcatalog); if (!result) { status = Status.ERROR; } } catch (Exception e) { status = Status.ERROR; status.setInfo(e.getMessage()); } return status; } @POST @Produces(MediaType.APPLICATION_JSON) @Path("initializeDb") public Status initializeDb(@Context HttpServletRequest request, @FormParam("dbaddress") String dbaddress, @FormParam("dbport") String dbport, @FormParam("dbuser") String dbuser, @FormParam("dbpassword") String dbpassword, @FormParam("dbcatalog") String dbcatalog, @FormParam("groupName") String groupName, @FormParam("groupComment") String groupComment, @FormParam("adminNo") String adminNo, @FormParam("adminName") String adminName, @FormParam("adminEmail") String adminEmail, @FormParam("adminPass") String adminPass) { Status status = Status.OK; try { boolean jdbcResult = initializeJdbcProperties(dbaddress, dbport, dbuser, dbpassword, dbcatalog); if (!jdbcResult) { status = Status.ERROR; status.setInfo("Error occured while initializing the jdbc.properties file."); return status; } initializeConfig(); //to be deleted boolean isSetupTables = setupTables(); if (!isSetupTables) { status = Status.ERROR; status.setInfo("Error occured while setting up the tables."); return status; } DalGroup group = new DalGroup(); group.setGroup_name(groupName); group.setGroup_comment(groupComment); LoginUser user = new LoginUser(); user.setUserNo(adminNo); user.setUserName(adminName); user.setUserEmail(adminEmail); user.setPassword(MD5Util.parseStrToMd5L32(adminPass)); boolean isSetupAdmin = setupAdmin(group, user); if (!isSetupAdmin) { status = Status.ERROR; status.setInfo("Error occured while setting up the admin."); return status; } } catch (Exception e) { status = Status.ERROR; status.setInfo(e.getMessage()); } return status; } @POST @Produces(MediaType.APPLICATION_JSON) @Path("connectionTest") public Status connectionTest(@FormParam("dbtype") String dbtype, @FormParam("dbaddress") String dbaddress, @FormParam("dbport") String dbport, @FormParam("dbuser") String dbuser, @FormParam("dbpassword") String dbpassword) { Status status = Status.OK; Connection conn = null; ResultSet rs = null; try { conn = DataSourceUtil.getConnection(dbaddress, dbport, dbuser, dbpassword, DatabaseType.valueOf(dbtype).getValue()); rs = conn.getMetaData().getCatalogs(); Set<String> allCatalog = new HashSet<>(); while (rs.next()) { allCatalog.add(rs.getString("TABLE_CAT")); } status.setInfo(mapper.writeValueAsString(allCatalog)); } catch (SQLException e) { status = Status.ERROR; status.setInfo(e.getMessage()); return status; } catch (JsonProcessingException e) { status = Status.ERROR; status.setInfo(e.getMessage()); return status; } finally { JdbcUtils.closeResultSet(rs); JdbcUtils.closeConnection(conn); } return status; } private static boolean resourceExists(String fileName) { boolean result = false; if (fileName == null || fileName.length() == 0) { return result; } URL url = classLoader.getResource(fileName); if (url != null) { result = true; } return result; } private static boolean jdbcPropertiesValid() throws Exception { boolean result = true; Properties properties = new Properties(); InputStream inStream = classLoader.getResourceAsStream(JDBC_PROPERTIES); properties.load(inStream); String driverClassName = properties.getProperty(JDBC_DRIVER_CLASS_NAME); result &= (driverClassName != null && driverClassName.trim().length() > 0); String url = properties.getProperty(JDBC_URL); result &= (url != null && url.trim().length() > 0); String userName = properties.getProperty(JDBC_USERNAME); result &= (userName != null && userName.trim().length() > 0); String password = properties.getProperty(JDBC_PASSWORD); result &= (password != null && password.trim().length() > 0); return result; } private boolean tableConsistent(String catalog) throws Exception { boolean result = false; Set<String> catalogTableNames = SpringBeanGetter.getSetupDBDao().getCatalogTableNames(catalog); if (catalogTableNames == null || catalogTableNames.size() == 0) { return result; } String scriptContent = getScriptContent(SCRIPT_FILE); Set<String> scriptTableNames = getScriptTableNames(scriptContent); result = true; if (scriptTableNames != null && scriptTableNames.size() > 0) { for (String tableName : scriptTableNames) { if (!catalogTableNames.contains(tableName)) { result = false; break; } } } return result; } private Set<String> getScriptTableNames(String script) { Set<String> set = new HashSet<>(); if (script == null || script.length() == 0) { return set; } String[] array = script.toUpperCase().split(";"); for (int i = 0; i < array.length; i++) { int beginIndex = array[i].indexOf(CREATE_TABLE); if (beginIndex == -1) { continue; } beginIndex += CREATE_TABLE.length(); int endIndex = array[i].indexOf("("); String temp = array[i].substring(beginIndex, endIndex); String tableName = temp.replaceAll("`", "").trim(); if (tableName != null && tableName.length() > 0) { set.add(tableName); } } return set; } private boolean initializeJdbcProperties(String dbaddress, String dbport, String dbuser, String dbpassword, String dbcatalog) { boolean result = false; try { Properties properties = new Properties(); properties.setProperty(JDBC_DRIVER_CLASS_NAME, "com.mysql.jdbc.Driver"); // Currently // fixed. properties.setProperty(JDBC_URL, String.format(jdbcUrlTemplate, dbaddress, dbport, dbcatalog)); properties.setProperty(JDBC_USERNAME, dbuser); properties.setProperty(JDBC_PASSWORD, dbpassword); URL url = classLoader.getResource(WEB_XML); String path = url.getPath().replace(WEB_XML, JDBC_PROPERTIES); FileOutputStream fileOutputStream = new FileOutputStream(path); properties.store(fileOutputStream, ""); fileOutputStream.close(); result = true; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } private boolean clearJdbcProperties() { boolean result = false; try { Properties properties = new Properties(); properties.setProperty(JDBC_DRIVER_CLASS_NAME, ""); properties.setProperty(JDBC_URL, ""); properties.setProperty(JDBC_USERNAME, ""); properties.setProperty(JDBC_PASSWORD, ""); URL url = classLoader.getResource(WEB_XML); String path = url.getPath().replace(WEB_XML, JDBC_PROPERTIES); FileOutputStream fileOutputStream = new FileOutputStream(path); properties.store(fileOutputStream, ""); fileOutputStream.close(); result = true; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } private String getScriptContent(String scriptPath) throws Exception { if (scriptPath == null || scriptPath.length() == 0) { return null; } InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(scriptPath); InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); StringBuffer stringBuffer = new StringBuffer(); String line = ""; while ((line = bufferedReader.readLine()) != null) { stringBuffer.append(line); } bufferedReader.close(); inputStreamReader.close(); inputStream.close(); return stringBuffer.toString(); } private void initializeConfig() throws Exception { SpringBeanGetter.refreshApplicationContext(); } private boolean setupTables() throws Exception { boolean scriptExists = resourceExists(SCRIPT_FILE); if (!scriptExists) { throw new Exception("script.sql not found."); } String scriptContent = getScriptContent(SCRIPT_FILE); return SpringBeanGetter.getSetupDBDao().executeSqlScript(scriptContent); } private boolean setupAdmin(DalGroup dalGroup, LoginUser user) throws Exception { boolean result = false; String groupName = dalGroup.getGroup_name(); if (groupName == null || groupName.isEmpty()) { return result; } String userName = user.getUserName(); if (userName == null || userName.isEmpty()) { return result; } int userResult = SpringBeanGetter.getDaoOfLoginUser().insertUser(user); if (userResult <= 0) { return result; } user = SpringBeanGetter.getDaoOfLoginUser().getUserByNo(user.getUserNo()); DalGroup group = new DalGroup(); group.setId(DalGroupResource.SUPER_GROUP_ID); group.setGroup_name(dalGroup.getGroup_name()); group.setGroup_comment(dalGroup.getGroup_comment()); group.setCreate_user_no(user.getUserNo()); group.setCreate_time(new Timestamp(System.currentTimeMillis())); int groupResult = SpringBeanGetter.getDaoOfDalGroup().insertDalGroup(group); if (groupResult <= 0) { return result; } int userGroupResult = SpringBeanGetter.getDalUserGroupDao().insertUserGroup(user.getId(), DalGroupResource.SUPER_GROUP_ID, RoleType.Admin.getValue(), AddUser.Allow.getValue()); if (userGroupResult <= 0) { return result; } return true; } }