Pārlūkot izejas kodu

自动化配置,mycat重启;

demon 8 gadi atpakaļ
vecāks
revīzija
3d460020c7
23 mainītis faili ar 981 papildinājumiem un 15 dzēšanām
  1. 8 0
      hos-arbiter/src/main/java/com/yihu/hos/arbiter/HosArbiterApplication.java
  2. 6 0
      hos-arbiter/src/main/java/com/yihu/hos/arbiter/configuration/ArbiterServerConfiguration.java
  3. 39 0
      hos-arbiter/src/main/java/com/yihu/hos/arbiter/routers/MycatRouter.java
  4. 86 0
      hos-arbiter/src/main/java/com/yihu/hos/arbiter/services/MycatProxy.java
  5. 146 0
      hos-arbiter/src/main/java/com/yihu/hos/arbiter/services/MycatService.java
  6. 2 0
      hos-arbiter/src/main/resources/application.yml
  7. 1 1
      hos-broker/src/main/java/com/yihu/hos/broker/common/shell/SSHLinuxTool.java
  8. 31 0
      hos-broker/src/main/java/com/yihu/hos/broker/controllers/ESBMycatlController.java
  9. 243 0
      hos-broker/src/main/java/com/yihu/hos/broker/services/MycatConfigService.java
  10. 28 0
      hos-broker/src/main/java/com/yihu/hos/broker/services/ServerShellService.java
  11. 167 0
      hos-broker/src/main/java/com/yihu/hos/broker/util/XMLUtil.java
  12. 2 0
      hos-broker/src/main/resources/application.yml
  13. 8 2
      hos-core/pom.xml
  14. 23 0
      hos-core/src/main/java/com/yihu/hos/core/file/FileUtil.java
  15. 16 0
      hos-web-framework/src/main/java/com/yihu/hos/web/framework/constant/MycatConstant.java
  16. 11 1
      hos-web-framework/src/main/java/com/yihu/hos/web/framework/constant/ServiceFlowConstant.java
  17. 69 0
      hos-web-framework/src/main/java/com/yihu/hos/web/framework/model/bo/ServiceMycat.java
  18. 5 0
      src/main/java/com/yihu/hos/ESBApplication.java
  19. 1 0
      src/main/java/com/yihu/hos/remoteManage/controller/RemoteShellController.java
  20. 56 0
      src/main/java/com/yihu/hos/services/ServiceMycatEventService.java
  21. 7 3
      src/main/java/com/yihu/hos/tenant/service/MySqlImportAndExport.java
  22. 25 7
      src/main/java/com/yihu/hos/tenant/service/TenantService.java
  23. 1 1
      src/main/resources/application.yml

+ 8 - 0
hos-arbiter/src/main/java/com/yihu/hos/arbiter/HosArbiterApplication.java

