From 8813f12ef8b4638de3ef044665bc9c5986700d61 Mon Sep 17 00:00:00 2001 From: "xiangyong.wang" Date: Mon, 13 Sep 2021 10:25:58 +0800 Subject: [PATCH 1/2] =?UTF-8?q?vmfs=E8=87=AA=E5=8A=A8=E6=89=A9=E5=AE=B9?= =?UTF-8?q?=E6=9C=80=E4=BD=B3=E5=AE=9E=E8=B7=B5=EF=BC=8C=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dmestore/constant/DpSqlFileConstants.java | 32 ++ .../dmestore/dao/BestPracticeCheckDao.java | 310 ++++++++++++++-- .../model/BestPracticeCheckRecordBean.java | 10 + .../model/BestPracticeUpResultBase.java | 10 + .../dmestore/mvc/BestPracticeController.java | 93 ++++- .../huawei/dmestore/mvc/VmRdmController.java | 60 ++- .../services/BestPracticeProcessService.java | 54 ++- .../BestPracticeProcessServiceImpl.java | 348 +++++++++++++++--- .../services/DmeStorageServiceImpl.java | 2 +- .../dmestore/services/SystemServiceImpl.java | 8 + .../dmestore/services/VmRdmService.java | 20 + .../dmestore/services/VmRdmServiceImpl.java | 123 ++++++- .../bestpractice/BestPracticeService.java | 13 + .../task/BackgroundCheckBestPractiseTask.java | 18 +- .../com/huawei/dmestore/utils/VCSDKUtils.java | 155 +++++++- .../huawei/vmware/mo/VirtualMachineMo.java | 27 ++ .../META-INF/spring/bundle-context.xml | 8 + .../dao/BestPracticeCheckDaoTest.java | 6 +- .../BestPracticeProcessServiceImplTest.java | 2 +- 19 files changed, 1190 insertions(+), 109 deletions(-) diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/constant/DpSqlFileConstants.java b/dmestore-service/src/main/java/com/huawei/dmestore/constant/DpSqlFileConstants.java index 8903d1005..382c168dd 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/constant/DpSqlFileConstants.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/constant/DpSqlFileConstants.java @@ -230,6 +230,38 @@ public final class DpSqlFileConstants { + "\"PUSH_EVENT_LEVEL\" integer, " + "\"HOST_PORT\" integer default 443, " + "CONSTRAINT UNIQUE_DP_HOST_IP UNIQUE (HOST_IP) " + ");"; + + /** + * DP_DME_BEST_PRACTICE_RECOMMAND. + */ + public static final String DP_DME_BEST_PRACTICE_RECOMMAND = "DP_DME_BEST_PRACTICE_RECOMMAND"; + + /** + * DP_DME_BEST_PRACTICE_RECOMMAND_SQL. + */ + public static final String DP_DME_BEST_PRACTICE_RECOMMAND_SQL = "DROP TABLE IF EXISTS \"DP_DME_BEST_PRACTICE_RECOMMAND\"; " + + "CREATE TABLE \"DP_DME_BEST_PRACTICE_RECOMMAND\" ( " + "\"ID\" integer PRIMARY KEY AUTO_INCREMENT NOT NULL, " + + "\"HOST_SETTING\" nvarchar(255) NOT NULL, " + "\"RECOMMEND_VALUE\" nvarchar(255) NOT NULL, " + + "\"REPAIR_ACTION\" nvarchar(10) NOT NULL, " + "\"CREATE_TIME\" datetime, " + + "\"UPDATE_RECOMMEND_TIME\" datetime, " + "\"UPDATE_REPAIR_TIME\" datetime " + ");"; + + /** + * DP_DME_BEST_PRACTICE_LOG. + */ + public static final String DP_DME_BEST_PRACTICE_LOG = "DP_DME_BEST_PRACTICE_LOG"; + + /** + * DP_DME_BEST_PRACTICE_LOG_SQL. + */ + public static final String DP_DME_BEST_PRACTICE_LOG_SQL = "DROP TABLE IF EXISTS \"DP_DME_BEST_PRACTICE_LOG\"; " + + "CREATE TABLE \"DP_DME_BEST_PRACTICE_LOG\" ( " + "\"ID\" integer PRIMARY KEY AUTO_INCREMENT NOT NULL, " + + "\"OBJECT_NAME\" nvarchar(512) NOT NULL, " + "\"OBJECT_ID\" nvarchar(255) NOT NULL, " + + "\"HOST_SETTING\" nvarchar(255) NOT NULL, " + "\"RECOMMEND_VALUE\" nvarchar(255) NOT NULL, " + + "\"VIOLATION_VALUE\" nvarchar(255) NOT NULL, " + "\"REPAIR_TYPE\" nvarchar(10) NOT NULL, " + + "\"REPAIR_RESULT\" BOOLEAN NOT NULL, " + "\"REPAIR_TIME\" DATETIME , " + + "\"MESSAGE\" clob " + ");"; + + /** * DPSqlFileConstant . */ diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/dao/BestPracticeCheckDao.java b/dmestore-service/src/main/java/com/huawei/dmestore/dao/BestPracticeCheckDao.java index 7a9dc21dc..700b56a0d 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/dao/BestPracticeCheckDao.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/dao/BestPracticeCheckDao.java @@ -2,7 +2,11 @@ import com.huawei.dmestore.constant.DpSqlFileConstants; import com.huawei.dmestore.exception.DataBaseException; +import com.huawei.dmestore.exception.DmeSqlException; import com.huawei.dmestore.model.BestPracticeBean; +import com.huawei.dmestore.model.BestPracticeLog; +import com.huawei.dmestore.model.BestPracticeRecommand; +import com.huawei.dmestore.model.BestPracticeRecommandUpReq; import com.huawei.dmestore.model.BestPracticeUpResultBase; import com.huawei.dmestore.model.BestPracticeUpResultResponse; @@ -19,10 +23,13 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; /** * BestPracticeCheckDao @@ -31,9 +38,11 @@ * @since 2020-09-15 **/ public class BestPracticeCheckDao extends H2DataBaseDao { - private static final String HOST_NAME = "HOST_NAME"; + public static final String HOST_NAME = "HOST_NAME"; - private static final String HOST_ID = "HOST_ID"; + public static final String HOST_ID = "HOST_ID"; + + public static final String HOST_SETTING = "HOST_SETTING"; private static final int PARAMETER_INDEX_1 = 1; @@ -41,6 +50,8 @@ public class BestPracticeCheckDao extends H2DataBaseDao { private static final int COLLECTIONS_DEFAULT_LEN = 16; + private final SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + /** * save * @@ -124,22 +135,31 @@ public List getHostNameByHostsetting(String hostSetting) throws SQLExcep * @return Map * @throws SQLException SQLException */ - public Map getAllHostIds(int pageNo, int pageSize) throws SQLException { - Map map = new HashMap<>(COLLECTIONS_DEFAULT_LEN); + public Map> getAllHostIds(int pageNo, int pageSize, String hostSetting) + throws SQLException { + Map> map = new HashMap<>(COLLECTIONS_DEFAULT_LEN); Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { con = getConnection(); - String sql = "SELECT HOST_ID,HOST_NAME from DP_DME_BEST_PRACTICE_CHECK where 1=1 "; - if (pageNo > 0 && pageSize > 0) { - int offset = (pageNo - 1) * pageSize; - sql = sql + " OFFSET " + offset + " ROWS FETCH FIRST " + pageSize + " ROWS ONLY"; + String sql = "SELECT HOST_ID,HOST_NAME,HOST_SETTING from DP_DME_BEST_PRACTICE_CHECK where 1=1 "; + if (!StringUtils.isEmpty(hostSetting)) { + sql = sql + "and HOST_SETTING='" + hostSetting + "' "; } + int fetchSize = pageSize > 0 ? pageSize : 100; + int offset = 0; + if (pageNo > 0) { + offset = (pageNo - 1) * pageSize; + } + sql = sql + " OFFSET " + offset + " ROWS FETCH FIRST " + fetchSize + " ROWS ONLY"; ps = con.prepareStatement(sql); rs = ps.executeQuery(); while (rs.next()) { - map.put(rs.getString(HOST_ID), rs.getString(HOST_NAME)); + Map temp = new HashMap<>(); + temp.put(HOST_NAME, rs.getString(HOST_NAME)); + temp.put(HOST_SETTING, rs.getString(HOST_SETTING)); + map.put(rs.getString(HOST_ID), temp); } } catch (DataBaseException | SQLException e) { LOGGER.error("getAllHostIds Failed! {}", e.getMessage()); @@ -157,8 +177,8 @@ public Map getAllHostIds(int pageNo, int pageSize) throws SQLExc * @return Map * @throws SQLException SQLException */ - public Map getByHostIds(List ids) throws SQLException { - Map map = new HashMap<>(COLLECTIONS_DEFAULT_LEN); + public Map> getByHostIds(List ids, String hostSetting) throws SQLException { + Map> map = new HashMap<>(COLLECTIONS_DEFAULT_LEN); if (ids == null || ids.size() == 0) { return map; } @@ -167,7 +187,11 @@ public Map getByHostIds(List ids) throws SQLException { ResultSet rs = null; try { con = getConnection(); - String sql = "SELECT HOST_ID,HOST_NAME from DP_DME_BEST_PRACTICE_CHECK where 1=1 AND HOST_ID in("; + String sql = "SELECT HOST_ID,HOST_NAME,HOST_SETTING from DP_DME_BEST_PRACTICE_CHECK where 1=1 "; + if (!StringUtils.isEmpty(hostSetting)) { + sql = sql + " AND HOST_SETTING='" + hostSetting + "' "; + } + sql = sql + " AND HOST_ID in("; StringBuilder stringBuilder = new StringBuilder(sql); for (int index = 0; index < ids.size(); index++) { if (index == ids.size() - 1) { @@ -182,7 +206,10 @@ public Map getByHostIds(List ids) throws SQLException { } rs = ps.executeQuery(); while (rs.next()) { - map.put(rs.getString(HOST_ID), rs.getString(HOST_NAME)); + Map temp = new HashMap<>(); + temp.put(HOST_NAME, rs.getString(HOST_NAME)); + temp.put(HOST_SETTING, rs.getString(HOST_SETTING)); + map.put(rs.getString(HOST_ID), temp); } } catch (DataBaseException | SQLException e) { LOGGER.error("getAllHostIds Failed! {}", e.getMessage()); @@ -237,15 +264,24 @@ public List getRecordByPage(String hostSetting, int pageNo, in return lists; } + public List getRecordBeanByHostSetting(String hostSetting, String id) throws SQLException { + List ids = null; + if (!StringUtils.isEmpty(id)) { + ids = new ArrayList<>(); + ids.add(id); + } + return getRecordBeanByHostSetting(hostSetting, ids); + } + /** * getRecordBeanByHostsetting * * @param hostSetting hostSetting - * @param id id + * @param ids id * @return List * @throws SQLException SQLException */ - public List getRecordBeanByHostsetting(String hostSetting, String id) throws SQLException { + public List getRecordBeanByHostSetting(String hostSetting, List ids) throws SQLException { List lists = new ArrayList<>(); Connection con = null; PreparedStatement ps = null; @@ -255,16 +291,16 @@ public List getRecordBeanByHostsetting(String hostSetting, Str String sql = "SELECT HOST_ID,HOST_NAME,HOST_SETTING,RECOMMEND_VALUE,ACTUAL_VALUE,HINT_LEVEL,NEED_REBOOT," + "AUTO_REPAIR from DP_DME_BEST_PRACTICE_CHECK where 1=1 "; if (!StringUtils.isEmpty(hostSetting)) { - sql = sql + " and HOST_SETTING=?"; - boolean isId = !StringUtils.isEmpty(id); + sql = sql + " and HOST_SETTING='" + hostSetting + "'"; + boolean isId = (ids != null && ids.size() > 0); if (isId) { - sql = sql + " and HOST_ID=?"; + StringBuilder stringBuilder = new StringBuilder(); + for (String id : ids) { + stringBuilder.append("'").append(id).append("'").append(","); + } + sql = sql + " and HOST_ID in(" + stringBuilder.substring(0, stringBuilder.lastIndexOf(",")) + ")"; } ps = con.prepareStatement(sql); - ps.setString(PARAMETER_INDEX_1, hostSetting); - if (isId) { - ps.setString(PARAMETER_INDEX_2, id); - } } else { ps = con.prepareStatement(sql); } @@ -477,4 +513,234 @@ public void update(List list) { closeConnection(con, pstm, null); } } + + public BestPracticeRecommand getRecommand(String hostsetting, String recommandValue) throws DmeSqlException { + BestPracticeRecommand recommand = getRecommandFromDb("HOST_SETTING", hostsetting); + if (recommand != null) { + return recommand; + } + + // 如果没有就默认生成一条记录 + initRecommand(hostsetting, recommandValue, "0"); + return getRecommandFromDb("HOST_SETTING", hostsetting); + } + + public int updateRecommendByFiled(String filedName, String filedValue, BestPracticeRecommandUpReq req) + throws DmeSqlException { + String recommandVale = req.getRecommandValue(); + String repairAction = req.getRepairAction(); + if (StringUtils.isEmpty(recommandVale) && StringUtils.isEmpty(repairAction)) { + LOGGER.error("best practice recommend update error!All parameters are null!"); + throw new DmeSqlException("parameter error!"); + } + + BestPracticeRecommand recommand = getRecommandFromDb(filedName, String.valueOf(filedValue)); + if (null == recommand) { + throw new DmeSqlException("recommend record not found!"); + } + + if (!StringUtils.isEmpty(recommandVale)) { + recommand.setRecommandValue(recommandVale); + recommand.setUpdateRecommendTime(new java.util.Date(System.currentTimeMillis())); + } + + if (!StringUtils.isEmpty(repairAction)) { + recommand.setRepairAction(repairAction); + recommand.setUpdateRepairTime(new java.util.Date(System.currentTimeMillis())); + } + + return updateRecommandFromDb(recommand); + } + + private int updateRecommandFromDb(BestPracticeRecommand recommand) throws DmeSqlException { + Connection con = null; + PreparedStatement pstm = null; + int upDateSize; + try { + con = getConnection(); + String sql = "UPDATE DP_DME_BEST_PRACTICE_RECOMMAND SET RECOMMEND_VALUE=?,UPDATE_RECOMMEND_TIME=?, " + + "REPAIR_ACTION=?,UPDATE_REPAIR_TIME=? where ID=?"; + pstm = con.prepareStatement(sql); + pstm.setString(DpSqlFileConstants.DIGIT_1, recommand.getRecommandValue()); + pstm.setString(DpSqlFileConstants.DIGIT_2, fmt.format(recommand.getUpdateRecommendTime())); + pstm.setString(DpSqlFileConstants.DIGIT_3, recommand.getRepairAction()); + pstm.setString(DpSqlFileConstants.DIGIT_4, fmt.format(recommand.getUpdateRepairTime())); + pstm.setString(DpSqlFileConstants.DIGIT_5, recommand.getId()); + pstm.execute(); + upDateSize = 1; + } catch (SQLException ex) { + throw new DmeSqlException(ex.getMessage()); + } finally { + closeConnection(con, pstm, null); + } + + return upDateSize; + } + + private BestPracticeRecommand getRecommandFromDb(String filedName, String filedValue) throws DmeSqlException { + Connection con = null; + PreparedStatement pstm = null; + ResultSet rs = null; + BestPracticeRecommand recommand = null; + try { + con = getConnection(); + String sql = "SELECT * FROM DP_DME_BEST_PRACTICE_RECOMMAND where " + filedName + "=?"; + pstm = con.prepareStatement(sql); + pstm.setString(PARAMETER_INDEX_1, filedValue); + rs = pstm.executeQuery(); + if (rs.next()) { + recommand = new BestPracticeRecommand(); + recommand.setId(rs.getString("ID")); + recommand.setHostsetting(rs.getString("HOST_SETTING")); + recommand.setRecommandValue(rs.getString("RECOMMEND_VALUE")); + recommand.setRepairAction(rs.getString("REPAIR_ACTION")); + recommand.setCreateTime(rs.getTimestamp("CREATE_TIME")); + recommand.setUpdateRecommendTime(rs.getTimestamp("UPDATE_RECOMMEND_TIME")); + recommand.setUpdateRepairTime(rs.getTimestamp("UPDATE_REPAIR_TIME")); + } + } catch (SQLException ex) { + throw new DmeSqlException(ex.getMessage()); + } finally { + closeConnection(con, pstm, rs); + } + + return recommand; + } + + private void initRecommand(String hostSetting, String recommandVale, String repairAction) { + BestPracticeRecommand recommand = new BestPracticeRecommand(); + String uuid = UUID.randomUUID().toString(); + recommand.setId(uuid); + recommand.setHostsetting(hostSetting); + recommand.setRecommandValue(recommandVale); + recommand.setRepairAction(repairAction); + java.util.Date date = new java.util.Date(System.currentTimeMillis()); + recommand.setCreateTime(date); + recommand.setUpdateRecommendTime(date); + recommand.setUpdateRepairTime(date); + saveRecommand(recommand); + } + + private void saveRecommand(BestPracticeRecommand recommand) { + Connection con = null; + PreparedStatement pstm = null; + try { + con = getConnection(); + String sql = "insert into DP_DME_BEST_PRACTICE_RECOMMAND(HOST_SETTING,RECOMMEND_VALUE,REPAIR_ACTION," + + "CREATE_TIME,UPDATE_RECOMMEND_TIME,UPDATE_REPAIR_TIME) values(?,?,?,?,?,?)"; + pstm = con.prepareStatement(sql); + + // 不自动提交 + con.setAutoCommit(false); + pstm.setString(DpSqlFileConstants.DIGIT_1, recommand.getHostsetting()); + pstm.setString(DpSqlFileConstants.DIGIT_2, recommand.getRecommandValue()); + pstm.setString(DpSqlFileConstants.DIGIT_3, recommand.getRepairAction()); + String dateStr = fmt.format(recommand.getCreateTime()); + pstm.setString(DpSqlFileConstants.DIGIT_4, dateStr); + pstm.setString(DpSqlFileConstants.DIGIT_5, dateStr); + pstm.setString(DpSqlFileConstants.DIGIT_6, dateStr); + pstm.execute(); + con.commit(); + } catch (SQLException ex) { + LOGGER.error("save recommand vale error!errMsg={}", ex.getMessage()); + try { + // 回滚 + con.rollback(); + } catch (SQLException e) { + LOGGER.error(e.getMessage()); + } + } finally { + closeConnection(con, pstm, null); + } + } + + public void saveRepairLog(List logs) { + if (logs == null || logs.size() == 0) { + return; + } + + Connection con = null; + PreparedStatement pstm = null; + try { + con = getConnection(); + String sql = "insert into DP_DME_BEST_PRACTICE_LOG(OBJECT_NAME,OBJECT_ID,HOST_SETTING,RECOMMEND_VALUE," + + "VIOLATION_VALUE,REPAIR_TYPE,REPAIR_RESULT,REPAIR_TIME,MESSAGE) values(?,?,?,?,?,?,?,?,?)"; + pstm = con.prepareStatement(sql); + + // 不自动提交 + con.setAutoCommit(false); + for (BestPracticeLog log : logs) { + pstm.setString(DpSqlFileConstants.DIGIT_1, log.getObjectName()); + pstm.setString(DpSqlFileConstants.DIGIT_2, log.getObjectId()); + pstm.setString(DpSqlFileConstants.DIGIT_3, log.getHostsetting()); + pstm.setString(DpSqlFileConstants.DIGIT_4, log.getRecommandValue()); + pstm.setString(DpSqlFileConstants.DIGIT_5, log.getViolationValue()); + pstm.setString(DpSqlFileConstants.DIGIT_6, log.getRepairType()); + pstm.setBoolean(DpSqlFileConstants.DIGIT_7, log.getRepairResult()); + pstm.setString(DpSqlFileConstants.DIGIT_8, fmt.format(log.getRepairTime())); + pstm.setCharacterStream(DpSqlFileConstants.DIGIT_9, new StringReader(log.getMessage())); + pstm.addBatch(); + } + pstm.executeBatch(); + con.commit(); + } catch (SQLException ex) { + LOGGER.error("save best practice log error!errMsg={}", ex.getMessage()); + try { + // 回滚 + con.rollback(); + } catch (SQLException e) { + LOGGER.error(e.getMessage()); + } + } finally { + closeConnection(con, pstm, null); + } + } + + public List getRepariLogByPage(String hostsetting, String objId, int pageNo, int pageSize) + throws DmeSqlException { + Connection con = null; + PreparedStatement ps = null; + ResultSet rs = null; + List logList = new ArrayList<>(); + try { + con = getConnection(); + String sql = "SELECT * from DP_DME_BEST_PRACTICE_LOG where 1=1 "; + if (!StringUtils.isEmpty(hostsetting)) { + sql = sql + " and HOST_SETTING='" + hostsetting + "' "; + } + + if (!StringUtils.isEmpty(objId)) { + sql = sql + " and OBJECT_ID='" + objId + "' "; + } + + sql = sql + " order by REPAIR_TIME DESC "; + + if (pageNo > 0 && pageSize > 0) { + int offset = (pageNo - 1) * pageSize; + sql = sql + " OFFSET " + offset + " ROWS FETCH FIRST " + pageSize + " ROWS ONLY"; + } + ps = con.prepareStatement(sql); + rs = ps.executeQuery(); + while (rs.next()) { + BestPracticeLog log = new BestPracticeLog(); + log.setId(rs.getString("ID")); + log.setObjectId(rs.getString("OBJECT_ID")); + log.setObjectName(rs.getString("OBJECT_NAME")); + log.setHostsetting(rs.getString("HOST_SETTING")); + log.setRecommandValue(rs.getString("RECOMMEND_VALUE")); + log.setViolationValue(rs.getString("VIOLATION_VALUE")); + log.setRepairType(rs.getString("REPAIR_TYPE")); + log.setRepairResult(rs.getBoolean("REPAIR_RESULT")); + log.setRepairTime(rs.getTimestamp("REPAIR_TIME")); + log.setMessage(clobToString(rs.getClob("MESSAGE"))); + logList.add(log); + } + } catch (DataBaseException | SQLException | IOException e) { + LOGGER.error("getAllHostIds Failed! {}", e.getMessage()); + throw new DmeSqlException(e.getMessage()); + } finally { + closeConnection(con, ps, rs); + } + return logList; + } } diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeCheckRecordBean.java b/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeCheckRecordBean.java index d441a0123..92bf27388 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeCheckRecordBean.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeCheckRecordBean.java @@ -29,6 +29,8 @@ public class BestPracticeCheckRecordBean { */ private int count; + private String repairAction; + /** * hostList . */ @@ -123,4 +125,12 @@ public List getHostList() { public void setHostList(final List param) { this.hostList = param; } + + public String getRepairAction() { + return repairAction; + } + + public void setRepairAction(String repairAction) { + this.repairAction = repairAction; + } } diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeUpResultBase.java b/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeUpResultBase.java index 42c35763c..a8d08ed7e 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeUpResultBase.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeUpResultBase.java @@ -27,6 +27,8 @@ public class BestPracticeUpResultBase { */ private boolean updateResult; + private String message; + /** * getHostSetting . * @@ -99,6 +101,14 @@ public void setUpdateResult(final boolean param) { this.updateResult = param; } + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + @Override public final String toString() { return "BestPracticeUpResultBase{" + "hostSetting='" + hostSetting + '\'' + ", needReboot=" + needReboot diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/mvc/BestPracticeController.java b/dmestore-service/src/main/java/com/huawei/dmestore/mvc/BestPracticeController.java index 6922e6261..cb50b2208 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/mvc/BestPracticeController.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/mvc/BestPracticeController.java @@ -3,6 +3,9 @@ import com.huawei.dmestore.exception.DmeException; import com.huawei.dmestore.exception.DmeSqlException; import com.huawei.dmestore.exception.VcenterException; +import com.huawei.dmestore.model.BestPracticeLog; +import com.huawei.dmestore.model.BestPracticeRecommand; +import com.huawei.dmestore.model.BestPracticeRecommandUpReq; import com.huawei.dmestore.model.BestPracticeUpResultResponse; import com.huawei.dmestore.model.BestPracticeUpdateByTypeRequest; import com.huawei.dmestore.model.ResponseBodyBean; @@ -18,7 +21,10 @@ import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * BestPracticeController @@ -70,6 +76,21 @@ public ResponseBodyBean checkByCluster(@RequestParam String clusterObjId) { } } + /** + * bestPractice + * + * @return ResponseBodyBean + */ + @RequestMapping(value = "/check/vmfs", method = RequestMethod.POST) + public ResponseBodyBean checkVmfs(@RequestBody(required = false) List objectIds) { + try { + bestPracticeProcessService.checkVmfs(objectIds); + return success(); + } catch (VcenterException ex) { + return failure(ex.getMessage()); + } + } + /** * getBestPracticeRecords * @@ -77,7 +98,7 @@ public ResponseBodyBean checkByCluster(@RequestParam String clusterObjId) { */ @RequestMapping(value = "/records/all", method = RequestMethod.GET) public ResponseBodyBean getBestPracticeRecords(@RequestParam(required = false) String type, - @RequestParam(required = false) String objectId) { + @RequestParam(required = false) String objectId) { try { return success(bestPracticeProcessService.getCheckRecord(type, objectId)); } catch (DmeSqlException ex) { @@ -91,13 +112,13 @@ public ResponseBodyBean getBestPracticeRecords(@RequestParam(required = false) S * getBySettingAndPage * * @param hostSetting hostSetting - * @param pageNo pageNo - * @param pageSize pageSize + * @param pageNo pageNo + * @param pageSize pageSize * @return ResponseBodyBean */ @RequestMapping(value = "/records/bypage", method = RequestMethod.GET) public ResponseBodyBean getBySettingAndPage(@RequestParam String hostSetting, @RequestParam int pageNo, - @RequestParam int pageSize) { + @RequestParam int pageSize) { try { return success(bestPracticeProcessService.getCheckRecordBy(hostSetting, pageNo, pageSize)); } catch (DmeException ex) { @@ -118,7 +139,7 @@ public ResponseBodyBean bylist(@RequestBody List listTemp = bestPracticeProcessService.update( - request.getHostObjectIds(), request.getHostSetting()); + request.getHostObjectIds(), request.getHostSetting(), false); if (null != listTemp && listTemp.size() > 0) { resultList.addAll(listTemp); } @@ -138,7 +159,8 @@ public ResponseBodyBean bylist(@RequestBody List hostObjectIds) { @RequestMapping(value = "/update/all", method = RequestMethod.POST) public ResponseBodyBean upAll() { try { - return success(bestPracticeProcessService.update(null, null)); + return success(bestPracticeProcessService.update(null)); } catch (DmeSqlException e) { return failure(e.getMessage()); } @@ -181,7 +203,7 @@ public ResponseBodyBean upAll() { @RequestMapping(value = "/update/byCluster", method = RequestMethod.POST) public ResponseBodyBean upByCluster() { try { - return success(bestPracticeProcessService.update(null, null)); + return success(bestPracticeProcessService.update(null, null, false)); } catch (DmeSqlException e) { return failure(e.getMessage()); } @@ -223,4 +245,59 @@ public ResponseBodyBean updateVirtualNicList(@RequestBody List logs) { + bestPracticeProcessService.saveLog(logs); + return success(); + } + + @RequestMapping(value = "/logs", method = RequestMethod.GET) + public ResponseBodyBean getLogs(@RequestParam(required = false) String hostsetting, + @RequestParam(required = false) String objectId, + @RequestParam(required = false) Integer pageNo, + @RequestParam(required = false) Integer pageSize) { + try { + List logList = bestPracticeProcessService.getLog(hostsetting, objectId, + pageNo == null ? 0 : pageNo, pageSize == null ? 0 : pageSize); + return success(logList); + } catch (DmeSqlException e) { + return failure(e.getMessage()); + } + } } diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/mvc/VmRdmController.java b/dmestore-service/src/main/java/com/huawei/dmestore/mvc/VmRdmController.java index 2fc222d45..87cfbc79b 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/mvc/VmRdmController.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/mvc/VmRdmController.java @@ -1,14 +1,18 @@ package com.huawei.dmestore.mvc; import com.huawei.dmestore.exception.DmeException; +import com.huawei.dmestore.model.DelVmRdmsRequest; import com.huawei.dmestore.model.ResponseBodyBean; import com.huawei.dmestore.model.VmRdmCreateBean; import com.huawei.dmestore.services.VmRdmService; + import com.google.gson.Gson; +import com.google.gson.JsonObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -16,7 +20,7 @@ import org.springframework.web.bind.annotation.RestController; import java.util.List; - +import java.util.Map; /** * VmRdmController @@ -28,22 +32,22 @@ @RequestMapping(value = "v1/vmrdm") public class VmRdmController extends BaseController { private static final Logger LOG = LoggerFactory.getLogger(VmRdmController.class); - + private final Gson gson = new Gson(); @Autowired private VmRdmService vmRdmService; + /** * createBean * - * @param vmObjectId vmObjectId - * @param createBean createBean + * @param vmObjectId vmObjectId + * @param createBean createBean * @param dataStoreObjectId dataStoreObjectId * @return ResponseBodyBean */ @RequestMapping(value = "createRdm", method = RequestMethod.POST) public ResponseBodyBean createRdm(@RequestParam("vmObjectId") String vmObjectId, - @RequestBody VmRdmCreateBean createBean, - @RequestParam("dataStoreObjectId") String dataStoreObjectId) { + @RequestBody VmRdmCreateBean createBean, @RequestParam("dataStoreObjectId") String dataStoreObjectId) { try { vmRdmService.createRdm(dataStoreObjectId, vmObjectId, createBean, createBean.getCompatibilityMode()); return success(); @@ -84,4 +88,48 @@ public ResponseBodyBean getDatastoreMountsOnHost(@RequestParam("vmObjectId") Str return failure(e.getMessage()); } } + + /** + * getRdms + * + * @param vmObjectId vmObjectId + * @return ResponseBodyBean + */ + @RequestMapping(value = "rdms/{vmObjectId}", method = RequestMethod.GET) + public ResponseBodyBean getRdms(@PathVariable("vmObjectId") String vmObjectId) { + try { + List> rdms = vmRdmService.getVmRdmByObjectId(vmObjectId); + return success(rdms); + } catch (DmeException e) { + LOG.error(e.getMessage()); + return failure(e.getMessage()); + } + } + + /** + * delRdms + * + * @param vmObjectId vmObjectId + * @param diskObjectIds Ҫɾ���Ĵ����б���Ϣ + * @return ResponseBodyBean + */ + @RequestMapping(value = "rdms/{vmObjectId}", method = RequestMethod.POST) + public ResponseBodyBean delRdms(@PathVariable("vmObjectId") String vmObjectId, @RequestBody List diskObjectIds) { + try { + String delResultStr = vmRdmService.delVmRdmByObjectId(vmObjectId, diskObjectIds); + JsonObject delResultObj = gson.fromJson(delResultStr, JsonObject.class); + ResponseBodyBean responseBodyBean = new ResponseBodyBean(); + responseBodyBean.setCode(delResultObj.get("code").getAsString()); + if(delResultObj.get("data") != null){ + List hostList = gson.fromJson(delResultObj.get("data"), List.class); + responseBodyBean.setData(hostList); + } + responseBodyBean.setDescription(delResultObj.get("description").getAsString()); + return responseBodyBean; + } catch (DmeException e) { + LOG.error(e.getMessage()); + return failure(e.getMessage()); + } + } + } diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/services/BestPracticeProcessService.java b/dmestore-service/src/main/java/com/huawei/dmestore/services/BestPracticeProcessService.java index 22ca7fe3d..a193d0fa0 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/services/BestPracticeProcessService.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/services/BestPracticeProcessService.java @@ -5,11 +5,15 @@ import com.huawei.dmestore.exception.VcenterException; import com.huawei.dmestore.model.BestPracticeBean; import com.huawei.dmestore.model.BestPracticeCheckRecordBean; +import com.huawei.dmestore.model.BestPracticeLog; +import com.huawei.dmestore.model.BestPracticeRecommand; +import com.huawei.dmestore.model.BestPracticeRecommandUpReq; import com.huawei.dmestore.model.BestPracticeUpResultResponse; import com.huawei.dmestore.model.UpHostVnicRequestBean; import java.util.List; +import java.util.Map; /** * BestPracticeProcessService @@ -24,6 +28,8 @@ public interface BestPracticeProcessService { void check(String objectId) throws VcenterException; + void checkVmfs(List objectIds) throws VcenterException; + void checkByCluster(String clusterObjectId) throws VcenterException; /** @@ -41,11 +47,12 @@ public interface BestPracticeProcessService { * * @param objectIds 主机对象ID * @param hostSetting 检查对象类型 + * @param byTask true:通过任务发起 false:手动点击 * @return List * @throws DmeSqlException 异常 * @author wangxy */ - List update(List objectIds, String hostSetting) throws DmeSqlException; + List update(List objectIds, String hostSetting, boolean byTask) throws DmeSqlException; /** * 根据集群ID实施最佳实践 @@ -74,4 +81,49 @@ public interface BestPracticeProcessService { * @author wangxy */ void upVirtualNicList(List beans); + + /** + * 获取最佳实践推荐值 + * + * @param hostsetting 检查项标签 + * @return BestPracticeRecommand + * @throws DmeSqlException 异常 + * @author wangxy + */ + BestPracticeRecommand getRecommand(String hostsetting) throws DmeSqlException; + + + /** + * 更新最佳实践推荐值 + * + * @param filedName 查询字段名称 + * @param filedValue 查询字段值 + * @param req 推荐值、动作map + * @return int 影响条数 + * @throws DmeSqlException 异常 + * @author wangxy + */ + int recommandUp(String filedName, String filedValue, BestPracticeRecommandUpReq req) throws DmeSqlException; + + /** + * 最佳实践实施日志保存 + * + * @param logs List 日志集合 + * @author wangxy + */ + void saveLog(List logs); + + /** + * 最佳实践实施日志查询 + * + * @param hostsetting 检查项 + * @param objectId 对象ID + * @param pageNo 页码 + * @param pageSize 每页数量 + * @return List 日志集合 + * @throws DmeSqlException 异常 + * @author wangxy + */ + List getLog(String hostsetting, String objectId,int pageNo, int pageSize) throws DmeSqlException; + } diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/services/BestPracticeProcessServiceImpl.java b/dmestore-service/src/main/java/com/huawei/dmestore/services/BestPracticeProcessServiceImpl.java index 66bdc1626..8e3590e18 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/services/BestPracticeProcessServiceImpl.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/services/BestPracticeProcessServiceImpl.java @@ -2,12 +2,15 @@ import com.huawei.dmestore.constant.DmeConstants; import com.huawei.dmestore.dao.BestPracticeCheckDao; +import com.huawei.dmestore.dao.DmeVmwareRalationDao; +import com.huawei.dmestore.entity.DmeVmwareRelation; import com.huawei.dmestore.exception.DmeException; import com.huawei.dmestore.exception.DmeSqlException; import com.huawei.dmestore.exception.VcenterException; import com.huawei.dmestore.model.*; import com.huawei.dmestore.services.bestpractice.BestPracticeService; import com.huawei.dmestore.services.bestpractice.JumboFrameMTUImpl; +import com.huawei.dmestore.services.bestpractice.VmfsDatastoreSpaceUtilizationImpl; import com.huawei.dmestore.utils.StringUtil; import com.huawei.dmestore.utils.VCSDKUtils; @@ -21,9 +24,11 @@ import java.sql.SQLException; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * BestPracticeProcessServiceImpl @@ -44,6 +49,10 @@ public class BestPracticeProcessServiceImpl implements BestPracticeProcessServic private List bestPracticeServices; + private VmfsDatastoreSpaceUtilizationImpl vmfsDatastoreSpaceUtilization; + + private DmeVmwareRalationDao dmeVmwareRalationDao; + public List getBestPracticeServices() { return bestPracticeServices; } @@ -68,6 +77,14 @@ public void setBestPracticeCheckDao(BestPracticeCheckDao bestPracticeCheckDao) { this.bestPracticeCheckDao = bestPracticeCheckDao; } + public void setVmfsDatastoreSpaceUtilization(VmfsDatastoreSpaceUtilizationImpl vmfsDatastoreSpaceUtilization) { + this.vmfsDatastoreSpaceUtilization = vmfsDatastoreSpaceUtilization; + } + + public void setDmeVmwareRalationDao(DmeVmwareRalationDao dmeVmwareRalationDao) { + this.dmeVmwareRalationDao = dmeVmwareRalationDao; + } + @Override public List getCheckRecord(String type, String objectId) throws DmeException { List objectIds = null; @@ -76,18 +93,15 @@ public List getCheckRecord(String type, String obje if (StringUtil.isNotBlank(type)) { objectIds = new ArrayList<>(); if (type.equals("host")) { - //check(objectId); objectIds.add(objectId); } else if (type.equals("cluster")) { // 查询集群下的所有主机信息 String hostsOnCluster = vcsdkUtils.getHostsOnCluster(objectId); if (StringUtil.isNotBlank(hostsOnCluster)) { List> hostList = gson.fromJson(hostsOnCluster, - new TypeToken>>() { - }.getType()); + new TypeToken>>() { }.getType()); for (int index = 0; index < hostList.size(); index++) { String tempHostObjectId = hostList.get(index).get("hostId"); - //check(tempHostObjectId); objectIds.add(tempHostObjectId); } } @@ -99,19 +113,22 @@ public List getCheckRecord(String type, String obje bean.setHostSetting(bestPracticeService.getHostSetting()); bean.setLevel(bestPracticeService.getLevel()); bean.setRecommendValue(String.valueOf(bestPracticeService.getRecommendValue())); + bean.setRepairAction(bestPracticeService.repairAction()); try { if (objectIds != null && objectIds.size() > 0) { List tempList = new ArrayList<>(); - for (String id : objectIds) { - List hostBeanTemp = bestPracticeCheckDao.getRecordBeanByHostsetting( - bestPracticeService.getHostSetting(), id); - tempList.addAll(hostBeanTemp); - } + List hostBeanTemp = bestPracticeCheckDao.getRecordBeanByHostSetting( + bestPracticeService.getHostSetting(), objectIds); + tempList.addAll(hostBeanTemp); bean.setHostList(tempList); bean.setCount(tempList.size()); + } else if(objectIds != null && objectIds.size() == 0){ + //集群下面没有主机 + bean.setHostList(new ArrayList<>()); + bean.setCount(0); } else { - List hostBean = bestPracticeCheckDao.getRecordBeanByHostsetting( - bestPracticeService.getHostSetting(), null); + List hostBean = bestPracticeCheckDao.getRecordBeanByHostSetting( + bestPracticeService.getHostSetting(), (String)null); bean.setHostList(hostBean); bean.setCount(hostBean.size()); } @@ -120,12 +137,28 @@ public List getCheckRecord(String type, String obje } list.add(bean); } + + // 添加vmfs记录信息 + list.add(getVmfsRecord(objectIds)); + return list; } @Override public List getCheckRecordBy(String hostSetting, int pageNo, int pageSize) throws DmeException { List list = new ArrayList<>(); + String vmfsHostSetting = vmfsDatastoreSpaceUtilization.getHostSetting(); + + // vmfs单独处理 + if (hostSetting.equals(vmfsHostSetting)) { + try { + list = bestPracticeCheckDao.getRecordByPage(vmfsHostSetting, pageNo, pageSize); + } catch (SQLException throwables) { + throwables.printStackTrace(); + } + return list; + } + for (BestPracticeService bestPracticeService : bestPracticeServices) { String setting = bestPracticeService.getHostSetting(); if (hostSetting.equals(setting)) { @@ -137,6 +170,7 @@ public List getCheckRecordBy(String hostSetting, int pageNo, i break; } } + return list; } @@ -149,10 +183,10 @@ public void check(String objectId) throws VcenterException { } else { hostsStr = vcsdkUtils.getAllHosts(); } + Map> checkMap = new HashMap<>(DmeConstants.COLLECTION_CAPACITY_16); JsonArray hostArray = gson.fromJson(hostsStr, JsonArray.class); + List unConnectedIds = new ArrayList<>(); if (null != hostArray) { - Map> checkMap = new HashMap<>(DmeConstants.COLLECTION_CAPACITY_16); - List unConnectedIds = new ArrayList<>(); for (int index = 0; index < hostArray.size(); index++) { // 对每一项进行检查 JsonObject hostObject = hostArray.get(index).getAsJsonObject(); @@ -174,7 +208,8 @@ public void check(String objectId) throws VcenterException { if (!isCheck) { BestPracticeBean bean = new BestPracticeBean(); bean.setHostSetting(hostSetting); - bean.setRecommendValue(String.valueOf(bestPracticeService.getRecommendValue(vcsdkUtils, hostObjectId))); + bean.setRecommendValue( + String.valueOf(bestPracticeService.getRecommendValue(vcsdkUtils, hostObjectId))); bean.setLevel(bestPracticeService.getLevel()); bean.setNeedReboot(String.valueOf(bestPracticeService.needReboot())); Object currentValue = bestPracticeService.getCurrentValue(vcsdkUtils, hostObjectId); @@ -188,29 +223,44 @@ public void check(String objectId) throws VcenterException { } catch (Exception ex) { // 报错,跳过当前项检查 log.error("{} check failed! The host may not support this operation!hostSetting={}", hostName, - bestPracticeService.getHostSetting(), ex); + bestPracticeService.getHostSetting(), ex); } } } + } - if (checkMap.size() > 0) { - // 保存到数据库 - bachDbProcess(checkMap); - } + // VMFS最佳实践检查 + Map> vmfsMap = checkVmfs(unConnectedIds, null); + checkMap.putAll(vmfsMap); - bestPracticeCheckDao.deleteByHostIds(unConnectedIds); - } + // 将无法连通的主机或者存储从最佳实践表中移除 + bestPracticeCheckDao.deleteByHostIds(unConnectedIds); + + // 保存到数据库 + bachDbProcess(checkMap); log.info("====best practice check end===="); } + @Override + public void checkVmfs(List objectIds) throws VcenterException { + log.info("====VMFS best practice check begin===="); + List unConnectedIds = new ArrayList<>(); + Map> vmfsMap = checkVmfs(unConnectedIds, objectIds); + // 将无法连通的主机或者存储从最佳实践表中移除 + bestPracticeCheckDao.deleteByHostIds(unConnectedIds); + + // 保存到数据库 + bachDbProcess(vmfsMap); + log.info("====VMFS best practice check end===="); + } + @Override public void checkByCluster(String clusterObjectId) throws VcenterException { // 查询集群下的所有主机信息 String hostsOnCluster = vcsdkUtils.getHostsOnCluster(clusterObjectId); if (StringUtil.isNotBlank(hostsOnCluster)) { List> hostList = gson.fromJson(hostsOnCluster, - new TypeToken>>() { - }.getType()); + new TypeToken>>() { }.getType()); for (int index = 0; index < hostList.size(); index++) { String tempHostObjectId = hostList.get(index).get("hostId"); check(tempHostObjectId); @@ -219,6 +269,9 @@ public void checkByCluster(String clusterObjectId) throws VcenterException { } private void bachDbProcess(Map> map) { + if (map == null || map.size() == 0) { + return; + } map.forEach((hostSetting, bestPracticeBeans) -> { // 本地全量查询 List localHostNames = new ArrayList<>(); @@ -259,6 +312,16 @@ private void bachDbProcess(Map> map) { }); } + @Override + public String getVirtualNicList(List hostObjIds) { + return vcsdkUtils.getVirtualNicList(hostObjIds, JumboFrameMTUImpl.RECOMMEND_VALUE); + } + + @Override + public void upVirtualNicList(List beans) { + vcsdkUtils.updateVirtualNicList(beans, JumboFrameMTUImpl.RECOMMEND_VALUE); + } + @Override public List updateByCluster(String clusterObjectId) throws DmeException { // 查询集群下的所有主机信息 @@ -266,8 +329,7 @@ public List updateByCluster(String clusterObjectId String hostsOnCluster = vcsdkUtils.getHostsOnCluster(clusterObjectId); if (StringUtil.isNotBlank(hostsOnCluster)) { List> hostList = gson.fromJson(hostsOnCluster, - new TypeToken>>() { - }.getType()); + new TypeToken>>() { }.getType()); List objectIds = new ArrayList<>(); for (int index = 0; index < hostList.size(); index++) { objectIds.add(hostList.get(index).get("hostId")); @@ -277,82 +339,127 @@ public List updateByCluster(String clusterObjectId return bestPracticeUpResultResponses; } - @Override - public String getVirtualNicList(List hostObjIds) { - return vcsdkUtils.getVirtualNicList(hostObjIds, JumboFrameMTUImpl.RECOMMEND_VALUE); - } - - @Override - public void upVirtualNicList(List beans) { - vcsdkUtils.updateVirtualNicList(beans, JumboFrameMTUImpl.RECOMMEND_VALUE); - } - @Override public List update(List objectIds) throws DmeSqlException { - return update(objectIds, null); + return update(objectIds, null, false); } @Override - public List update(List objectIds, String hostSetting) - throws DmeSqlException { + public List update(List objectIds, String hostSetting, boolean byTask) + throws DmeSqlException { // 获取对应的service List services = new ArrayList<>(); - for (BestPracticeService bestPracticeService : bestPracticeServices) { - if (hostSetting != null) { - if (bestPracticeService.getHostSetting().equals(hostSetting)) { - services.add(bestPracticeService); - break; - } + if (hostSetting == null) { + services.add(vmfsDatastoreSpaceUtilization); + services.addAll(bestPracticeServices); + } else { + if (hostSetting.equals(vmfsDatastoreSpaceUtilization.getHostSetting())) { + services.add(vmfsDatastoreSpaceUtilization); } else { - services.addAll(bestPracticeServices); - break; + for (BestPracticeService bestPracticeService : bestPracticeServices) { + if (bestPracticeService.getHostSetting().equals(hostSetting)) { + services.add(bestPracticeService); + break; + } + } } } // 从本地数据库查询需要实施最佳实践的主机信息 - Map hostMap = getHostMap(objectIds); + Map> hostMap = getHostMap(objectIds, hostSetting); List responses = new ArrayList<>(); - List successList = new ArrayList<>(); + + List logList = new ArrayList<>(); List disconnectedIds = new ArrayList<>(); - for (Map.Entry entry : hostMap.entrySet()) { + for (Map.Entry> entry : hostMap.entrySet()) { String objectId = entry.getKey(); + String objName = entry.getValue().get(BestPracticeCheckDao.HOST_NAME); + boolean isVmfs = objectId.contains("Datastore"); + if (isVmfs && !vcsdkUtils.isAccessibleOfDatastore(objectId)) { + disconnectedIds.add(objectId); + continue; + } + // 连接断开的主机跳过 - if (!vcsdkUtils.isHostConnected(objectId)) { + if (!isVmfs && !vcsdkUtils.isHostConnected(objectId)) { disconnectedIds.add(objectId); continue; } - String hostName = entry.getValue(); BestPracticeUpResultResponse response = new BestPracticeUpResultResponse(); List baseList = new ArrayList(); response.setHostObjectId(objectId); - response.setHostName(hostName); + response.setHostName(objName); boolean isNeedReboot = false; for (BestPracticeService service : services) { // 能自动修复的才进行实施操作 if (!service.autoRepair()) { continue; } + + //如果是通过任务发起的更新,修复动作为手动的检查项不执行最佳实践操作 + if (byTask && service.repairAction().equals("0")) { + continue; + } + + // 如果是vmfs自动扩容最佳实践实施,只调用vmfs的更新即可 + if (isVmfs && !(service instanceof VmfsDatastoreSpaceUtilizationImpl)) { + continue; + } + BestPracticeUpResultBase base = new BestPracticeUpResultBase(); base.setHostObjectId(objectId); base.setHostSetting(service.getHostSetting()); base.setNeedReboot(service.needReboot()); + + String violationValue = null; + boolean checkFlag = false; + boolean repairResult = false; + String repairMessage = "success"; try { - boolean checkFlag = service.check(vcsdkUtils, objectId); - log.info("check! before best practice update! checkFlag={}, objectId={}, hostSetting={}", checkFlag, objectId, hostSetting); + checkFlag = service.check(vcsdkUtils, objectId); + log.info("check! before best practice update! checkFlag={}, objectId={}, hostSetting={}", checkFlag, + objectId, service.getHostSetting()); if (!checkFlag) { + // 违规值需要在更新前获取 + violationValue = service.getCurrentValue(vcsdkUtils, objectId) + ""; + service.update(vcsdkUtils, objectId); // 更新成功后,只要有一项是需要重启的则该主机需要重启后生效 if (service.needReboot()) { isNeedReboot = true; } + + repairResult = true; } base.setUpdateResult(true); - successList.add(objectId); } catch (Exception ex) { base.setUpdateResult(false); + repairMessage = ex.getMessage(); + base.setMessage(repairMessage); + repairResult = false; log.error("best practice update {} {} recommend value failed!errMsg:{}", objectId, hostSetting, ex); } baseList.add(base); + + // 日志bean构建 + try { + if (!checkFlag) { + BestPracticeLog bestPracticeLog = new BestPracticeLog(); + bestPracticeLog.setHostsetting(service.getHostSetting()); + bestPracticeLog.setId("-1"); + bestPracticeLog.setObjectId(objectId); + bestPracticeLog.setObjectName(objName); + bestPracticeLog.setRecommandValue(service.getRecommendValue(vcsdkUtils, objectId) + ""); + bestPracticeLog.setViolationValue(violationValue); + bestPracticeLog.setRepairType(byTask ? "1" : "0"); + bestPracticeLog.setRepairResult(repairResult); + bestPracticeLog.setMessage(repairMessage); + bestPracticeLog.setRepairTime(new Date(System.currentTimeMillis())); + logList.add(bestPracticeLog); + } + } catch (Exception exception) { + log.error("build BestPracticeLog error!", exception); + } } response.setResult(baseList); response.setNeedReboot(isNeedReboot); @@ -362,18 +469,20 @@ public List update(List objectIds, String // 将成功修改了最佳实践值的记录从表中删除 bestPracticeCheckDao.deleteBy(responses); bestPracticeCheckDao.deleteByHostIds(disconnectedIds); + bestPracticeCheckDao.saveRepairLog(logList); return responses; } - private Map getHostMap(List objectIds) throws DmeSqlException { - Map hostMap = new HashMap<>(DmeConstants.COLLECTION_CAPACITY_16); + private Map> getHostMap(List objectIds, String hostSetting) throws DmeSqlException { + Map> hostMap = new HashMap<>(DmeConstants.COLLECTION_CAPACITY_16); if (objectIds == null || objectIds.size() == 0) { // 获取本地所有 int pageNo = 0; try { while (true) { - Map hostMapTemp = bestPracticeCheckDao.getAllHostIds(pageNo++, PAGE_SIZE); + Map> hostMapTemp = bestPracticeCheckDao.getAllHostIds(pageNo++, + PAGE_SIZE, hostSetting); hostMap.putAll(hostMapTemp); if (hostMapTemp.size() != PAGE_SIZE) { @@ -386,11 +495,132 @@ private Map getHostMap(List objectIds) throws DmeSqlExce } else { try { // 从本地数据库查询指定的主机信息 - hostMap = bestPracticeCheckDao.getByHostIds(objectIds); + hostMap = bestPracticeCheckDao.getByHostIds(objectIds, hostSetting); } catch (SQLException e) { throw new DmeSqlException(e.getMessage()); } } return hostMap; } + + private Map> checkVmfs(List unConnectedIds, List objIds) { + Map> vmfsMap = new HashMap(); + List list = new ArrayList<>(); + try { + List dvrlistTemp = dmeVmwareRalationDao.getDmeVmwareRelation(DmeConstants.STORE_TYPE_VMFS); + List dvrlist; + if(objIds != null && objIds.size()> 0){ + dvrlist = dvrlistTemp.stream().filter(re ->objIds.contains(re.getStoreId())).collect(Collectors.toList()); + }else { + dvrlist = dvrlistTemp; + } + dvrlist.forEach(dmeVmwareRelation -> { + String hostSetting = vmfsDatastoreSpaceUtilization.getHostSetting(); + String objId = dmeVmwareRelation.getStoreId(); + if (!vcsdkUtils.isAccessibleOfDatastore(objId)) { + unConnectedIds.add(objId); + } else { + try { + boolean isCheck = vmfsDatastoreSpaceUtilization.check(vcsdkUtils, objId); + if (!isCheck) { + BestPracticeBean bean = new BestPracticeBean(); + bean.setHostSetting(hostSetting); + bean.setRecommendValue( + vmfsDatastoreSpaceUtilization.getRecommendValue(vcsdkUtils, objId) + ""); + bean.setLevel(vmfsDatastoreSpaceUtilization.getLevel()); + bean.setNeedReboot(String.valueOf(vmfsDatastoreSpaceUtilization.needReboot())); + Object currentValue = vmfsDatastoreSpaceUtilization.getCurrentValue(vcsdkUtils, objId); + String actualValue = String.valueOf(currentValue); + bean.setActualValue(actualValue); + bean.setHostObjectId(objId); + bean.setHostName(dmeVmwareRelation.getStoreName()); + bean.setAutoRepair(String.valueOf(vmfsDatastoreSpaceUtilization.autoRepair())); + list.add(bean); + } + } catch (Exception ex) { + log.error("vmfs best practice check error! vmfs name={}", dmeVmwareRelation.getStoreName(), ex); + } + } + }); + } catch (DmeSqlException ex) { + log.error("vmfs best practice check sql error!", ex); + } + + vmfsMap.put(vmfsDatastoreSpaceUtilization.getHostSetting(), list); + return vmfsMap; + } + + private BestPracticeCheckRecordBean getVmfsRecord(List hostObjIds) { + BestPracticeCheckRecordBean bean = new BestPracticeCheckRecordBean(); + String hostSetting = vmfsDatastoreSpaceUtilization.getHostSetting(); + bean.setHostSetting(hostSetting); + bean.setLevel(vmfsDatastoreSpaceUtilization.getLevel()); + bean.setRepairAction(vmfsDatastoreSpaceUtilization.repairAction()); + try { + bean.setRecommendValue(vmfsDatastoreSpaceUtilization.getRecommendValue(vcsdkUtils, null) + ""); + } catch (Exception exception) { + log.error("vmfs best practice check get recommend value error!", exception); + } + + try { + // 根据主机ID + if (hostObjIds != null && hostObjIds.size() > 0) { + List dsIds = new ArrayList<>(); + for (String hostObjId : hostObjIds) { + dsIds.addAll(vcsdkUtils.getDatastoreByHostObjIdAndType(hostObjId, DmeConstants.STORE_TYPE_VMFS)); + } + List temp = new ArrayList<>(16); + List hostBeanTemp = bestPracticeCheckDao.getRecordBeanByHostSetting(hostSetting, dsIds); + temp.addAll(hostBeanTemp); + bean.setHostList(temp); + bean.setCount(temp.size()); + } else if(hostObjIds != null && hostObjIds.size() == 0){ + bean.setHostList(new ArrayList<>()); + bean.setCount(0); + } else { + List hostBean = bestPracticeCheckDao.getRecordBeanByHostSetting(hostSetting, (String)null); + bean.setHostList(hostBean); + bean.setCount(hostBean.size()); + } + } catch (SQLException throwables) { + log.error("vmfs best practice get records error!", throwables); + } + + return bean; + } + + @Override + public BestPracticeRecommand getRecommand(String hostsetting) throws DmeSqlException { + boolean legalSetting = false; + BestPracticeService service = vmfsDatastoreSpaceUtilization; + for (BestPracticeService _service : bestPracticeServices) { + if (hostsetting.equals(_service.getHostSetting())) { + legalSetting = true; + service = _service; + break; + } + } + + if (legalSetting || hostsetting.equals(vmfsDatastoreSpaceUtilization.getHostSetting())) { + return bestPracticeCheckDao.getRecommand(hostsetting, String.valueOf(service.getRecommendValue())); + } else { + throw new DmeSqlException(hostsetting + " hostsetting is not supported"); + } + } + + @Override + public int recommandUp(String filedName, String filedValue, BestPracticeRecommandUpReq req) throws DmeSqlException { + return bestPracticeCheckDao.updateRecommendByFiled(filedName, filedValue, req); + } + + @Override + public void saveLog(List logList) { + bestPracticeCheckDao.saveRepairLog(logList); + } + + @Override + public List getLog(String hostsetting, String objectId, int pageNo, int pageSize) + throws DmeSqlException { + return bestPracticeCheckDao.getRepariLogByPage(hostsetting, objectId, pageNo, pageSize); + } } diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/services/DmeStorageServiceImpl.java b/dmestore-service/src/main/java/com/huawei/dmestore/services/DmeStorageServiceImpl.java index d090d5140..7a7858ca8 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/services/DmeStorageServiceImpl.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/services/DmeStorageServiceImpl.java @@ -431,7 +431,7 @@ public List getStoragePools(String storageId, String mediaType) thr } try { ResponseEntity responseEntity = dmeAccessService.accessByJson(url, HttpMethod.GET, params); - LOG.info(gson.toJson(responseEntity)); + LOG.debug(gson.toJson(responseEntity)); int code = responseEntity.getStatusCodeValue(); if (code != HttpStatus.OK.value()) { throw new DmeException(CODE_503, "search oriented storage pool error"); diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/services/SystemServiceImpl.java b/dmestore-service/src/main/java/com/huawei/dmestore/services/SystemServiceImpl.java index 60f05a519..6c0104f92 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/services/SystemServiceImpl.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/services/SystemServiceImpl.java @@ -42,6 +42,14 @@ public void initDb() { systemDao.checkExistAndCreateTable(DpSqlFileConstants.DP_DME_VCENTER_INFO, DpSqlFileConstants.DP_DME_VCENTER_INFO_SQL); + // 20210723 add table DP_DME_BEST_PRACTICE_RECOMMAND + systemDao.checkExistAndCreateTable(DpSqlFileConstants.DP_DME_BEST_PRACTICE_RECOMMAND, + DpSqlFileConstants.DP_DME_BEST_PRACTICE_RECOMMAND_SQL); + + // 20210723 add table DP_DME_BEST_PRACTICE_RECOMMAND + systemDao.checkExistAndCreateTable(DpSqlFileConstants.DP_DME_BEST_PRACTICE_LOG, + DpSqlFileConstants.DP_DME_BEST_PRACTICE_LOG_SQL); + LOGGER.info("creating table over..."); systemDao.initData(DpSqlFileConstants.DP_DME_BEST_PRACTICE_CHECK_ALTER_SQL); diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/services/VmRdmService.java b/dmestore-service/src/main/java/com/huawei/dmestore/services/VmRdmService.java index 38e335080..77da9830a 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/services/VmRdmService.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/services/VmRdmService.java @@ -1,6 +1,7 @@ package com.huawei.dmestore.services; import com.huawei.dmestore.exception.DmeException; +import com.huawei.dmestore.model.DelVmRdmsRequest; import com.huawei.dmestore.model.VmRdmCreateBean; import java.util.List; @@ -41,4 +42,23 @@ void createRdm(String dataStoreObjectId, String vmObjectId, VmRdmCreateBean crea * @throws DmeException DmeException **/ List getDatastoreMountsOnHost(String vmObjectId) throws DmeException; + + /** + * 获取虚拟机的RDM磁盘信息 + * + * @param vmObjectId vCenter虚拟机objectId + * @return java.util.List + * @throws DmeException DmeException + **/ + List> getVmRdmByObjectId(String vmObjectId) throws DmeException; + + + /** + * 虚拟机的RDM磁盘删除 + * + * @param vmObjectId vCenter虚拟机objectId + * @param disks vCenter虚拟机RDM的Id + * @throws DmeException DmeException + **/ + String delVmRdmByObjectId(String vmObjectId, List disks) throws DmeException; } diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/services/VmRdmServiceImpl.java b/dmestore-service/src/main/java/com/huawei/dmestore/services/VmRdmServiceImpl.java index 281240170..8ae4253e5 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/services/VmRdmServiceImpl.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/services/VmRdmServiceImpl.java @@ -10,9 +10,14 @@ import com.google.gson.Gson; import com.google.gson.JsonArray; +import com.google.gson.JsonNull; import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; import com.google.gson.reflect.TypeToken; +import springfox.documentation.spring.web.json.Json; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpMethod; @@ -113,7 +118,7 @@ public void setTaskService(TaskService taskService) { public void createRdm(String dataStoreObjectId, String vmObjectId, VmRdmCreateBean createBean, String compatibilityMode) throws DmeException { String taskId = createDmeRdm(createBean); - List lunNames = taskService.getSuccessNameFromCreateTask(TASKTYPE,taskId, longTaskTimeOut); + List lunNames = taskService.getSuccessNameFromCreateTask(TASKTYPE, taskId, longTaskTimeOut); Map paramMap = initParams(createBean); String requestVolumeName = (String) paramMap.get("requestVolumeName"); int capacity = (int) paramMap.get(CAPACITY); @@ -276,10 +281,10 @@ private String getDmeHostId(String hostIp, String hostObjectId) throws DmeExcept hostId = ToolUtils.jsonToStr(hostObject.get(ID_FIELD)); } } - Map>> allinitionators=vmfsAccessService.getAllInitionator(); + Map>> allinitionators = vmfsAccessService.getAllInitionator(); if (hostId == null) { - hostId = vmfsAccessService.checkOrCreateToHost(hostIp, hostObjectId,allinitionators); + hostId = vmfsAccessService.checkOrCreateToHost(hostIp, hostObjectId, allinitionators); } return hostId; } @@ -481,4 +486,116 @@ private String getStorageModel(String storageId) throws DmeException { StorageDetail storageDetail = dmeStorageService.getStorageDetail(storageId); return storageDetail.getModel() + " " + storageDetail.getProductVersion(); } + + @Override + public List> getVmRdmByObjectId(String vmObjectId) throws DmeException { + List> reList = new ArrayList<>(); + try { + List> vcRdmList = vcsdkUtils.getVmRdmByObjectId(vmObjectId); + for (int i = 0; i < vcRdmList.size(); i++) { + Map vcRdmMap = vcRdmList.get(i); + String wwn = vcRdmMap.get("lunWwn"); + + // 根据wwn查询DME Lun信息 + String url = DmeConstants.DME_VOLUME_BASE_URL + "?volume_wwn=" + wwn; + ResponseEntity responseEntity = dmeAccessService.access(url, HttpMethod.GET, null); + if (responseEntity.getStatusCodeValue() / 100 == 2) { + JsonObject object = new JsonParser().parse(responseEntity.getBody()).getAsJsonObject(); + if (object.get("count").getAsInt() == 0) { + continue; + } + JsonObject dmeVolume = object.getAsJsonArray("volumes").get(0).getAsJsonObject(); + vcRdmMap.put("lunName", dmeVolume.get("name").getAsString()); + reList.add(vcRdmMap); + } + } + + } catch (Exception exception) { + throw new DmeException(exception.getMessage()); + } + + return reList; + } + + @Override + public String delVmRdmByObjectId(String vmObjectId, List disks) throws DmeException { + JsonObject reObj = new JsonObject(); + reObj.addProperty("code", 200); + reObj.add("data", null); + reObj.addProperty("description", ""); + try { + boolean isConnected = vcsdkUtils.vmIsConnected(vmObjectId); + if(!isConnected){ + reObj.addProperty("code", 500); + reObj.addProperty("description", "The RMD cannot be deleted in the current status!"); + return reObj.toString(); + } + List diskObjectIds = disks.stream() + .map(DelVmRdmsRequest::getDiskObjectId) + .collect(Collectors.toList()); + List wwns = disks.stream().map(DelVmRdmsRequest::getLunWwn).collect(Collectors.toList()); + + // 调用vCenter删除RDM + vcsdkUtils.delVmRdm(vmObjectId, diskObjectIds); + + Map> unMap = new HashMap<>(); + for (String wwn : wwns) { + String url = DmeConstants.DME_VOLUME_BASE_URL + "?volume_wwn=" + wwn; + ResponseEntity responseEntity = dmeAccessService.access(url, HttpMethod.GET, null); + if (responseEntity.getStatusCodeValue() / 100 == 2) { + JsonObject object = new JsonParser().parse(responseEntity.getBody()).getAsJsonObject(); + if (object.get("count").getAsInt() == 0) { + continue; + } + JsonObject dmeVolume = object.getAsJsonArray("volumes").get(0).getAsJsonObject(); + JsonArray attachments = dmeVolume.getAsJsonArray("attachments"); + if (attachments == null || attachments.isJsonNull() || attachments.size() == 0) { + continue; + } + for (int i = 0; i < attachments.size(); i++) { + JsonObject attachment = attachments.get(i).getAsJsonObject(); + String hostId = attachment.get("host_id").getAsString(); + String volumeId = attachment.get("volume_id").getAsString(); + if (unMap.get(hostId) == null) { + unMap.put(hostId, new ArrayList<>()); + } + unMap.get(hostId).add(volumeId); + } + } + } + int errCnt = 0; + JsonArray hostArray = new JsonArray(); + JsonArray errorMsgArray = new JsonArray(); + for ( Map.Entry> entry :unMap.entrySet()){ + String dmeHostId = entry.getKey(); + String hostIp = null; + try { + dmeAccessService.unMapHost(dmeHostId, entry.getValue()); + //根据主机ID获取主机IP后刷新vCenter vmfs存储 + Map dmeHostMap = dmeAccessService.getDmeHost(dmeHostId); + hostIp = String.valueOf(dmeHostMap.get("ip")); + vcsdkUtils.hostRescanVmfs(hostIp); + }catch (DmeException dmeException){ + errCnt++; + hostArray.add(new JsonPrimitive(hostIp)); + JsonObject errorObj = new JsonObject(); + errorObj.addProperty("host_ip", hostIp); + errorObj.addProperty("error_message", dmeException.getMessage()); + errorMsgArray.add(errorObj); + LOG.error("host unmapping error!hostIp={},errorMsg={}", hostIp, dmeException.getMessage()); + continue; + } + } + if(errCnt > 0){ + reObj.addProperty("code", errCnt == unMap.size()? 500: 206); + reObj.add("data", hostArray); + reObj.addProperty("description", errorMsgArray.toString()); + } + } catch (Exception ex) { + reObj.addProperty("code", 500); + reObj.addProperty("description", ex.getMessage()); + } + + return reObj.toString(); + } } diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/services/bestpractice/BestPracticeService.java b/dmestore-service/src/main/java/com/huawei/dmestore/services/bestpractice/BestPracticeService.java index 2f859bacc..8156b2c80 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/services/bestpractice/BestPracticeService.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/services/bestpractice/BestPracticeService.java @@ -116,4 +116,17 @@ default HostVmwareFactory getHostMoFactory() { default DatastoreVmwareMoFactory getDatastoreMoFactory() { return DatastoreVmwareMoFactory.getInstance(); } + + /** + * 修复动作,默认为手动 + * 0:手动 + * 1:自动 + * + * @return String + * + */ + default String repairAction() { + return "0"; + } + } diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/task/BackgroundCheckBestPractiseTask.java b/dmestore-service/src/main/java/com/huawei/dmestore/task/BackgroundCheckBestPractiseTask.java index ab0653fd8..7579ee778 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/task/BackgroundCheckBestPractiseTask.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/task/BackgroundCheckBestPractiseTask.java @@ -1,5 +1,6 @@ package com.huawei.dmestore.task; +import com.huawei.dmestore.exception.DmeSqlException; import com.huawei.dmestore.exception.VcenterException; import com.huawei.dmestore.services.BestPracticeProcessService; @@ -22,13 +23,24 @@ public class BackgroundCheckBestPractiseTask implements StatefulJob { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { - LOGGER.info("CheckBestPractise start"); try { + long t1 = System.currentTimeMillis(); + LOGGER.info("CheckBestPractise Start"); Object obj = ApplicationContextHelper.getBean("BestPracticeProcessServiceImpl"); - ((BestPracticeProcessService) obj).check(null); + BestPracticeProcessService bestPracticeProcessService = (BestPracticeProcessService) obj; + bestPracticeProcessService.check(null); + long t2 = System.currentTimeMillis(); + LOGGER.info("CheckBestPractise End!Take {}ms", t2 -t1); + + LOGGER.info("BestPractise Up Start"); + // ������˺�ִ���Զ����� + bestPracticeProcessService.update(null, null, true); + long t3 = System.currentTimeMillis(); + LOGGER.info("BestPractise Up End!Take {}ms", t3 -t2); } catch (VcenterException e) { LOGGER.error("CheckBestPractise error", e); + } catch (DmeSqlException e) { + LOGGER.error("BestPractise Up Error", e); } - LOGGER.info("CheckBestPractise end"); } } diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/utils/VCSDKUtils.java b/dmestore-service/src/main/java/com/huawei/dmestore/utils/VCSDKUtils.java index 50ba8e805..a09a67e65 100644 --- a/dmestore-service/src/main/java/com/huawei/dmestore/utils/VCSDKUtils.java +++ b/dmestore-service/src/main/java/com/huawei/dmestore/utils/VCSDKUtils.java @@ -66,8 +66,6 @@ import java.net.URI; import java.util.*; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import javax.xml.parsers.DocumentBuilder; @@ -4718,4 +4716,157 @@ public List> getMountDataStoresByHostObjectIdNew(String host } return lists; } + + + /** + * 存储是否可访问 + * + * @param datastoreObjId 存储objectid + * @return boolean boolean + */ + public boolean isAccessibleOfDatastore(String datastoreObjId) { + try { + String serverguid = vcConnectionHelpers.objectId2Serverguid(datastoreObjId); + VmwareContext context = vcConnectionHelpers.getServerContext(serverguid); + ManagedObjectReference objmor = vcConnectionHelpers.objectId2Mor(datastoreObjId); + DatastoreMo datastoreMo = datastoreVmwareMoFactory.build(context, objmor); + DatastoreSummary datastoreSummary = datastoreMo.getSummary(); + return datastoreSummary.isAccessible(); + } catch (Exception e) { + logger.error("query datastore accessible by objectid error!datastoreObjId={}, error:{}", datastoreObjId, + e.getMessage()); + } + return false; + } + + /** + * 主机下的存储查询 + * + * @param hostObjId 主机objectId + * @param datastroreType 存储类型 + * @return List> 列表 + */ + public List getDatastoreByHostObjIdAndType(String hostObjId, String datastroreType){ + List ids = new ArrayList<>(); + try { + String serverguid = vcConnectionHelpers.objectId2Serverguid(hostObjId); + VmwareContext context = vcConnectionHelpers.getServerContext(serverguid); + ManagedObjectReference objmor = vcConnectionHelpers.objectId2Mor(hostObjId); + HostMo hostMo = hostVmwareFactory.build(context, objmor); + List dataStoreMorList = hostMo.getHostDatastoreSystemMo().getDatastores(); + List> mapList = getDataStoresByMors(datastroreType, context, dataStoreMorList); + mapList.forEach(map -> ids.add(map.get(OBJECT_ID))); + } catch (Exception ex) { + logger.error("query datastore by hostObjId error!hostObjId={},type={}, error:{}", hostObjId, datastroreType, + ex.getMessage()); + } + + return ids; + } + + private List> getDataStoresByMors(String datastroreType, VmwareContext context, + List dataStoreMorList) throws Exception { + List> mapList = new ArrayList<>(); + for (ManagedObjectReference dataStoreMor : dataStoreMorList) { + DatastoreMo datastoreMo = datastoreVmwareMoFactory.build(context, dataStoreMor); + DatastoreSummary datastoreSummary = datastoreMo.getSummary(); + if (!StringUtils.isEmpty(datastroreType) && !datastoreSummary.getType().equals(datastroreType)) { + continue; + } + Map map = new HashMap<>(); + String objectId = vcConnectionHelpers.mor2ObjectId(dataStoreMor, context.getServerAddress()); + map.put(NAME, datastoreSummary.getName()); + map.put(OBJECT_ID, objectId); + map.put(STATUS, ToolUtils.getStr(datastoreSummary.isAccessible())); + map.put(TYPE, datastoreSummary.getType()); + + mapList.add(map); + } + + return mapList; + } + + public List> getVmRdmByObjectId(String vmObjId) throws Exception{ + String serverguid = vcConnectionHelpers.objectId2Serverguid(vmObjId); + VmwareContext context = vcConnectionHelpers.getServerContext(serverguid); + ManagedObjectReference objmor = vcConnectionHelpers.objectId2Mor(vmObjId); + VirtualMachineMo virtualMachineMo = virtualMachineMoFactorys.build(context, objmor); + VirtualDisk[] virtualDisks = virtualMachineMo.getAllDiskDevice(); + List> rdmListMap = new ArrayList<>(); + for (VirtualDisk virtualDisk : virtualDisks) { + VirtualDeviceBackingInfo backingInfo = virtualDisk.getBacking(); + if (backingInfo instanceof VirtualDiskRawDiskMappingVer1BackingInfo) { + VirtualDiskRawDiskMappingVer1BackingInfo rdmBacking = (VirtualDiskRawDiskMappingVer1BackingInfo)backingInfo; + Map rdmMap = new HashMap<>(); + + String diskObjectId = virtualDisk.getDiskObjectId(); + long capacity = virtualDisk.getCapacityInBytes() / ToolUtils.GI; + String diskLabel = virtualDisk.getDeviceInfo().getLabel(); + String physicsLun = rdmBacking.getDeviceName(); + String sharing = rdmBacking.getSharing(); + String diskMode = rdmBacking.getDiskMode(); + String compatibilityMode = rdmBacking.getCompatibilityMode(); + String lunUuid = rdmBacking.getLunUuid(); + String wwn = lunUuid.substring(10, 42); + + rdmMap.put("diskObjectId", diskObjectId); + rdmMap.put("capacity", String.valueOf(capacity)); + rdmMap.put("physicsLun", physicsLun); + rdmMap.put("lunWwn", wwn); + rdmMap.put("sharing", sharing); + rdmMap.put("diskMode", diskMode); + rdmMap.put("diskLabel_cn", diskLabel); + rdmMap.put("diskLabel_zh", diskLabel.replace("Hard disk", "硬盘")); + rdmMap.put("compatibilityMode", compatibilityMode); + rdmMap.put("vmObjectId", vmObjId); + + rdmListMap.add(rdmMap); + } + } + + return rdmListMap; + } + + + public void delVmRdm(String vmObjId, List diskObjectIds) throws Exception { + ManagedObjectReference morVm = vcConnectionHelpers.objectId2Mor(vmObjId); + String serverguid = vcConnectionHelpers.objectId2Serverguid(vmObjId); + VmwareContext context = vcConnectionHelpers.getServerContext(serverguid); + VirtualMachineMo virtualMachineMo = virtualMachineMoFactorys.build(context, morVm); + VirtualDisk[] virtualDisks = virtualMachineMo.getAllDiskDevice(); + VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec(); + for (String diskObjectId : diskObjectIds) { + for (VirtualDisk virtualDisk : virtualDisks) { + if (virtualDisk.getDiskObjectId().equals(diskObjectId)) { + VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec(); + deviceConfigSpec.setDevice(virtualDisk); + deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE); + + // 从数据存储删除文件 + deviceConfigSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.DESTROY); + reConfigSpec.getDeviceChange().add(deviceConfigSpec); + + break; + } + } + } + + ManagedObjectReference morTask = context.getService().reconfigVMTask(morVm, reConfigSpec); + boolean result = context.getVimClient().waitForTask(morTask); + + if (!result) { + throw new Exception("Failed to detach disk due to " + TaskMo.getTaskFailureInfo(context, morTask)); + } + + context.waitForTaskProgressDone(morTask); + } + + public boolean vmIsConnected(String vmObjId) throws Exception { + ManagedObjectReference morVm = vcConnectionHelpers.objectId2Mor(vmObjId); + String serverguid = vcConnectionHelpers.objectId2Serverguid(vmObjId); + VmwareContext context = vcConnectionHelpers.getServerContext(serverguid); + VirtualMachineMo virtualMachineMo = virtualMachineMoFactorys.build(context, morVm); + return virtualMachineMo.isConnected(); + } + } diff --git a/dmestore-service/src/main/java/com/huawei/vmware/mo/VirtualMachineMo.java b/dmestore-service/src/main/java/com/huawei/vmware/mo/VirtualMachineMo.java index 4563f830f..a5e0485cd 100644 --- a/dmestore-service/src/main/java/com/huawei/vmware/mo/VirtualMachineMo.java +++ b/dmestore-service/src/main/java/com/huawei/vmware/mo/VirtualMachineMo.java @@ -19,6 +19,7 @@ import com.vmware.vim25.VirtualLsiLogicController; import com.vmware.vim25.VirtualMachineConfigOption; import com.vmware.vim25.VirtualMachineConfigSpec; +import com.vmware.vim25.VirtualMachineConnectionState; import com.vmware.vim25.VirtualMachineFileInfo; import com.vmware.vim25.VirtualMachineRuntimeInfo; import com.vmware.vim25.VirtualSCSIController; @@ -92,6 +93,18 @@ public VirtualMachineRuntimeInfo getRuntimeInfo() throws Exception { return (VirtualMachineRuntimeInfo) context.getVimClient().getDynamicProperty(mor, "runtime"); } + /** + * getRuntimeInfo + * + * @return VirtualMachineRuntimeInfo + * @throws Exception Exception + */ + public boolean isConnected() throws Exception { + VirtualMachineRuntimeInfo runtimeInfo = getRuntimeInfo(); + VirtualMachineConnectionState connectionState = runtimeInfo.getConnectionState(); + return connectionState.value().equals(VirtualMachineConnectionState.CONNECTED.value()); + } + /** * getFileInfo * @@ -423,4 +436,18 @@ public int getNextDeviceNumber(int controllerKey) throws Exception { } return unitNumber; } + + public VirtualDisk[] getAllDiskDevice() throws Exception { + List deviceList = new ArrayList(); + List devices = context.getVimClient().getDynamicProperty(mor, "config.hardware.device"); + if (devices != null && devices.size() > 0) { + for (VirtualDevice device : devices) { + if (device instanceof VirtualDisk) { + deviceList.add((VirtualDisk) device); + } + } + } + + return deviceList.toArray(new VirtualDisk[0]); + } } diff --git a/dmestore-service/src/main/resources/META-INF/spring/bundle-context.xml b/dmestore-service/src/main/resources/META-INF/spring/bundle-context.xml index e8de2ca8c..bf5c44ffd 100644 --- a/dmestore-service/src/main/resources/META-INF/spring/bundle-context.xml +++ b/dmestore-service/src/main/resources/META-INF/spring/bundle-context.xml @@ -188,6 +188,8 @@ + + @@ -238,6 +240,12 @@ + + + + + + diff --git a/dmestore-service/src/test/java/com/huawei/dmestore/dao/BestPracticeCheckDaoTest.java b/dmestore-service/src/test/java/com/huawei/dmestore/dao/BestPracticeCheckDaoTest.java index 499909f7c..c0a2ee158 100644 --- a/dmestore-service/src/test/java/com/huawei/dmestore/dao/BestPracticeCheckDaoTest.java +++ b/dmestore-service/src/test/java/com/huawei/dmestore/dao/BestPracticeCheckDaoTest.java @@ -61,14 +61,14 @@ public void getHostNameByHostsetting() throws SQLException { @Test public void getAllHostIds() throws SQLException { - System.out.println(bestPracticeCheckDao.getAllHostIds(1, 10)); + System.out.println(bestPracticeCheckDao.getAllHostIds(1, 10, null)); } @Test public void getByHostIds() throws SQLException { List list = new ArrayList<>(); list.add("321"); - bestPracticeCheckDao.getByHostIds(list); + bestPracticeCheckDao.getByHostIds(list, null); } @Test @@ -78,7 +78,7 @@ public void getRecordByPage() throws SQLException { @Test public void getRecordBeanByHostsetting() throws SQLException { - bestPracticeCheckDao.getRecordBeanByHostsetting("321", null); + bestPracticeCheckDao.getRecordBeanByHostSetting("321", (String)null); } @Test diff --git a/dmestore-service/src/test/java/com/huawei/dmestore/services/BestPracticeProcessServiceImplTest.java b/dmestore-service/src/test/java/com/huawei/dmestore/services/BestPracticeProcessServiceImplTest.java index a186cf2b9..f60c6bb40 100644 --- a/dmestore-service/src/test/java/com/huawei/dmestore/services/BestPracticeProcessServiceImplTest.java +++ b/dmestore-service/src/test/java/com/huawei/dmestore/services/BestPracticeProcessServiceImplTest.java @@ -72,7 +72,7 @@ public void testGetCheckRecord() throws Exception { List hostBeanList = new ArrayList<>(); BestPracticeBean bestPracticeBean = new BestPracticeBean(); hostBeanList.add(bestPracticeBean); - when(bestPracticeCheckDao.getRecordBeanByHostsetting(anyString(), anyString())).thenReturn(hostBeanList); + when(bestPracticeCheckDao.getRecordBeanByHostSetting(anyString(), anyString())).thenReturn(hostBeanList); bestPracticeProcessService.getCheckRecord(null, null); } From 40762db8eca7ce939124e2c5bea988cb2e721e3b Mon Sep 17 00:00:00 2001 From: "xiangyong.wang" Date: Mon, 13 Sep 2021 10:47:56 +0800 Subject: [PATCH 2/2] =?UTF-8?q?vmfs=E8=87=AA=E5=8A=A8=E6=89=A9=E5=AE=B9?= =?UTF-8?q?=E6=9C=80=E4=BD=B3=E5=AE=9E=E8=B7=B5=EF=BC=8C=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dmestore/model/BestPracticeLog.java | 115 +++++++++++ .../dmestore/model/BestPracticeRecommand.java | 87 +++++++++ .../model/BestPracticeRecommandUpReq.java | 23 +++ .../dmestore/model/DelVmRdmsRequest.java | 28 +++ .../VmfsDatastoreSpaceUtilizationImpl.java | 178 ++++++++++++++++++ 5 files changed, 431 insertions(+) create mode 100644 dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeLog.java create mode 100644 dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeRecommand.java create mode 100644 dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeRecommandUpReq.java create mode 100644 dmestore-service/src/main/java/com/huawei/dmestore/model/DelVmRdmsRequest.java create mode 100644 dmestore-service/src/main/java/com/huawei/dmestore/services/bestpractice/VmfsDatastoreSpaceUtilizationImpl.java diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeLog.java b/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeLog.java new file mode 100644 index 000000000..deba4e5ca --- /dev/null +++ b/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeLog.java @@ -0,0 +1,115 @@ +package com.huawei.dmestore.model; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * BestPracticeLog . + * + * @author wangxiangyong . + * @since 2021-07-23 + **/ +public class BestPracticeLog implements Serializable { + private String id; + + private String objectName; + + private String objectId; + + private String hostsetting; + + private String violationValue; + + private String recommandValue; + + private String repairType; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date repairTime; + + private boolean repairResult; + + private String message; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getObjectName() { + return objectName; + } + + public void setObjectName(String objectName) { + this.objectName = objectName; + } + + public String getObjectId() { + return objectId; + } + + public void setObjectId(String objectId) { + this.objectId = objectId; + } + + public String getViolationValue() { + return violationValue; + } + + public void setViolationValue(String violationValue) { + this.violationValue = violationValue; + } + + public String getRecommandValue() { + return recommandValue; + } + + public void setRecommandValue(String recommandValue) { + this.recommandValue = recommandValue; + } + + public String getRepairType() { + return repairType; + } + + public void setRepairType(String repairType) { + this.repairType = repairType; + } + + public Date getRepairTime() { + return repairTime; + } + + public void setRepairTime(Date repairTime) { + this.repairTime = repairTime; + } + + public boolean getRepairResult() { + return repairResult; + } + + public void setRepairResult(boolean repairResult) { + this.repairResult = repairResult; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getHostsetting() { + return hostsetting; + } + + public void setHostsetting(String hostsetting) { + this.hostsetting = hostsetting; + } +} diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeRecommand.java b/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeRecommand.java new file mode 100644 index 000000000..7628d9459 --- /dev/null +++ b/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeRecommand.java @@ -0,0 +1,87 @@ +package com.huawei.dmestore.model; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * BestPracticeUpResultResponse . + * + * @author wangxiangyong . + * @since 2020-12-01 + **/ +public class BestPracticeRecommand implements Serializable { + private String id; + + private String hostsetting; + + private String recommandValue; + + private String repairAction; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date updateRecommendTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date updateRepairTime; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getHostsetting() { + return hostsetting; + } + + public void setHostsetting(String hostsetting) { + this.hostsetting = hostsetting; + } + + public String getRecommandValue() { + return recommandValue; + } + + public void setRecommandValue(String recommandValue) { + this.recommandValue = recommandValue; + } + + public String getRepairAction() { + return repairAction; + } + + public void setRepairAction(String repairAction) { + this.repairAction = repairAction; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public Date getUpdateRecommendTime() { + return updateRecommendTime; + } + + public void setUpdateRecommendTime(Date updateRecommendTime) { + this.updateRecommendTime = updateRecommendTime; + } + + public Date getUpdateRepairTime() { + return updateRepairTime; + } + + public void setUpdateRepairTime(Date updateRepairTime) { + this.updateRepairTime = updateRepairTime; + } +} diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeRecommandUpReq.java b/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeRecommandUpReq.java new file mode 100644 index 000000000..7f046dc5e --- /dev/null +++ b/dmestore-service/src/main/java/com/huawei/dmestore/model/BestPracticeRecommandUpReq.java @@ -0,0 +1,23 @@ +package com.huawei.dmestore.model; + +public class BestPracticeRecommandUpReq { + private String recommandValue; + + private String repairAction; + + public String getRecommandValue() { + return recommandValue; + } + + public void setRecommandValue(String recommandValue) { + this.recommandValue = recommandValue; + } + + public String getRepairAction() { + return repairAction; + } + + public void setRepairAction(String repairAction) { + this.repairAction = repairAction; + } +} diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/model/DelVmRdmsRequest.java b/dmestore-service/src/main/java/com/huawei/dmestore/model/DelVmRdmsRequest.java new file mode 100644 index 000000000..071f57b70 --- /dev/null +++ b/dmestore-service/src/main/java/com/huawei/dmestore/model/DelVmRdmsRequest.java @@ -0,0 +1,28 @@ +package com.huawei.dmestore.model; + +/** + * @author wangxiangyong + * @Description: TODO + * @date 2021/8/13 11:15 + */ +public class DelVmRdmsRequest { + private String diskObjectId; + private String lunWwn; + + public String getDiskObjectId() { + return diskObjectId; + } + + public void setDiskObjectId(String diskObjectId) { + this.diskObjectId = diskObjectId; + } + + public String getLunWwn() { + return lunWwn; + } + + public void setLunWwn(String lunWwn) { + this.lunWwn = lunWwn; + } + +} diff --git a/dmestore-service/src/main/java/com/huawei/dmestore/services/bestpractice/VmfsDatastoreSpaceUtilizationImpl.java b/dmestore-service/src/main/java/com/huawei/dmestore/services/bestpractice/VmfsDatastoreSpaceUtilizationImpl.java new file mode 100644 index 000000000..e85cf8086 --- /dev/null +++ b/dmestore-service/src/main/java/com/huawei/dmestore/services/bestpractice/VmfsDatastoreSpaceUtilizationImpl.java @@ -0,0 +1,178 @@ +package com.huawei.dmestore.services.bestpractice; + +import static com.huawei.dmestore.utils.ToolUtils.GI; + +import com.huawei.dmestore.dao.BestPracticeCheckDao; +import com.huawei.dmestore.dao.DmeVmwareRalationDao; +import com.huawei.dmestore.exception.DmeSqlException; +import com.huawei.dmestore.model.BestPracticeRecommand; +import com.huawei.dmestore.services.VmfsOperationService; +import com.huawei.dmestore.utils.VCSDKUtils; +import com.huawei.vmware.mo.DatastoreMo; +import com.huawei.vmware.util.DatastoreVmwareMoFactory; +import com.huawei.vmware.util.VmwareContext; + +import com.vmware.vim25.DatastoreSummary; +import com.vmware.vim25.ManagedObjectReference; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.DecimalFormat; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Vmfs6AutoReclaimImpl + * + * @author wangxiangyong + * @since 2020-11-30 + **/ +public class VmfsDatastoreSpaceUtilizationImpl extends BaseBestPracticeService implements BestPracticeService { + private final Logger logger = LoggerFactory.getLogger(BaseBestPracticeService.class); + + private final Map CAPACITY_MAP = new ConcurrentHashMap<>(); + + private String DEFAULT_RECOMMAND_VALUE = "80%"; + + private VmfsOperationService vmfsOperationService; + + private DmeVmwareRalationDao dmeVmwareRalationDao; + + private BestPracticeCheckDao bestPracticeCheckDao; + + public void setVmfsOperationService(VmfsOperationService vmfsOperationService) { + this.vmfsOperationService = vmfsOperationService; + } + + public void setDmeVmwareRalationDao(DmeVmwareRalationDao dmeVmwareRalationDao) { + this.dmeVmwareRalationDao = dmeVmwareRalationDao; + } + + public void setBestPracticeCheckDao(BestPracticeCheckDao bestPracticeCheckDao) { + this.bestPracticeCheckDao = bestPracticeCheckDao; + } + + @Override + public String getHostSetting() { + return "VMFS Datastore Space Utilization"; + } + + @Override + public Object getRecommendValue() { + //通过查询数据库获取,默认为80% + try { + BestPracticeRecommand bestPracticeRecommand = bestPracticeCheckDao.getRecommand(getHostSetting(), + DEFAULT_RECOMMAND_VALUE); + return bestPracticeRecommand.getRecommandValue(); + } catch (DmeSqlException ex) { + logger.error("get vmfs recommand value error,return default value 80%!", ex); + } + return "80%"; + } + + @Override + public Object getCurrentValue(VCSDKUtils vcsdkUtils, String objectId) throws Exception { + DatastoreSummary summary = getSummary(vcsdkUtils, objectId); + double capacity = (double) summary.getCapacity(); + double freeSpace = (double) summary.getFreeSpace(); + double used = capacity - freeSpace; + double rate = used / capacity * 100; + String rateStr = new DecimalFormat("#.00").format(rate) + "%"; + return rateStr; + } + + @Override + public String getLevel() { + return "Warning"; + } + + @Override + public boolean needReboot() { + return false; + } + + @Override + public boolean autoRepair() { + return true; + } + + @Override + public boolean check(VCSDKUtils vcsdkUtils, String objectId) throws Exception { + DatastoreSummary summary = getSummary(vcsdkUtils, objectId); + // 不可访问的VMFS存储直接不检查 + if (!summary.isAccessible()) { + logger.info("存储'{}'不可访问,不进行最佳实践操作!", summary.getName()); + return true; + } + + // 每次检查的时候刷新缓存,提供给update使用避免重复查询 + CAPACITY_MAP.put(objectId, summary); + double capacity = (double) summary.getCapacity(); + double freeSpace = (double) summary.getFreeSpace(); + double used = capacity - freeSpace; + double rate = used / capacity * 100; + String recommendValue = ((String) getRecommendValue()).split("%")[0]; + // 超过预定值则认为违规 + if (Double.compare(rate, Double.valueOf(recommendValue)) > 0) { + return false; + } + return true; + } + + @Override + public void update(VCSDKUtils vcsdkUtils, String objectId) throws Exception { + DatastoreSummary summary = CAPACITY_MAP.get(objectId); + if (summary == null) { + summary = getSummary(vcsdkUtils, objectId); + } + // 以步长10%进行扩容 + double capacity = summary.getCapacity(); + double freeSpace = summary.getFreeSpace(); + double used = capacity - freeSpace; + String recommendStr = String.valueOf(getRecommendValue()); + double recommendDouble = new Double(recommendStr.substring(0, recommendStr.indexOf("%"))) / 100; + double needCapacity = used / recommendDouble; + double stepCapacity = capacity * 1.1; + double addCapacityD = capacity * 0.1; + if (needCapacity > stepCapacity) { + addCapacityD = (needCapacity - capacity); + logger.info("{}, A 10 percent growth rate is not enough!Updated The new capacity to {}", + capacity * 0.1 / GI, addCapacityD / GI); + } + double addCapacityGB = addCapacityD / GI; + int addCapacity = addCapacityGB % 1 == 0 ? (int) addCapacityGB : (int) (addCapacityGB / 1) + 1; + String volume_id = dmeVmwareRalationDao.getVolumeIdlByStoreId(objectId); + + Map volumes = new HashMap<>(); + volumes.put("capacityUnit", "GB"); + volumes.put("obj_id", objectId); + volumes.put("ds_name", summary.getName()); + volumes.put("vo_add_capacity", Integer.toString(addCapacity)); + volumes.put("volume_id", volume_id); + vmfsOperationService.expandVmfs2(volumes); + logger.info("最佳实践VMFS扩容成功!增加容量:{}GB", addCapacity); + } + + @Override + public String repairAction() { + try { + BestPracticeRecommand bestPracticeRecommand = bestPracticeCheckDao.getRecommand(getHostSetting(), + DEFAULT_RECOMMAND_VALUE); + return bestPracticeRecommand.getRepairAction(); + } catch (DmeSqlException ex) { + logger.error("get vmfs repair action error,return default value 0!", ex); + } + + return "0"; + } + + private DatastoreSummary getSummary(VCSDKUtils vcsdkUtils, String objectId) throws Exception { + ManagedObjectReference mor = vcsdkUtils.getVcConnectionHelper().objectId2Mor(objectId); + VmwareContext context = vcsdkUtils.getVcConnectionHelper().getServerContext(objectId); + DatastoreMo datastoreMo = DatastoreVmwareMoFactory.getInstance().build(context, mor); + return datastoreMo.getSummary(); + } + +}