/*************************************************************************** * Copyright (c) 2012-2015 VMware, Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ package com.vmware.bdd.manager; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import com.vmware.bdd.apitypes.*; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.hibernate.Hibernate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import com.vmware.aurora.vc.VcVirtualMachine; import com.vmware.bdd.aop.annotation.RetryTransaction; import com.vmware.bdd.dal.IClusterDAO; import com.vmware.bdd.dal.INetworkDAO; import com.vmware.bdd.dal.INodeDAO; import com.vmware.bdd.dal.INodeGroupDAO; import com.vmware.bdd.dal.INodeTemplateDAO; import com.vmware.bdd.dal.IResourcePoolDAO; import com.vmware.bdd.dal.IServerInfoDAO; import com.vmware.bdd.entity.ClusterEntity; import com.vmware.bdd.entity.DiskEntity; import com.vmware.bdd.entity.NicEntity; import com.vmware.bdd.entity.NodeEntity; import com.vmware.bdd.entity.NodeGroupEntity; import com.vmware.bdd.entity.NodeTemplateEntity; import com.vmware.bdd.entity.ServerInfoEntity; import com.vmware.bdd.entity.VcResourcePoolEntity; import com.vmware.bdd.exception.BddException; import com.vmware.bdd.manager.i18n.Messages; import com.vmware.bdd.manager.intf.IClusterEntityManager; import com.vmware.bdd.software.mgmt.plugin.intf.SoftwareManager; import com.vmware.bdd.software.mgmt.plugin.model.ClusterBlueprint; import com.vmware.bdd.software.mgmt.plugin.model.HadoopStack; import com.vmware.bdd.software.mgmt.plugin.model.NodeGroupInfo; import com.vmware.bdd.software.mgmt.plugin.model.NodeInfo; import com.vmware.bdd.software.mgmt.plugin.monitor.ClusterReport; import com.vmware.bdd.software.mgmt.plugin.monitor.NodeReport; import com.vmware.bdd.software.mgmt.thrift.GroupData; import com.vmware.bdd.software.mgmt.thrift.OperationStatusWithDetail; import com.vmware.bdd.software.mgmt.thrift.ServerData; import com.vmware.bdd.usermgmt.UserMgmtConstants; import com.vmware.bdd.utils.*; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.hibernate.Hibernate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.util.*; @Transactional(readOnly = true) public class ClusterEntityManager implements IClusterEntityManager, Observer { private static final Logger logger = Logger .getLogger(ClusterEntityManager.class); private IClusterDAO clusterDao; private INodeGroupDAO nodeGroupDao; private INodeDAO nodeDao; @Autowired private INodeTemplateDAO nodeTemplateDAO; private INetworkDAO networkDAO; private IResourcePoolDAO rpDao; private IServerInfoDAO serverInfoDao; private SoftwareManagerCollector softwareManagerCollector; @Override public IServerInfoDAO getServerInfoDao() { return serverInfoDao; } @Autowired public void setServerInfoDao(IServerInfoDAO serverInfoDao) { this.serverInfoDao = serverInfoDao; } public IClusterDAO getClusterDao() { return clusterDao; } @Autowired public void setClusterDao(IClusterDAO clusterDao) { this.clusterDao = clusterDao; } public INodeGroupDAO getNodeGroupDao() { return nodeGroupDao; } @Autowired public void setNodeGroupDao(INodeGroupDAO nodeGroupDao) { this.nodeGroupDao = nodeGroupDao; } public INodeDAO getNodeDao() { return nodeDao; } @Autowired public void setNodeDao(INodeDAO nodeDao) { this.nodeDao = nodeDao; } public INetworkDAO getNetworkDAO() { return networkDAO; } @Autowired public void setNetworkDAO(INetworkDAO networkDAO) { this.networkDAO = networkDAO; } @Autowired public void setRpDao(IResourcePoolDAO rpDao) { this.rpDao = rpDao; } @Autowired public void setSoftwareManagerCollector( SoftwareManagerCollector softwareManagerCollector) { this.softwareManagerCollector = softwareManagerCollector; } @Override public SoftwareManagerCollector getSoftwareManagerCollector() { return this.softwareManagerCollector; } @Override public ClusterEntity findClusterById(Long id) { return clusterDao.findById(id); } @Override public NodeGroupEntity findNodeGroupById(Long id) { return nodeGroupDao.findById(id); } @Override public NodeEntity findNodeById(Long id) { return nodeDao.findById(id); } @Override public ClusterEntity findByName(String clusterName) { return clusterDao.findByName(clusterName); } @Override public ClusterRead findClusterWithNodeGroups(String clusterName) { ClusterEntity cluster = clusterDao.findWithNodeGroups(clusterName); ClusterRead clusterRead = RestObjectManager.clusterEntityToRead(cluster); SoftwareManager softMgr = null; try { softMgr = softwareManagerCollector.getSoftwareManager(cluster.getAppManager()); } catch (Exception e) { logger.error("Failed to get softwareManger."); // do not throw exception for exporting cluster info } int clusterInstanceNum = 0; List<NodeGroupRead> ngReads = new ArrayList<>(); for(NodeGroupEntity ng: cluster.getNodeGroupsSortedById()) { NodeGroupRead ngRead = RestObjectManager.nodeGroupEntityToRead(ng); int instanceNum = this.nodeDao.getCountByNodeGroup(ng.getId()); ngRead.setInstanceNum(instanceNum); clusterInstanceNum += instanceNum; ngRead.setComputeOnly(false); try { ngRead.setComputeOnly(softMgr.isComputeOnlyRoles(ngRead.getRoles())); } catch (Exception e) { } ngReads.add(ngRead); } clusterRead.setNodeGroups(ngReads); clusterRead.setInstanceNum(clusterInstanceNum); setNodeTemplateName(clusterRead, cluster.getTemplateId()); return clusterRead; } @Override public ClusterRead findClusterWithNodes(String clusterName, boolean includeVolumes) { ClusterEntity cluster = clusterDao.findWithNodes(clusterName, includeVolumes); ClusterRead clusterRead = RestObjectManager.clusterEntityToRead(cluster); SoftwareManager softMgr = null; try { softMgr = softwareManagerCollector.getSoftwareManager(cluster.getAppManager()); } catch (Exception e) { logger.error("Failed to get softwareManger."); // do not throw exception for exporting cluster info } int clusterInstanceNum = 0; List<NodeGroupRead> ngReads = new ArrayList<>(); List<VcResourcePoolEntity> rps = new ArrayList<>(); for(NodeGroupEntity ng: cluster.getNodeGroupsSortedById()) { NodeGroupRead ngRead = RestObjectManager.nodeGroupEntityToRead(ng); List<NodeRead> nodeReads = new ArrayList<>(); for(NodeEntity node: ng.getNodes()) { nodeReads.add(RestObjectManager.nodeEntityToRead(node, includeVolumes)); } ngRead.setInstances(nodeReads); int instanceNum = this.nodeDao.getCountByNodeGroup(ng.getId()); ngRead.setInstanceNum(instanceNum); clusterInstanceNum += instanceNum; try { ngRead.setComputeOnly(softMgr.isComputeOnlyRoles(ngRead.getRoles())); } catch (Exception e) { } ngReads.add(ngRead); List<VcResourcePoolEntity> rpsNg = this.rpDao.findUsedRpsByNodeGroup(ng.getId()); if(rpsNg != null && !rpsNg.isEmpty()) { rps.addAll(rpsNg); } logger.debug("findClusterWithNodes rps size:" + rps.size()); } clusterRead.setNodeGroups(ngReads); clusterRead.setInstanceNum(clusterInstanceNum); setNodeTemplateName(clusterRead, cluster.getTemplateId()); List<ResourcePoolRead> rpReads = new ArrayList<ResourcePoolRead>(); Set<Long> processedRpIds = new HashSet<>(); for (VcResourcePoolEntity rp : rps) { if(!processedRpIds.contains(rp.getId())) { ResourcePoolRead rpRead = RestObjectManager.vcResourcePoolEntityToRead(rp); rpRead.setNodes(null); rpReads.add(rpRead); processedRpIds.add(rp.getId()); } } logger.debug("findClusterWithNodes rpReads size:" + rpReads.size()); clusterRead.setResourcePools(rpReads); return clusterRead; } //Set node template name for ClusterRead object private void setNodeTemplateName(ClusterRead clusterRead, String templateId) { NodeTemplateEntity template = null; if(templateId != null) { template = this.nodeTemplateDAO.findByMoid(templateId); } if(template != null) { clusterRead.setTemplateName(template.getName()); } else { logger.warn("NodeTemplateEntity not found, templateId=[" + templateId + "]"); String notFound = Messages.getString("CLUSTER_MANAGER.NODE_TEMPLATE_NOT_FOUND"); clusterRead.setTemplateName(notFound); } } public Map<String, Map<String, String>> findInfraConfig(String clusterName) { String infraCfgStr = clusterDao.findInfraConfig(clusterName); if(!StringUtils.isBlank(infraCfgStr)) { ObjectMapper objectMapper = new ObjectMapper(); try { return objectMapper.readValue(infraCfgStr, Map.class); } catch (IOException e) { throw new RuntimeException("failed to parse infra config string from cluster table!"); } } return null; } @Override public Map<String, String> findUserMgmtCfg(String clusterName) { Map<String, Map<String, String>> infraCfg = findInfraConfig(clusterName); if(infraCfg != null) { return infraCfg.get(UserMgmtConstants.LDAP_USER_MANAGEMENT); } else { return null; } } @Override public NodeGroupEntity findByName(String clusterName, String groupName) { return nodeGroupDao.findByName(clusterDao.findByName(clusterName), groupName); } @Override public NodeGroupEntity findByName(ClusterEntity cluster, String groupName) { return nodeGroupDao.findByName(cluster, groupName); } @Override public NodeEntity findByName(String clusterName, String groupName, String nodeName) { return nodeDao.findByName(findByName(clusterName, groupName), nodeName); } @Override public NodeEntity findByName(NodeGroupEntity nodeGroup, String nodeName) { return nodeDao.findByName(nodeGroup, nodeName); } @Override public NodeEntity findNodeByName(String nodeName) { return nodeDao.findByName(nodeName); } @Override public List<String> findByAppManager(String appManagerName) { return clusterDao.findClustersByAppManager(appManagerName); } @Override public List<ClusterEntity> findAllClusters() { return clusterDao.findAll(); } @Override public List<String> findAllClusterNames() { return clusterDao.findAllClusterNames(); } @Override public List<NodeGroupEntity> findAllGroups(String clusterName) { List<ClusterEntity> clusters = new ArrayList<ClusterEntity>(); ClusterEntity cluster = clusterDao.findByName(clusterName); clusters.add(cluster); return nodeGroupDao.findAllByClusters(clusters); } @Override public List<NodeEntity> findAllNodes(String clusterName) { return clusterDao.getAllNodes(clusterName); } @Override public List<NodeEntity> findAllNodes(String clusterName, String groupName) { NodeGroupEntity nodeGroup = findByName(clusterName, groupName); return new ArrayList<NodeEntity>(nodeGroup.getNodes()); } @Override @Transactional @RetryTransaction public void insert(ClusterEntity cluster) { AuAssert.check(cluster != null); clusterDao.insert(cluster); } @Override @Transactional @RetryTransaction public void insert(NodeEntity node) { AuAssert.check(node != null); nodeDao.insert(node); } @Override @Transactional @RetryTransaction public void insert(NodeGroupEntity nodegroup) { AuAssert.check(nodegroup != null); logger.info("ClusterEntityManager" + nodegroup); nodeGroupDao.insert(nodegroup); } @Override @Transactional @RetryTransaction public void delete(NodeEntity node) { AuAssert.check(node != null); // remove from parent's collection by cascading NodeGroupEntity parent = node.getNodeGroup(); parent.getNodes().remove(node); nodeDao.delete(node); } @Override @Transactional @RetryTransaction public void delete(ClusterEntity cluster) { AuAssert.check(cluster != null); clusterDao.delete(cluster); } @Override @Transactional @RetryTransaction public void updateClusterStatus(String clusterName, ClusterStatus status) { clusterDao.updateStatus(clusterName, status); } @Override @Transactional @RetryTransaction public void updateNodesActionForUpgrade(String clusterName, String action) { List<NodeEntity> nodes = clusterDao.getAllNodes(clusterName); for (NodeEntity node : nodes) { updateNodeActionForUpgrade(node, action); } } @Override @Transactional @RetryTransaction public void updateNodeActionForUpgrade(NodeEntity node, String action) { if (node.needUpgrade(getServerVersion()) && node.canBeUpgrade()) { nodeDao.updateAction(node.getMoId(), action); } } @Override @Transactional @RetryTransaction public void update(ClusterEntity clusterEntity) { clusterDao.update(clusterEntity); } @Override @Transactional @RetryTransaction public void update(NodeGroupEntity group) { nodeGroupDao.update(group); } @Override @Transactional @RetryTransaction public void update(NodeEntity node) { nodeDao.update(node); } @Override @Transactional @RetryTransaction public void updateDisks(String nodeName, List<DiskEntity> diskSets) { NodeEntity node = findNodeByName(nodeName); for (DiskEntity disk : diskSets) { boolean found = false; for (DiskEntity old : node.getDisks()) { if (disk.getName().equals(old.getName())) { found = true; old.setDatastoreName(disk.getDatastoreName()); old.setDatastoreMoId(disk.getDatastoreMoId()); old.setVmdkPath(disk.getVmdkPath()); old.setSizeInMB(disk.getSizeInMB()); } } if (!found) { disk.setNodeEntity(node); node.getDisks().add(disk); } } } @Override @Transactional @RetryTransaction public boolean handleOperationStatus(String clusterName, OperationStatusWithDetail status, boolean lastUpdate) { logger.info("handle operation status: " + status.getOperationStatus()); boolean finished = status.getOperationStatus().isFinished(); final Map<String, GroupData> groups = status.getClusterData().getGroups(); ClusterEntity cluster = findByName(clusterName); AuAssert.check(cluster.getId() != null); for (NodeGroupEntity group : cluster.getNodeGroups()) { for (String groupName : groups.keySet()) { if (groupName.equals(group.getName())) { for (ServerData serverData : groups.get(groupName) .getInstances()) { logger.debug("server data: " + serverData.getName() + ", action:" + serverData.getAction() + ", status:" + serverData.getStatus()); Iterator<NodeEntity> iter = group.getNodes().iterator(); while (iter.hasNext()) { NodeEntity oldNode = iter.next(); if (oldNode.getVmName().equals(serverData.getName())) { logger.debug("old node:" + oldNode.getVmName() + ", status: " + oldNode.getStatus()); oldNode.setAction(serverData.getAction()); logger.debug("node status: " + NodeStatus.fromString(serverData.getStatus())); String errorMsg = serverData.getError_msg(); if (lastUpdate && errorMsg != null && !errorMsg.isEmpty()) { oldNode.setActionFailed(true); oldNode.setErrMessage(errorMsg); logger.debug("error message: " + errorMsg); } if (!oldNode.isDisconnected()) { oldNode.setStatus( NodeStatus.fromString(serverData.getStatus()), false); logger.debug("new node:" + oldNode.getVmName() + ", status: " + oldNode.getStatus()); } else { logger.debug("do not override node status for disconnected node."); } update(oldNode); break; } } } } } } logger.debug("updated database"); return finished; } @Override @Transactional @RetryTransaction public void setClusterStatus(String clusterName, ClusterReport report) { // process cluster status handleClusterStatus(clusterName, report); // process node status handleNodeStatus(report, true); } private void handleClusterStatus(String clusterName, ClusterReport report) { ClusterEntity cluster = findByName(clusterName); ClusterStatus oldState = cluster.getStatus(); switch (oldState) { case RUNNING: case SERVICE_STOPPED: case SERVICE_WARNING: switch (report.getStatus()) { case STARTED: cluster.setStatus(ClusterStatus.RUNNING); break; case ALERT: cluster.setStatus(ClusterStatus.SERVICE_WARNING); break; case STOPPED: cluster.setStatus(ClusterStatus.SERVICE_STOPPED); break; default: break; } logger.info("Got status " + report.getStatus() + " for cluster " + clusterName + ", change cluster status from " + oldState + " to " + cluster.getStatus()); break; default: logger.debug("In status " + cluster.getStatus() + ". Do not change cluster status based on service status change."); break; } } @Override @Transactional @RetryTransaction public boolean handleOperationStatus(String clusterName, ClusterReport report, boolean lastUpdate) { handleClusterStatus(clusterName, report); return handleNodeStatus(report, lastUpdate); } private boolean handleNodeStatus(ClusterReport report, boolean lastUpdate) { boolean finished = report.isFinished(); ClusterEntity cluster = findByName(report.getName()); Map<String, NodeReport> nodeReportMap = report.getNodeReports(); for (NodeGroupEntity group : cluster.getNodeGroups()) { for (NodeEntity node : group.getNodes()) { NodeReport nodeReport = nodeReportMap.get(node.getVmName()); if (nodeReport == null) { continue; } if (nodeReport.getStatus() != null) { if (!node.isDisconnected() && node.getStatus().ordinal() >= NodeStatus.VM_READY .ordinal()) { logger.debug("Got node " + node.getVmName() + " status " + nodeReport.getStatus().toString()); NodeStatus oldStatus = node.getStatus(); switch (nodeReport.getStatus()) { case STARTED: node.setStatus(NodeStatus.SERVICE_READY, false); break; case UNHEALTHY: node.setStatus(NodeStatus.SERVICE_UNHEALTHY, false); break; case ALERT: if (node.getStatus() != NodeStatus.BOOTSTRAP_FAILED) { node.setStatus(NodeStatus.SERVICE_ALERT, false); } break; case UNKONWN: node.setStatus(NodeStatus.UNKNOWN, false); break; case PROVISIONING: case STOPPED: if (node.getStatus() != NodeStatus.BOOTSTRAP_FAILED) { node.setStatus(NodeStatus.VM_READY, false); } break; default: node.setStatus(NodeStatus.BOOTSTRAP_FAILED, false); } logger.debug("node:" + node.getVmName() + ", status changed from old status: " + oldStatus + " to new status: " + node.getStatus()); } } if (nodeReport.isUseClusterMsg() && report.getAction() != null) { logger.debug("set node action to:" + report.getAction()); node.setAction(report.getAction()); } else if (nodeReport.getAction() != null) { node.setAction(nodeReport.getAction()); } if (lastUpdate) { if (nodeReport.getErrMsg() != null) { logger.debug("set node error message to:" + report.getAction()); node.setErrMessage(nodeReport.getErrMsg()); node.setActionFailed(true); } else { logger.debug("clear node error message for node " + node.getHostName()); node.setErrMessage(null); node.setActionFailed(false); } } } } return finished; } private void setNotExist(NodeEntity node) { logger.debug("vm " + node.getVmName() + " does not exist. Update node status to NOT_EXIST."); node.setStatus(NodeStatus.NOT_EXIST); node.resetNicsInfo(); node.setMoId(null); if (node.getAction() != null && !(node.getAction().equals(Constants.NODE_ACTION_CLONING_VM)) && !(node.getAction().equals(Constants.NODE_ACTION_CLONING_FAILED))) { node.setAction(null); } update(node); } /* @Transactional @RetryTransaction public void syncUp(String clusterName, boolean updateClusterStatus) { List<NodeEntity> nodes = findAllNodes(clusterName); boolean allNodesDown = true; for (NodeEntity node : nodes) { refreshNodeStatus(node, false); if (node.getStatus().ordinal() >= NodeStatus.POWERED_ON.ordinal()) { allNodesDown = false; } } if (updateClusterStatus && allNodesDown) { ClusterEntity cluster = findByName(clusterName); if (cluster.getStatus() == ClusterStatus.RUNNING) { logger.info("All nodes are powered off, switch cluster status to stopped."); cluster.setStatus(ClusterStatus.STOPPED); } } }*/ @Override @Transactional @RetryTransaction public void removeVmReference(String vmId) { NodeEntity node = nodeDao.findByMobId(vmId); if (node != null) { setNotExist(node); } } @Override @Transactional @RetryTransaction public void syncUpNode(String clusterName, String nodeName) { NodeEntity node = findNodeByName(nodeName); if (node != null) { refreshNodeStatus(node, false); } } @Override @Transactional @RetryTransaction public List<String> getPortGroupNames(String clusterName) { ClusterEntity clusterEntity = clusterDao.findByName(clusterName); List<String> portGroups = new ArrayList<String>(); for (String networkName : clusterEntity.fetchNetworkNameList()) { portGroups.add(networkDAO.findNetworkByName(networkName) .getPortGroup()); } return portGroups; } @Override @Transactional public NodeRead refreshNodeStatus(String vmName, boolean inSession) { NodeEntity nodeEntity = nodeDao.findByName(vmName); refreshNodeStatus(nodeEntity, inSession); return nodeEntity.toNodeRead(false); } private void refreshNodeStatus(NodeEntity node, boolean inSession) { VcVirtualMachine vcVm = ClusterUtil.getVcVm(this, node); if (vcVm == null) { // vm is deleted setNotExist(node); return; } if (!vcVm.isConnected() || vcVm.getHost().isUnavailbleForManagement()) { node.setUnavailableConnection(); return; } // TODO: consider more status if (!vcVm.isPoweredOn()) { node.setStatus(NodeStatus.POWERED_OFF); node.resetNicsInfo(); } else { node.setStatus(NodeStatus.POWERED_ON); } if (vcVm.isPoweredOn()) { //update ip address for (NicEntity nicEntity : node.getNics()) { VcVmUtil.populateNicInfo(nicEntity, node.getMoId(), nicEntity .getNetworkEntity().getPortGroup()); } if (node.nicsReady()) { node.setStatus(NodeStatus.VM_READY); if (node.getAction() != null && (node.getAction().equals(Constants.NODE_ACTION_WAITING_IP) || node .getAction().equals(Constants.NODE_ACTION_RECONFIGURE))) { node.setAction(null); } } String guestHostName = VcVmUtil.getGuestHostName(vcVm, inSession); if (guestHostName != null) { node.setGuestHostName(guestHostName); } } node.setHostName(vcVm.getHost().getName()); update(node); } @Override public ClusterBlueprint toClusterBluePrint(String clusterName) { ClusterEntity clusterEntity = findByName(clusterName); ClusterBlueprint blueprint = new ClusterBlueprint(); Gson gson = new Gson(); blueprint.setName(clusterEntity.getName()); blueprint.setInstanceNum(clusterEntity.getRealInstanceNum(true)); // set rack topology blueprint.setTopologyPolicy(clusterEntity.getTopologyPolicy()); // set cluster software configuration if (clusterEntity.getHadoopConfig() != null) { @SuppressWarnings("unchecked") Map<String, Object> clusterConfigs = gson.fromJson(clusterEntity.getHadoopConfig(), Map.class); blueprint.setConfiguration(clusterConfigs); } // set HadoopStack HadoopStack hadoopStack = new HadoopStack(); hadoopStack.setDistro(clusterEntity.getDistro()); hadoopStack.setVendor(clusterEntity.getDistroVendor()); hadoopStack.setFullVersion(clusterEntity.getDistroVersion()); blueprint.setHadoopStack(hadoopStack); // set nodes/nodegroups List<NodeGroupInfo> nodeGroupInfos = new ArrayList<NodeGroupInfo>(); for (NodeGroupEntity group : clusterEntity.getNodeGroups()) { NodeGroupInfo nodeGroupInfo = toNodeGroupInfo(group); nodeGroupInfos.add(nodeGroupInfo); } blueprint.setNodeGroups(nodeGroupInfos); // set external HDFS, Mapreduce, Namenode, Datanodes Map<String, String> advancedProperties = gson.fromJson(clusterEntity.getAdvancedProperties(), Map.class); if (advancedProperties != null) { blueprint.setExternalHDFS(advancedProperties.get("ExternalHDFS")); blueprint.setExternalHDFS(advancedProperties.get("ExternalMapReduce")); blueprint.setExternalNamenode(advancedProperties.get("ExternalNamenode")); blueprint.setExternalSecondaryNamenode(advancedProperties.get("ExternalSecondaryNamenode")); if (advancedProperties.get("ExternalDatanodes") != null) { blueprint.setExternalDatanodes(gson.fromJson(gson.toJson(advancedProperties.get("ExternalDatanodes")), HashSet.class)); } } return blueprint; } private NodeGroupInfo toNodeGroupInfo(NodeGroupEntity group) { Gson gson = new Gson(); NodeGroupInfo nodeGroupInfo = new NodeGroupInfo(); nodeGroupInfo.setName(group.getName()); nodeGroupInfo.setInstanceNum(group.getRealInstanceNum(true)); nodeGroupInfo.setRoles(gson.fromJson(group.getRoles(), List.class)); if (group.getHadoopConfig() != null) { Map<String, Object> groupConfigs = gson.fromJson(group.getHadoopConfig(), Map.class); nodeGroupInfo.setConfiguration(groupConfigs); } if (group.getHaFlag().equalsIgnoreCase(Constants.HA_FLAG_FT) || group.getHaFlag().equalsIgnoreCase(Constants.HA_FLAG_ON)) { nodeGroupInfo.setHaEnabled(true); } if(group.getLatencySensitivity() != null && !CommonUtil.isBlank(group.getLatencySensitivity().name())) nodeGroupInfo.setLatencySensitivity(group.getLatencySensitivity()); else nodeGroupInfo.setLatencySensitivity(LatencyPriority.NORMAL); nodeGroupInfo.setInstanceType(group.getNodeType()); nodeGroupInfo.setStorageSize(group.getStorageSize()); nodeGroupInfo.setStorageType(group.getStorageType().name()); nodeGroupInfo.setMemorySize(group.getMemorySize()); // set nodes List<NodeInfo> nodeInfos = new ArrayList<NodeInfo>(); for (NodeEntity node : group.getNodes()) { NodeInfo nodeInfo = new NodeInfo(); nodeInfo.setName(node.getVmName()); nodeInfo.setHostname(node.getGuestHostName()); nodeInfo.setIpConfigs(node.convertToIpConfigInfo()); nodeInfo.setRack(node.getRack()); nodeInfo.setVolumes(node.getDataVolumnsMountPoint()); nodeInfos.add(nodeInfo); } nodeGroupInfo.setNodes(nodeInfos); return nodeGroupInfo; } @Override public NodeGroupInfo toNodeGroupInfo(String clusterName, String groupName) { NodeGroupEntity group = findByName(clusterName, groupName); return toNodeGroupInfo(group); } @Deprecated @Override public ClusterRead toClusterRead(String clusterName, boolean withNodesList) { return toClusterRead(clusterName, withNodesList, false); } @Deprecated @Override @SuppressWarnings("rawtypes") public ClusterRead toClusterRead(String clusterName, boolean withNodesList, boolean ignoreObsoleteNode) { ClusterEntity cluster = findByName(clusterName); if (cluster == null) { throw BddException.NOT_FOUND("Cluster", clusterName); } ClusterStatus clusterStatus = cluster.getStatus(); ClusterRead clusterRead = new ClusterRead(); clusterRead .setInstanceNum(cluster.getRealInstanceNum(ignoreObsoleteNode)); clusterRead.setName(cluster.getName()); clusterRead.setStatus(clusterStatus); clusterRead.setAppManager(cluster.getAppManager()); clusterRead.setDistro(cluster.getDistro()); clusterRead.setDistroVendor(cluster.getDistroVendor()); clusterRead.setTopologyPolicy(cluster.getTopologyPolicy()); clusterRead.setTemplateName(nodeTemplateDAO.findByMoid(cluster.getTemplateId()).getName()); clusterRead.setAutomationEnable(cluster.getAutomationEnable()); clusterRead.setVhmMinNum(cluster.getVhmMinNum()); clusterRead.setVhmMaxNum(cluster.getVhmMaxNum()); clusterRead.setVhmTargetNum(cluster.getVhmTargetNum()); clusterRead.setIoShares(cluster.getIoShares()); clusterRead.setVersion(cluster.getVersion()); if (!CommonUtil.isBlank(cluster.getAdvancedProperties())) { Gson gson = new Gson(); Map<String, String> advancedProperties = gson.fromJson(cluster.getAdvancedProperties(), Map.class); clusterRead.setExternalHDFS(advancedProperties.get("ExternalHDFS")); clusterRead.setExternalMapReduce(advancedProperties .get("ExternalMapReduce")); clusterRead.setLocalRepoURL(advancedProperties.get("LocalRepoURL")); clusterRead.setClusterCloneType(advancedProperties.get("ClusterCloneType")); clusterRead.setExternalNamenode(advancedProperties.get("ExternalNamenode")); clusterRead.setExternalSecondaryNamenode(advancedProperties.get("ExternalSecondaryNamenode")); if (advancedProperties.get("ExternalDatanodes") != null) { clusterRead.setExternalDatanodes(gson.fromJson(gson.toJson(advancedProperties.get("ExternalDatanodes")), HashSet.class)); } } String cloneType = clusterRead.getClusterCloneType(); if (CommonUtil.isBlank(cloneType)) { // for clusters from previous releases, it should be fast clone clusterRead.setClusterCloneType(Constants.CLUSTER_CLONE_TYPE_FAST_CLONE); } SoftwareManager softMgr = null; try { softMgr = softwareManagerCollector.getSoftwareManager(cluster .getAppManager()); } catch (Exception e) { logger.error("Failed to get softwareManger."); // do not throw exception for exporting cluster info } List<NodeGroupRead> groupList = new ArrayList<NodeGroupRead>(); for (NodeGroupEntity group : cluster.getNodeGroups()) { NodeGroupRead groupRead = group.toNodeGroupRead(withNodesList, ignoreObsoleteNode); groupRead.setComputeOnly(false); try { groupRead.setComputeOnly(softMgr.isComputeOnlyRoles(groupRead .getRoles())); } catch (Exception e) { } groupList.add(groupRead); } clusterRead.setNodeGroups(groupList); Set<VcResourcePoolEntity> rps = cluster.getUsedRps(); List<ResourcePoolRead> rpReads = new ArrayList<ResourcePoolRead>(rps.size()); for (VcResourcePoolEntity rp : rps) { ResourcePoolRead rpRead = rp.toRest(); rpRead.setNodes(null); rpReads.add(rpRead); } clusterRead.setResourcePools(rpReads); if (clusterStatus.isActiveServiceStatus() || clusterStatus == ClusterStatus.STOPPED) { clusterRead.setDcSeperation(clusterRead.validateSetManualElasticity()); } if(StringUtils.isNotBlank(cluster.getInfraConfig())) { clusterRead.setInfrastructure_config(InfrastructureConfigUtils.read(cluster.getInfraConfig())); } return clusterRead; } @Override @Transactional @RetryTransaction public void refreshNodeByMobId(String vmId, boolean inSession) { NodeEntity node = nodeDao.findByMobId(vmId); if (node != null) { refreshNodeStatus(node, inSession); } } @Override @Transactional @RetryTransaction public void setNodeConnectionState(String vmName) { NodeEntity node = nodeDao.findByName(vmName); if (node != null) { node.setUnavailableConnection(); } } @Override @Transactional @RetryTransaction public void refreshNodeByMobId(String vmId, String action, boolean inSession) { NodeEntity node = nodeDao.findByMobId(vmId); if (node != null) { node.setAction(action); refreshNodeStatus(node, inSession); } } @Override public NodeEntity getNodeByMobId(String vmId) { return nodeDao.findByMobId(vmId); } @Override @Transactional public NodeEntity getNodeWithNicsByMobId(String vmId) { NodeEntity nodeEntity = nodeDao.findByMobId(vmId); Hibernate.initialize(nodeEntity.getNics()); return nodeEntity; } @Override public NodeEntity getNodeByVmName(String vmName) { return nodeDao.findByName(vmName); } @Override public List<NodeEntity> getNodesByHost(String hostName) { return nodeDao.findByHostName(hostName); } @Override @Transactional @RetryTransaction public void refreshNodeByVmName(String vmId, String vmName, boolean inSession) { NodeEntity node = nodeDao.findByName(vmName); if (node != null) { node.setMoId(vmId); refreshNodeStatus(node, inSession); } } @Override @Transactional @RetryTransaction public void refreshNodeByVmName(String vmId, String vmName, String nodeAction, boolean inSession) { NodeEntity node = nodeDao.findByName(vmName); if (node != null) { node.setMoId(vmId); node.setAction(nodeAction); refreshNodeStatus(node, inSession); } } @Override @Transactional @RetryTransaction public void updateClusterTaskId(String clusterName, Long taskId) { ClusterEntity cluster = clusterDao.findByName(clusterName); cluster.setLatestTaskId(taskId); clusterDao.update(cluster); } @Override public List<Long> getLatestTaskIds() { List<ClusterEntity> clusters = clusterDao.findAll(); List<Long> taskIds = new ArrayList<Long>(clusters.size()); for (ClusterEntity cluster : clusters) { taskIds.add(cluster.getLatestTaskId()); } return taskIds; } @Override public List<DiskEntity> getDisks(String nodeName) { NodeEntity node = nodeDao.findByName(nodeName); return new ArrayList<DiskEntity>(node.getDisks()); } @Override @Transactional @RetryTransaction public void cleanupActionError(String clusterName) { List<NodeEntity> nodes = findAllNodes(clusterName); for (NodeEntity node : nodes) { node.cleanupErrorMessage(); } } @Override @Transactional @RetryTransaction public boolean needUpgrade(String clusterName) { String serverVersion = getServerVersion(); String clusterVersion = findByName(clusterName).getVersion(); List<NodeEntity> nodes = findAllNodes(clusterName); boolean allNodesUpgraded = true; for (NodeEntity node : nodes) { if (node.canBeUpgrade() && node.needUpgrade(serverVersion)) { allNodesUpgraded = false; break; } } return clusterVersion == null || !serverVersion.equals(clusterVersion) || !allNodesUpgraded; } @Override @Transactional @RetryTransaction public String getServerVersion() { List<ServerInfoEntity> serverInfoEntities = getServerInfoDao().findAll(); if (serverInfoEntities.isEmpty()) { return null; } ServerInfoEntity serverInfoEntity = serverInfoEntities.get(0); String serverVersion = serverInfoEntity.getVersion(); return serverVersion; } @Override @Transactional @RetryTransaction public void storeClusterLastStatus(String clusterName) { ClusterStatus clusterStatus = clusterDao.getStatus(clusterName); if (!ClusterStatus.UPGRADE_ERROR.equals(clusterStatus) && !ClusterStatus.UPGRADING.equals(clusterStatus)) { clusterDao.updateLastStatus(clusterName, clusterStatus); } } @Override @Transactional @RetryTransaction public void cleanupErrorForClusterUpgrade(String clusterName) { List<NodeEntity> nodes = findAllNodes(clusterName); for (NodeEntity node : nodes) { node.cleanupErrorMessageForUpgrade(); } } @Override @Transactional @RetryTransaction //Sometimes, set password may take long time to finish, we'd better display the action on the cli //so that user will know the progress public void updateNodeAction(NodeEntity node, String action) { node = getNodeWithNicsByMobId(node.getMoId()); node.setAction(action); node.setActionFailed(false); node.setErrMessage(null); update(node); } @Override public void update(Observable o, Object arg) { // TODO } @Override public String getClusterVersion(String clusterName) { ClusterEntity clusterEntity = clusterDao.findByName(clusterName); return clusterEntity.getVersion(); } }