@ -1,6 +1,7 @@
package com.yihu.hos.arbiter;
import com.yihu.hos.arbiter.configuration.ArbiterServerConfiguration;
import com.yihu.hos.arbiter.services.MycatProxy;
import com.yihu.hos.arbiter.services.ProxyService;
import com.yihu.hos.arbiter.services.ShellService;
import org.springframework.beans.factory.annotation.Autowired;
@ -18,6 +19,7 @@ public class HosArbiterApplication implements CommandLineRunner {
    private ArbiterServerConfiguration configuration;
    private ProxyService proxyService;
    private ShellService shellService;
    private MycatProxy mycatProxy;
    public static void main(String[] args) {
        SpringApplication.run(HosArbiterApplication.class, args);
@ -35,6 +37,7 @@ public class HosArbiterApplication implements CommandLineRunner {
        proxyService.start();
        shellService.start();
        mycatProxy.start();;
    }
    @Autowired
@ -51,4 +54,9 @@ public class HosArbiterApplication implements CommandLineRunner {
    public void setShellService(ShellService shellService) {
        this.shellService = shellService;
    }
    @Autowired
    public void setMycatProxy(MycatProxy mycatProxy) {
        this.mycatProxy = mycatProxy;
    }
}

+ 6 - 0
hos-arbiter/src/main/java/com/yihu/hos/arbiter/configuration/ArbiterServerConfiguration.java

@ -24,9 +24,15 @@ public class ArbiterServerConfiguration {
    private String terminalUrl;
    @Value("${arbiter.tenant.name}")
    private String tenant;
    @Value("${arbiter.mycat.name}")
    private String mycatName;
    private ZbusBroker zbusBroker;
    public String getMycatName() {
        return mycatName;
    }
    public String getCentralUrl() {
        return centralUrl;
    }

+ 39 - 0
hos-arbiter/src/main/java/com/yihu/hos/arbiter/routers/MycatRouter.java

@ -0,0 +1,39 @@
package com.yihu.hos.arbiter.routers;
import com.yihu.hos.arbiter.configuration.ActivemqConfiguration;
import com.yihu.hos.web.framework.constant.ServiceFlowConstant;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.jms.JmsComponent;
import org.apache.camel.model.ModelCamelContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.jms.ConnectionFactory;
/**
 * mycat操作  消息router
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/5.
 */
@Component
public class MycatRouter extends RouteBuilder {
    @Autowired
    private ActivemqConfiguration activemqConfiguration;
    @Override
    public void configure() throws Exception {
        ModelCamelContext context = this.getContext();
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                activemqConfiguration.getUser(), activemqConfiguration.getPassword(), activemqConfiguration.getBrokerURL());
        // Note we can explicit name the component
        context.addComponent("service.mycat.event", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
        from(ServiceFlowConstant.MYCAT_EVENT_SERVICE)
                .choice()
                .when(header("tenant").isNotNull()).to("bean:mycatService?method=proxy")
                .when(header("event").isEqualTo(ServiceFlowConstant.EXECUTE_MYCAT)).to("bean:mycatService?method=updateMycat")
                .endChoice();
    }
}

+ 86 - 0
hos-arbiter/src/main/java/com/yihu/hos/arbiter/services/MycatProxy.java

@ -0,0 +1,86 @@
package com.yihu.hos.arbiter.services;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.hos.arbiter.configuration.ArbiterServerConfiguration;
import com.yihu.hos.core.log.Logger;
import com.yihu.hos.core.log.LoggerFactory;
import com.yihu.hos.web.framework.constant.ServiceFlowConstant;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zbus.broker.ZbusBroker;
import org.zbus.mq.Consumer;
import org.zbus.net.http.Message;
import java.util.HashMap;
import java.util.Map;
/**
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/6.
 */
@Service
public class MycatProxy {
    private static final Logger logger = LoggerFactory.getLogger(MycatProxy.class);
    private CamelContext camelContext;
    private ArbiterServerConfiguration configuration;
    private ZbusBroker zbusBroker;
    private Consumer consumer;
    @Autowired
    private ObjectMapper objectMapper;
    private static Map<String,String> cunsumerNap = new HashMap<>();
    public void proxy(Message message, Consumer consumer) {
        Map<String, Object> header = new HashMap<>();
        header.put("event", message.getHead("event"));
        ProducerTemplate producerTemplate = camelContext.createProducerTemplate();
        producerTemplate.sendBodyAndHeaders(ServiceFlowConstant.MYCAT_EVENT_SERVICE, message.getBodyString(), header);
    }
    public void start() {
        if (zbusBroker == null) {
            logger.error("zbusBroker is null");
            return;
        }
        try {
            if (!cunsumerNap.containsKey(ServiceFlowConstant.MYCAT_UPDATE + "@" + configuration.getMycatName())){
                consumer = new Consumer(zbusBroker, ServiceFlowConstant.MYCAT_UPDATE + "@" + configuration.getMycatName());
                consumer.start(this::proxy);
                cunsumerNap.put(ServiceFlowConstant.MYCAT_UPDATE + "@" + configuration.getMycatName(),configuration.getMycatName());
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
    }
    @Autowired
    public void setZbusBroker(ZbusBroker zbusBroker) {
        this.zbusBroker = zbusBroker;
    }
    @Autowired
    public void setCamelContext(CamelContext camelContext) {
        this.camelContext = camelContext;
    }
    @Autowired
    public void setConfiguration(ArbiterServerConfiguration configuration) {
        this.configuration = configuration;
    }
    @Override
    protected void finalize() throws Throwable {
        consumer.close();
        super.finalize();
    }
}

+ 146 - 0
hos-arbiter/src/main/java/com/yihu/hos/arbiter/services/MycatService.java

@ -0,0 +1,146 @@
package com.yihu.hos.arbiter.services;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.hos.arbiter.models.BrokerServer;
import com.yihu.hos.core.http.HTTPResponse;
import com.yihu.hos.core.http.HttpClientKit;
import com.yihu.hos.web.framework.constant.ServiceFlowConstant;
import org.apache.camel.Body;
import org.apache.camel.Headers;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zbus.broker.ZbusBroker;
import org.zbus.mq.Producer;
import org.zbus.net.http.Message;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/5.
 */
@Service("mycatService")
public class MycatService {
    private static final Logger logger = LogManager.getLogger(MycatService.class);
    @Autowired
    private BrokerServerService brokerServerService;
    private ZbusBroker zbusBroker;
    @Autowired
    private ObjectMapper objectMapper;
    private MycatProxy mycatProxy;
    /**
     * SAAS化的管理端过来的消息会被proxy进行中转,之后发送到终端的Arbiter对Broker进行实际的控制。
     *
     * @param header 消息头部信息
     * @param msg    消息
     */
    public void proxy(@Headers Map<String, String> header, @Body String msg) {
        if (zbusBroker == null) {
            logger.error("zbusBroker is null.");
            return;
        }
        try {
            // 设置mycat 配置修改的 消息生产者
            Producer producer = new Producer(zbusBroker, ServiceFlowConstant.MYCAT_UPDATE + "@" + header.get("tenant"));
            producer.createMQ();    //确定为创建消息队列需要显示调用
            Message message = new Message();
            message.setHead("event", header.get("event"));
            message.setHead("tenant", header.get("tenant"));
            message.setMethod("POST");
            message.setBody(msg);
            message = producer.sendSync(message);
            logger.debug(message);
            mycatProxy.start();
//            System.out.println("test");
        } catch (IOException | InterruptedException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
    }
    /**
     * 发送shell命令请求到broker
     * @param msg    命令消息内容
     */
    public void updateMycat(String msg) {
        try {
            List<BrokerServer> brokerServerList  = brokerServerService.get(false);
            for (BrokerServer broker : brokerServerList) {
                String result = sendMessage(broker, "post", "/esb/serviceMycat/update", msg);
                if (result==null) {
                    logger.error("sendMessage to broker server failed, broker:" + broker.getURL() + ", msg:" + msg);
                    continue;
                }else {
                    logger.debug("发送mycat修改请求到broker成功");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
    }
    private String sendMessage(BrokerServer brokerServer, String method, String path, String msg) {
        if (brokerServer == null) {
            return null;
        }
        switch (method) {
            case "post": {
                HTTPResponse response = HttpClientKit.post(brokerServer.getURL() + path, msg);
                if (response.getStatusCode() == 200) {
                    String body = response.getBody();
                    return body;
                }
                return null;
            }
            case "put": {
                HTTPResponse response = HttpClientKit.put(brokerServer.getURL() + path, msg);
                if (response.getStatusCode() == 200) {
                    String body = response.getBody();
                    logger.debug(body);
                    return body;
                }
                return null;
            }
            case "delete": {
                HTTPResponse response = HttpClientKit.delete(brokerServer.getURL() + path, msg);
                if (response.getStatusCode() == 200) {
                    String body = response.getBody();
                    logger.debug(body);
                    return body;
                }
                return null;
            }
            default:
                break;
        }
        return null;
    }
    @Autowired
    public void setZbusBroker(ZbusBroker zbusBroker) {
        this.zbusBroker = zbusBroker;
    }
    @Autowired
    public void setMycatProxy(MycatProxy mycatProxy) {
        this.mycatProxy = mycatProxy;
    }
}

+ 2 - 0
hos-arbiter/src/main/resources/application.yml

@ -29,6 +29,8 @@ arbiter:
    url: 192.168.131.119:15555
  tenant:
    name: jkzl
  mycat:
    name: mycat192.168.75.128    ##mycat 服务器标识,规则:“mycat"+ 本机IP
---
spring:
  profiles: test

+ 1 - 1
hos-broker/src/main/java/com/yihu/hos/broker/common/shell/SSHLinuxTool.java

@ -102,7 +102,7 @@ public class SSHLinuxTool {
            }
            if (instream.available() > 0) {
                    byte[] data = new byte[instream.available()];
                byte[] data = new byte[instream.available()];
                int nLen = instream.read(data);
                if (nLen < 0) {
                    throw new Exception("network error.");

+ 31 - 0
hos-broker/src/main/java/com/yihu/hos/broker/controllers/ESBMycatlController.java

@ -0,0 +1,31 @@
package com.yihu.hos.broker.controllers;
import com.yihu.hos.broker.services.MycatConfigService;
import com.yihu.hos.web.framework.model.Result;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
 * Created by lingfeng on 2016/8/4.
 */
@RestController
@RequestMapping("/esb")
public class ESBMycatlController {
    @Autowired
    private MycatConfigService mycatService;
    @RequestMapping(value = "/serviceMycat/update", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
    @ApiOperation(value = "修改mycat", produces = "application/json", notes = "修改mycat的配置文件,并重新加载配置")
    public Result updateMycat(
            @ApiParam(name = "msg", value = "消息", required = true)
            @RequestBody() String msg) {
        return mycatService.addeMycat(msg);
    }
}

+ 243 - 0
hos-broker/src/main/java/com/yihu/hos/broker/services/MycatConfigService.java

@ -0,0 +1,243 @@
package com.yihu.hos.broker.services;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.hos.broker.common.shell.SSHLinuxTool;
import com.yihu.hos.broker.util.XMLUtil;
import com.yihu.hos.web.framework.constant.MycatConstant;
import com.yihu.hos.web.framework.model.Result;
import com.yihu.hos.web.framework.model.bo.ServiceMycat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.annotation.Resource;
import java.util.Map;
/**
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/24.
 */
@Service("MycatConfigService")
public class MycatConfigService {
    public static final String BEAN_ID = "MycatConfigService";
    @Resource(name = SSHLinuxTool.BEAN_ID)
    private SSHLinuxTool sshLinuxTool;
    @Autowired
    private ObjectMapper objectMapper;
    @Value("${hos.mycat.path}")
    private String mycatPath;
    @Resource(name = ServerShellService.BEAN_ID)
    private ServerShellService serverShellService;
    //新增 mycat
    public Result addeMycat(String msg) {
        String result = "";
        try {
            ServiceMycat serviceMycat = objectMapper.readValue(msg, ServiceMycat.class);
            //mycat 修改操作
            System.out.println("修改mycat配置,并重载==================");
            //schema.xml修改
//            String schemaXmlPath =  "e:/conf/schema.xml";
            String schemaXmlPath = mycatPath + "/conf/schema.xml";
            Document schemaXML = XMLUtil.parseXml2Doc(schemaXmlPath);
            schemaXML = addMycatSchema(schemaXML, serviceMycat);
            boolean b1 = XMLUtil.writeToXml(schemaXML, schemaXmlPath);
            //server.mxl修改
//            String serverPath =  "e:/conf/server.xml";
            String serverPath = mycatPath + "/conf/server.xml";
            Document serverXML = XMLUtil.parseXml2Doc(serverPath);
            serverXML = addMycatServer(serverXML, serviceMycat);
            boolean b2 = XMLUtil.writeToXml(serverXML, serverPath);
            //TODO 修改完配置文件后,重启mycat
            mycatRestart(mycatPath + "/bin/");
            if (b1 && b2){
                //TODO  需要做灾难抢救处理
                return Result.success("mycat 修改,重启完成!");
            }else {
                return Result.error("mycat 修改配置失败!!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.error("mycat 修改异常,请处理!!");
    }
    public void mycatRestart( String mycatBinPath) throws Exception {
        StringBuffer command = new StringBuffer();
        command.append("cd ").append(mycatBinPath).append("\r\n");
        command.append("./mycat restart").append("\r\n");
        serverShellService.executeShell(command.toString(), false);
    }
    /***************************************   修改mycat 的schema.xml配置  ****************************************************/
    /**
     * 添加mycat schema.xml 配置
     * @param doc   mycat xml的dom对象
     * @param obj   租户信息
     * @return
     */
    public  Document addMycatSchema(Document doc, ServiceMycat obj) {
        Node stNode = doc.getElementsByTagName("mycat:schema").item(0);
        //获取数据库实例名,当前写死获取第一个
        Element dnElem = (Element)  doc.getElementsByTagName("dataHost").item(0);
        String dataHost = dnElem.getAttribute("name");//数据库实例名
        //添加schema节点
        Element firstSchema = (Element)  doc.getElementsByTagName("schema").item(0);// 第一个schema节点;用于新节点的插入
        Element schemaElem = doc.createElement("schema");
        schemaElem.setAttribute("name", obj.getSchema());
        schemaElem.setAttribute("dataNode",  MycatConstant.DATA_NODE + obj.getSchema());
        schemaElem.setAttribute("checkSQLschema", "false");
        schemaElem.setAttribute("sqlMaxLimit", "100");
        stNode.insertBefore(schemaElem,firstSchema);
//        stNode.appendChild(schemaElem);
        //添加dataNode节点
        Element firstDataNode = (Element)  doc.getElementsByTagName("dataNode").item(0);//  第一个dataNode节点;用于新节点的插入
        Element dataNodeElem = doc.createElement("dataNode");
        dataNodeElem.setAttribute("dataHost", dataHost);
        dataNodeElem.setAttribute("name",  MycatConstant.DATA_NODE + obj.getSchema());
        dataNodeElem.setAttribute("database",  MycatConstant.DATA_BASE + obj.getSchema());
        stNode.insertBefore(dataNodeElem,firstDataNode);
//        stNode.appendChild(dataNodeElem);
        return doc;
    }
    /**
     * 删除schema相关的mycat配置
     * @param doc   mycat xml的dom对象
     * @param obj   租户信息
     * @return
     */
    public  Document delMycatSchema(Document doc, ServiceMycat obj) {
        Node stNode = doc.getElementsByTagName("mycat:schema").item(0);
        //删除schema节点
        Element schemaNode = doc.createElement("schema");
        schemaNode.setAttribute("name",obj.getSchema());
        stNode.removeChild(schemaNode);
        //删除dataNode节点
        Element dataNodeNode = doc.createElement("schema");
        dataNodeNode.setAttribute("name",MycatConstant.DATA_NODE + obj.getSchema());
        stNode.removeChild(dataNodeNode);
        return doc;
    }
    /***************************************   修改mycat server.xml配置  ****************************************************/
    /**
     * 添加mycat  server.xml配置
     * @param doc   mycat xml的dom对象
     * @param obj   租户信息
     * @return
     */
    public  Document addMycatServer(Document doc, ServiceMycat obj) {
        //获取数据库实例名,当前写死获取第一个
        Element stNode = (Element)  doc.getElementsByTagName("mycat:server").item(0);
        //添加user节点
        Element schemaElem = doc.createElement("user");
        schemaElem.setAttribute("name", obj.getLoginName());
        //添加user的属性子节点
        Element password = doc.createElement("property");
        password.setAttribute("name","password");
        password.setTextContent(obj.getPassword());
        Element schemas = doc.createElement("property");
        schemas.setAttribute("name","schemas");
        schemas.setTextContent(obj.getSchema());
        schemaElem.appendChild(password);
        schemaElem.appendChild(schemas);
        stNode.appendChild(schemaElem);
        //TODO 修改管理员节点,添加新的schema,使管理员可以看到所有的schema;
        Element firstUser = (Element)  doc.getElementsByTagName("user").item(0);// 第一个user节点;用于新节点的插入
        NodeList childNodes = firstUser.getElementsByTagName("property");
        for (int i=0;i<childNodes.getLength();i++){
            Element item = (Element)  childNodes.item(i);
            String name = item.getAttribute("name");
            if ("schemas".equals(name)){
                item.setTextContent(item.getTextContent() + "," + obj.getSchema());
            }
        }
        return doc;
    }
    /* **********************************  以下为具体操作方法;暂无用 *********************************************/
    /**
     *  添加schema节点
     * @param doc      xml DOM对象
     * @param childMap   schema节点
     * @return
     */
    public  Document addSchemaElement(Document doc, Map<String ,String> childMap) {
        Node stNode = doc.getElementsByTagName("mycat:schema").item(0);
        Element element = doc.createElement("schema");
        for (Map.Entry<String, String> entry : childMap.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            element.setAttribute(key,value);
        }
        stNode.appendChild(element);
        return doc;
    }
    /**
     * 删除Schema子节点
     * @param doc         xml DOM对象
     * @param schemaName  要删除的子节点名称
     */
    public  void deleteElement(Document doc, String schemaName) {
        Node stNode = doc.getElementsByTagName("mycat:schema").item(0);
        Element schemaNode = doc.createElement("schema");
        schemaNode.setAttribute("name", schemaName);
        stNode.removeChild(schemaNode);
    }
    /**
     * 修改节点属性
     * @param doc          mycat xmldom对象
     * @param schemaName   要修改的节点名称
     * @param childMap 修改的节点属性
     */
    public  Document updateAttributeValue(Document doc,String schemaName ,Map<String,String> childMap) {
        NodeList nodeList = doc.getElementsByTagName("schema");
        if (nodeList != null) {
            //所有schema节点
            for (int i = 0; i < nodeList.getLength(); i++) {
                Element elem = (Element) nodeList.item(i);
                String name = elem.getAttribute("name");
                if (schemaName.equals(name)){
                    //schema节点的所有属性
                    for (Map.Entry<String, String> entry : childMap.entrySet()) {
                        String key = entry.getKey();
                        String value = entry.getValue();
                        elem.setAttribute(key,value);
                    }
                }
            }
        }
        return doc;
    }
    public static void main(String[] args) throws Exception {
        MycatConfigService service = new MycatConfigService();
        service.mycatRestart("e://mycat");
    }
}

+ 28 - 0
hos-broker/src/main/java/com/yihu/hos/broker/services/ServerShellService.java

@ -58,4 +58,32 @@ public class ServerShellService {
        return Result.error("shell命令执行失败!");
    }
    public String executeShell(String command,boolean iskeep) {
        String result="";
        try {
            if (session==null){
                session = sshLinuxTool.getsessionConn();
            }
            if (!iskeep) {
                //保持通道连接
                System.out.println("执行命令,并保持当前会话==================");
                result = sshLinuxTool.sshShell(session, command, false);
                System.out.println("结果:"+result);
            } else {
                //断开通道连接,会话
                System.out.println("执行命令,并结束当前会话==================");
                result = sshLinuxTool.sshShell(session, command, true);
                session = null;
                System.out.println("结果:"+result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

+ 167 - 0
hos-broker/src/main/java/com/yihu/hos/broker/util/XMLUtil.java

@ -0,0 +1,167 @@
package com.yihu.hos.broker.util;
import org.w3c.dom.*;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.util.Map;
public class XMLUtil {
//    public static void main(String[] args) {
//        String filePath = "e://test.xml";
//        XMLUtil xmlUtil = new XMLUtil();
//        xmlUtil.parseXml(filePath);
//    }
    public static void parseXml(String filePath) {
        File xmlFile = new File(filePath);
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder;
        try {
            dBuilder = dbFactory.newDocumentBuilder();
            dBuilder.setEntityResolver(new IgnoreDTDEntityResolver());
            Document doc = dBuilder.parse(xmlFile);
            Element eltName = doc.createElement("schema");
            Attr attr = doc.createAttribute("name");
            attr.setValue("22222");
            Attr attr2 = doc.createAttribute("checkSQLschema");
            attr2.setValue("true");
            Attr attr3 = doc.createAttribute("sqlMaxLimit");
            attr3.setValue("10");
            Attr attr4 = doc.createAttribute("dataNode");
            attr4.setValue("T2222");
            eltName.setAttributeNode(attr);
            eltName.setAttributeNode(attr2);
            eltName.setAttributeNode(attr3);
            eltName.setAttributeNode(attr4);
            Node stNode = doc.getElementsByTagName("mycat:schema").item(0);
            stNode = addElement(stNode, eltName);
            writeToXml(doc, filePath);
            Element rootElement = doc.getDocumentElement();
            NodeList nodeList = rootElement.getElementsByTagName("schema");
            if (nodeList != null) {
                for (int i = 0; i < nodeList.getLength(); i++) {
                    Element element = (Element) nodeList.item(i);
                    String name = element.getAttribute("name");
                    System.out.println(name);
                }
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
    public static Document parseXml2Doc(String filePath) {
        Document doc = null;
        File xmlFile = new File(filePath);
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder;
        try {
            dBuilder = dbFactory.newDocumentBuilder();
            dBuilder.setEntityResolver(new IgnoreDTDEntityResolver());
            doc = dBuilder.parse(xmlFile);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return doc;
    }
    /**
     *  添加节点
     * @param stNode      基节点
     * @param childNode   要新增的子节点
     * @return
     */
    public static Node addElement(Node stNode, Element childNode) {
        stNode.appendChild(childNode);
        return stNode;
    }
    /**
     * 删除子节点
     * @param node        父节点
     * @param childNode  要删除的子节点
     */
    public static void deleteElement(Node node, Element childNode) {
        node.removeChild(childNode);
    }
    /**
     * //TODO 不需要
     * 修改子节点
     * @param doc
     */
    public static void updateElementValue(Document doc) {
        NodeList mycatNode = doc.getElementsByTagName("mycat:schema");
        Element emp = null;
        //loop for each employee
        for (int i = 0; i < mycatNode.getLength(); i++) {
            emp = (Element) mycatNode.item(i);
            Node name = emp.getElementsByTagName("name").item(0).getFirstChild();
            name.setNodeValue(name.getNodeValue().toUpperCase());
        }
    }
    /**
     * 修改节点属性
     * @param element   要修改的节点
     * @param updateMap 修改的节点属性
     */
    public static Element updateAttributeValue(Element element ,Map<String,String> updateMap) {
        for (Map.Entry<String, String> entry : updateMap.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            element.setAttribute(key,value);
        }
        return element;
    }
    /**
     * 将修改完的xml保存
     *
     * @param doc       修改后的xml
     * @param rptdesign xml的保存路径
     */
    public static boolean writeToXml(Document doc, String rptdesign) {
        boolean succ = false;
        try {
            OutputStream fileoutputStream = new FileOutputStream(rptdesign);
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();
            transformer.setOutputProperty("indent" ,  "yes" );
            System.out.println(doc.getDoctype().getPublicId());
            DOMSource source = new DOMSource(doc);
            //添加解析时忽略的dtd引用
            transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());
            StreamResult result = new StreamResult(fileoutputStream);
            transformer.transform(source, result);
            succ = true;
        } catch (Exception e) {
            System.out.println("Can't write to file: " + rptdesign);
            e.printStackTrace();
        }
        return succ;
    }
   static class IgnoreDTDEntityResolver implements EntityResolver {
        @Override
        public InputSource resolveEntity(String arg0, String arg1) throws SAXException, IOException {
            return new InputSource(new ByteArrayInputStream("<?xml version='1.0' encoding='UTF-8'?>".getBytes()));
        }
    }
}

+ 2 - 0
hos-broker/src/main/resources/application.yml

@ -58,6 +58,8 @@ hos:
      period: 10000
  tenant:
    name: jkzl
  mycat:
    path: /usr/local/mycat/   ##mycat的安装目录
  #jcraft shell操作
  jcraft:
    host: 172.19.103.57

+ 8 - 2
hos-core/pom.xml

@ -122,13 +122,19 @@
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.4.6</version>
            <version>2.8.5</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.4.6</version>
            <version>2.8.5</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.8.5</version>
        </dependency>
        <!--jackson end-->
        <!-- Log framework start-->

+ 23 - 0
hos-core/src/main/java/com/yihu/hos/core/file/FileUtil.java

@ -347,5 +347,28 @@ public class FileUtil {
        return stringBuilder.toString();
    }
    public static String readFileText(InputStream in) {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
            String line = null;
            while ((line = br.readLine()) != null) {
                stringBuilder.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e1) {
                }
            }
        }
        return stringBuilder.toString();
    }
}

+ 16 - 0
hos-web-framework/src/main/java/com/yihu/hos/web/framework/constant/MycatConstant.java

@ -0,0 +1,16 @@
package com.yihu.hos.web.framework.constant;
/**
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/24.
 */
public class MycatConstant {
    public static final String MYCAT = "mycat";   // mycat dataNode前缀
    public static final String DATA_NODE = "dn_";   // mycat dataNode前缀
    public static final String DATA_BASE = "db_";   // mycat database前缀
}

+ 11 - 1
hos-web-framework/src/main/java/com/yihu/hos/web/framework/constant/ServiceFlowConstant.java

@ -40,10 +40,11 @@ public interface ServiceFlowConstant {
    //ArbiterServer MQ
    String SSH = "ssh";
    /* *******   shell相关  ******  */
    // shell 请求命令,对列名称
    String SHELL_EVENT_QUEUE = "configuration.service.shell";
    String SHELL_EVENT_SERVICE = "service.shell.event:queue:configuration.service.shell";
    //Arbiter shell
    String ARBITER_SHELL_SEND = "arbiterShellSend"; //shell 命令执行消息
    String ARBITER_SHELL_ACEPT = "arbiterShellAcept"; //shell 执行结果消息
@ -52,4 +53,13 @@ public interface ServiceFlowConstant {
    // hos-admin 接收shell执行结果
    String SHELL_RESPONSE = "shell_response";
    /* ********************** mycat相关  ************************ */
    // shell 请求命令,对列名称
    String MYCAT_EVENT_QUEUE = "configuration.service.mycat";
    String MYCAT_EVENT_SERVICE = "service.mycat.event:queue:configuration.service.mycat";
    //Arbiter mycat 操作事件
    String EXECUTE_MYCAT = "execute_mycat"; //shell 命令执行消息
    //arbiter mycat修改 消息队列
    String MYCAT_UPDATE = "mycat_update";
}

+ 69 - 0
hos-web-framework/src/main/java/com/yihu/hos/web/framework/model/bo/ServiceMycat.java

@ -0,0 +1,69 @@
package com.yihu.hos.web.framework.model.bo;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
/**
 *  租户表
 * @author HZY
 * @vsrsion 1.0
 * Created at 2016/12/2.
 */
@Document
public class ServiceMycat {
    @Id
    private String id;
    private String name;
    private String loginName;
    private String password;
    private String schema;
    private String tenant;
    public String getTenant() {
        return tenant;
    }
    public void setTenant(String tenant) {
        this.tenant = tenant;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getLoginName() {
        return loginName;
    }
    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getSchema() {
        return schema;
    }
    public void setSchema(String schema) {
        this.schema = schema;
    }
}

+ 5 - 0
src/main/java/com/yihu/hos/ESBApplication.java

@ -52,6 +52,11 @@ public class ESBApplication extends WebMvcConfigurerAdapter  implements CommandL
        return new ActiveMQQueue(ServiceFlowConstant.SHELL_EVENT_QUEUE);
    }
    @Bean(name = "mycatQueue")
    public Queue mycatQueue() {
        return new ActiveMQQueue(ServiceFlowConstant.MYCAT_EVENT_QUEUE);
    }
    @Override
    public void run(String... strings) throws Exception {
        MqServerConfig config = new MqServerConfig();

+ 1 - 0
src/main/java/com/yihu/hos/remoteManage/controller/RemoteShellController.java

@ -80,6 +80,7 @@ public class RemoteShellController extends BaseController {
                    break;
                }
            }
            LocalContext.getContext().removeAttachment(ContextAttributes.SHELL_RESPONSE + attachment);
            System.out.println("接口返回结果:" + result);
        } catch (InterruptedException e) {
            e.printStackTrace();

+ 56 - 0
src/main/java/com/yihu/hos/services/ServiceMycatEventService.java

@ -0,0 +1,56 @@
package com.yihu.hos.services;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.hos.core.log.Logger;
import com.yihu.hos.core.log.LoggerFactory;
import com.yihu.hos.web.framework.constant.ServiceFlowConstant;
import com.yihu.hos.web.framework.model.bo.ServiceMycat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.jms.Queue;
import java.util.HashMap;
import java.util.Map;
/**
 *  mycat配置文件操作 消息到MQ
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/5.
 */
@Component
public class ServiceMycatEventService {
    static final Logger logger = LoggerFactory.getLogger(ServiceMycatEventService.class);
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;
    @Resource(name = "mycatQueue")
    private Queue mycatQueue;
    @Autowired
    private ObjectMapper objectMapper;
    public void executeMycatConfig(ServiceMycat servviceMycat, String tenant) {
        this.sendMsg(ServiceFlowConstant.EXECUTE_MYCAT, servviceMycat,tenant);
    }
    private void sendMsg(String event, ServiceMycat servviceMycat,String tenant) {
        try {
            Map<String, Object> header = new HashMap<>();
            String msg = objectMapper.writeValueAsString(servviceMycat);
            header.put("tenant", tenant);
            header.put("event", event);
            this.jmsMessagingTemplate.convertAndSend(this.mycatQueue, msg, header);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
    }
}

+ 7 - 3
src/main/java/com/yihu/hos/tenant/service/MySqlImportAndExport.java

@ -68,6 +68,7 @@ public class MySqlImportAndExport {
        try {
            //runtime.exec(cmdarray);//这里也是简单的直接抛出异常
            Process process = runtime.exec(cmdarray[0]);
            Thread.sleep(300);//没睡眠的话会出现问题:出现异常的时候不会被捕获;
            //执行了第一条命令以后已经登录到mysql了,所以之后就是利用mysql的命令窗口
            //进程执行后面的代码
            OutputStream os = process.getOutputStream();
@ -79,9 +80,12 @@ public class MySqlImportAndExport {
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
            return e.getMessage();
            return e.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return e.toString();
        }
        return "";
        return null;
    }
@ -101,7 +105,7 @@ public class MySqlImportAndExport {
        if (System.getProperties().getProperty("os.name").contains("Windows")) {
            System.out.println("===========操作系统是:" + System.getProperties().getProperty("os.name"));
            //TODO 获取mysql的安装路径
            String mysqlPath = "C:\\Program Files\\MySQL\\MySQL Server 5.6\\bin ";
            String mysqlPath = "C:\\Program Files\\MySQL\\MySQL Server 5.6\\bin";
            String cmd = "cmd /c C: && cd " + mysqlPath + " && ";
            command.append(cmd);
        }

+ 25 - 7
src/main/java/com/yihu/hos/tenant/service/TenantService.java

@ -2,10 +2,13 @@ package com.yihu.hos.tenant.service;
import com.yihu.hos.config.MongoConfig;
import com.yihu.hos.core.encrypt.DES;
import com.yihu.hos.services.ServiceMycatEventService;
import com.yihu.hos.tenant.dao.TenantDao;
import com.yihu.hos.tenant.model.DBInfoModel;
import com.yihu.hos.tenant.model.TenantModel;
import com.yihu.hos.web.framework.constant.MycatConstant;
import com.yihu.hos.web.framework.model.Result;
import com.yihu.hos.web.framework.model.bo.ServiceMycat;
import com.yihu.hos.web.framework.util.GridFSUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -48,6 +51,9 @@ public class TenantService {
    @Autowired
    private MySqlImportAndExport mySqlImportAndExport;
    @Autowired
    private ServiceMycatEventService serviceMycatEventService;
    public TenantModel findTenantByName(String name) throws Exception {
        List<TenantModel> list = tenantDao.getTenantList(name);
@ -65,6 +71,7 @@ public class TenantService {
        return tenantDao.getEntity(TenantModel.class, id);
    }
//    @Transactional(rollbackFor={RuntimeException.class, Exception.class})
    public Result addTenant(TenantModel obj) {
        String code = UUID.randomUUID().toString();
        obj.setCode(code);
@ -72,7 +79,7 @@ public class TenantService {
        obj.setCreatedUnix(0);
        obj.setUpdated(new Date());
        obj.setUpdatedUnix(0);
        String message = "";
        String errorMessage = null;
        try {
            // 建库建表操作
            DBInfoModel dbInfo = dbInfoService.getDBInfoById(obj.getDataSourceId());
@ -81,18 +88,29 @@ public class TenantService {
            db.setPassword(dbInfo.getPassword());
            db.setHost(dbInfo.getHost());
            db.setPort(dbInfo.getPort());
            db.setDbName(obj.getSchema());
            db.setDbName(MycatConstant.DATA_BASE + obj.getSchema());//新建的数据库命名规则为"db_"+ schema
            //建库,建表,数据复制操作
            message = mySqlImportAndExport.importSql(db, sqlFilePath);
            //TODO  mycat操作问题
            tenantDao.saveEntity(obj);
            return Result.success("保存成功");
            errorMessage = mySqlImportAndExport.importSql(db, sqlFilePath);
            if (errorMessage ==null){
                //TODO  mycat操作消息发送;使用zbus;tenant: "mycat"+ IP
                ServiceMycat serrviceMycat = new ServiceMycat();
                serrviceMycat.setSchema(obj.getSchema());
                serrviceMycat.setTenant(MycatConstant.MYCAT+db.getHost());
                serrviceMycat.setLoginName(obj.getLoginName());
                serrviceMycat.setPassword(obj.getPassword());
                serviceMycatEventService.executeMycatConfig(serrviceMycat, MycatConstant.MYCAT+dbInfo.getHost());
                tenantDao.saveEntity(obj);
                return Result.success("保存成功");
            }else {
                return Result.error("建库建表操作失败,异常信息\r\n" + errorMessage);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.error("保存租户信息失败:" + message);
        return Result.error("保存租户信息失败,异常信息\n" + errorMessage);
    }
    @Transactional

+ 1 - 1
src/main/resources/application.yml

@ -62,7 +62,7 @@ hos:
    port: 15555
    store: ./store
  mysql:
    filePath: e://learn.sql   #sql文件位置
    filePath: e://learn.sql   #租户基础表 sql文件位置
---
spring: