浏览代码

Merge branch 'master' of http://192.168.1.220:10080/esb/esb

zhenglingfeng 8 年之前
父节点
当前提交
12ee00e785

+ 5 - 1
hos-arbiter/pom.xml

@ -40,7 +40,11 @@
            <artifactId>hos-web-framework</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.53</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.zbus/zbus -->
        <dependency>
            <groupId>org.zbus</groupId>

+ 4 - 1
hos-arbiter/src/main/java/com/yihu/hos/arbiter/HosArbiterApplication.java

@ -2,6 +2,7 @@ package com.yihu.hos.arbiter;
import com.yihu.hos.arbiter.configuration.ArbiterServerConfiguration;
import com.yihu.hos.arbiter.services.ProxyService;
import com.yihu.hos.web.framework.constant.ServiceFlowConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
@ -31,7 +32,9 @@ public class HosArbiterApplication implements CommandLineRunner {
            server.start();
        }
        proxyService.start();
        proxyService.start(ServiceFlowConstant.SSH + "@" + configuration.getTenant());
        proxyService.start(ServiceFlowConstant.SHELL + "@" + configuration.getTenant());
    }
    @Autowired

+ 39 - 0
hos-arbiter/src/main/java/com/yihu/hos/arbiter/routers/LinuxShellRouter.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;
/**
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/5.
 */
@Component
public class LinuxShellRouter 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.shell.event", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
        from(ServiceFlowConstant.SHELL_EVENT_ENDPOINT)
                .choice()
                .when(header("tenant").isNotNull()).to("bean:linuxShellService?method=proxy")
                .when(header("event").isEqualTo(ServiceFlowConstant.ARBITER_SHELL_SEND)).to("bean:linuxShellService?method=sendShell")
                .when(header("event").isEqualTo(ServiceFlowConstant.ARBITER_SHELL_ACEPT)).to("bean:linuxShellService?method=aceptShell")
                .endChoice();
    }
}

+ 65 - 0
hos-arbiter/src/main/java/com/yihu/hos/arbiter/services/LinuxShellService.java

@ -0,0 +1,65 @@
package com.yihu.hos.arbiter.services;
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.Map;
/**
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/5.
 */
@Service("linuxShellService")
public class LinuxShellService {
    private static final Logger logger = LogManager.getLogger(LinuxShellService.class);
    private ZbusBroker zbusBroker;
    /**
     * 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 {
            //TODO 设置shell发起用户
            Producer producer = new Producer(zbusBroker, ServiceFlowConstant.SHELL + "@" + 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);
//            System.out.println("test");
        } catch (IOException | InterruptedException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
    }
    @Autowired
    public void setZbusBroker(ZbusBroker zbusBroker) {
        this.zbusBroker = zbusBroker;
    }
}

+ 2 - 8
hos-arbiter/src/main/java/com/yihu/hos/arbiter/services/ProxyService.java

@ -1,6 +1,5 @@
package com.yihu.hos.arbiter.services;
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;
@ -25,7 +24,6 @@ public class ProxyService {
    private static final Logger logger = LoggerFactory.getLogger(ProxyService.class);
    private CamelContext camelContext;
    private ArbiterServerConfiguration configuration;
    private ZbusBroker zbusBroker;
    private Consumer consumer;
@ -38,13 +36,13 @@ public class ProxyService {
        producerTemplate.sendBodyAndHeaders(ServiceFlowConstant.FLOW_EVENT_ENDPOINT, message.getBodyString(), header);
    }
    public void start() {
    public void start(String queueName) {
        if (zbusBroker == null) {
            logger.error("zbusBroker is null");
            return;
        }
        consumer = new Consumer(zbusBroker, ServiceFlowConstant.SSH + "@" + configuration.getTenant());
        consumer = new Consumer(zbusBroker,queueName);
        try {
            consumer.start(this::proxy);
        } catch (IOException e) {
@ -64,10 +62,6 @@ public class ProxyService {
        this.camelContext = camelContext;
    }
    @Autowired
    public void setConfiguration(ArbiterServerConfiguration configuration) {
        this.configuration = configuration;
    }
    @Override
    protected void finalize() throws Throwable {

+ 127 - 0
hos-arbiter/src/main/java/com/yihu/hos/arbiter/shell/SSHLinuxTool.java

@ -0,0 +1,127 @@
package com.yihu.hos.arbiter.shell;
import com.jcraft.jsch.*;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
 * ssh 链接操作测试类
 *
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/3.
 */
@Service("SSHLinuxTool")
public class SSHLinuxTool {
    public static final String BEAN_ID = "SSHLinuxTool";
    @Value("${jcraft.host}")
    private String host;
    @Value("${jcraft.port}")
    private Integer port;
    @Value("${jcraft.user}")
    private String user;
    @Value("${jcraft.password}")
    private String password;
    public static Channel channel = null;
    /**
     * //TODO 密钥密码等验证
     * 建立一个shell连接会话
     *
     * @return
     * @throws JSchException
     */
    public Session getsessionConn() throws JSchException {
        JSch jsch = new JSch();
        Session session = jsch.getSession(user, host, port);
        session.setConfig("StrictHostKeyChecking", "no");
        //    java.util.Properties config = new java.util.Properties();
        //   config.put("StrictHostKeyChecking", "no");
        session.setTimeout(600000); // 设置timeout时间
        session.setPassword(password);
        session.connect();
        return session;
    }
    public String exeCommand(Session session, String command, boolean exit) throws JSchException, IOException {
        if (!session.isConnected()) {
            session = getsessionConn();
        }
        ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
        InputStream in = channelExec.getInputStream();
        channelExec.setCommand(command);
        channelExec.setErrStream(System.err);
        channelExec.connect();
        String out = IOUtils.toString(in, "UTF-8");
        if (exit) {
            channelExec.disconnect();
        }
        return out;
    }
    /**
     * 利用JSch实现远程主机SHELL命令执行
     */
    public  String sshShell(Session session, String command, boolean exit) throws Exception {
        //如果服务器连接不上,则抛出异常
        if (session == null) {
            throw new Exception("session is null");
        }
        try {
            //创建sftp通信通道
            if (channel == null) {
                channel = session.openChannel("shell");
                channel.connect(1000);
            }
            //获取输入流和输出流
            InputStream instream = channel.getInputStream();
            OutputStream outstream = channel.getOutputStream();
            //发送需要执行的SHELL命令,需要用\n结尾,表示回车
            String shellCommand = command + " \n";
            outstream.write(shellCommand.getBytes());
            outstream.flush();
            //获取命令执行的结果
            Thread.sleep(2000);
            if (instream.available() > 0) {
                byte[] data = new byte[instream.available()];
                int nLen = instream.read(data);
                if (nLen < 0) {
                    throw new Exception("network error.");
                }
                //转换输出结果并打印出来
                String temp = new String(data, 0, nLen, "iso8859-1");
                System.out.println(temp);
                return temp;
            }
            outstream.close();
            instream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (exit) {
                channel.disconnect();
                session.disconnect();
            }
        }
        return null;
    }
}

+ 16 - 4
hos-arbiter/src/main/resources/application.yml

@ -20,7 +20,7 @@ spring:
    password: admin
arbiter:
  timer:
      period: 10000
    period: 10000
  central:
    url:
    port: 15555
@ -29,19 +29,25 @@ arbiter:
    url: 192.168.131.119:15555
  tenant:
    name: jkzl
#jcraft shell操作
jcraft:
  host: 172.19.103.57
  port: 22
  user: root
  password: ceshi
---
spring:
  profiles: test
  data:
    mongodb:
      host: 172.19.103.86
      host: 172.19.103.58
      port: 27017
      username: esb
      password: esb
      authenticationDatabase: admin
      database: configuration
  activemq:
    broker-url: tcp://172.19.103.86:61616
    broker-url: tcp://172.19.103.58:61616
    user: admin
    password: admin
arbiter:
@ -106,4 +112,10 @@ arbiter:
  terminal:
    url: 192.168.131.38:15555
  tenant:
    name: yichang
    name: yichang
#jcraft shell操作
jcraft:
  host: 172.19.103.57
  port: 22
  user: root
  password: ceshi

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

@ -76,7 +76,7 @@ spring:
      min-idle: 10
      initial-size: 10
  activemq:
      broker-url: tcp://172.19.103.57:61616
      broker-url: tcp://172.19.103.58:61616
      user: admin
      password: admin
  data:

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

@ -39,4 +39,15 @@ public interface ServiceFlowConstant {
    //ArbiterServer MQ
    String SSH = "ssh";
    // shell 请求命令,对列名称
    String SHELL_EVENT_QUEUE = "configuration.service.shell";
    String SHELL_EVENT_ENDPOINT = "service.shell.event:queue:configuration.service.shell";
    //Arbiter shell
    String ARBITER_SHELL_SEND = "arbiterShellSend"; //shell 命令执行消息
    String ARBITER_SHELL_ACEPT = "arbiterShellAcept"; //shell 执行结果消息
    String SHELL = "shell";
}

+ 98 - 0
hos-web-framework/src/main/java/com/yihu/hos/web/framework/model/bo/ServiceShell.java

@ -0,0 +1,98 @@
package com.yihu.hos.web.framework.model.bo;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
/**
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/5.
 */
@Document
public class ServiceShell {
    @Id
    private String id;
    private String name;
    private String type;    //send or acept?
    private Date updated;
    private String fromHost;
    private String tenant;
    private String command;
    private String result;
    private boolean disconnect;//是否断开连接
    public boolean isDisconnect() {
        return disconnect;
    }
    public void setDisconnect(boolean disconnect) {
        this.disconnect = disconnect;
    }
    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 getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public Date getUpdated() {
        return updated;
    }
    public void setUpdated(Date updated) {
        this.updated = updated;
    }
    public String getFromHost() {
        return fromHost;
    }
    public void setFromHost(String fromHost) {
        this.fromHost = fromHost;
    }
    public String getTenant() {
        return tenant;
    }
    public void setTenant(String tenant) {
        this.tenant = tenant;
    }
    public String getCommand() {
        return command;
    }
    public void setCommand(String command) {
        this.command = command;
    }
    public String getResult() {
        return result;
    }
    public void setResult(String result) {
        this.result = result;
    }
}

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

@ -36,4 +36,9 @@ public class ESBApplication extends WebMvcConfigurerAdapter {
    public Queue queue() {
        return new ActiveMQQueue(ServiceFlowConstant.FLOW_EVENT_QUEUE);
    }
    @Bean(name = "shellQueue")
    public Queue shellQueue() {
        return new ActiveMQQueue(ServiceFlowConstant.SHELL_EVENT_QUEUE);
    }
}

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

@ -0,0 +1,94 @@
package com.yihu.hos.remoteManage.controller;
import com.yihu.hos.remoteManage.service.RemoteShellService;
import com.yihu.hos.web.framework.util.controller.BaseController;
import io.swagger.annotations.ApiParam;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
/**
 * 远程终端管理--shell操作
 *
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/5.
 */
@RequestMapping("/shell")
@Controller
public class RemoteShellController extends BaseController {
    @Resource(name = RemoteShellService.BEAN_ID)
    private RemoteShellService remoteShellService;
    /**
     * 远程shell操作页面
     *
     * @param model
     * @return
     */
    @RequestMapping("/initial")
    public String appInitial(Model model) {
        model.addAttribute("contentPage", "shell/shell");
        return "partView";
    }
    @RequestMapping(value = "/shell", produces = "application/json;charset=UTF-8", method = RequestMethod.GET)
    @ResponseBody
    public String shellTest(
            @ApiParam(name = "command", value = "shell命令")
            @RequestParam(value = "command", required = false) String command,
//            @ApiParam(name = "tenant", value = "租户名称")
//            @RequestParam(value = "tenant", required = false) String tenant,
            @ApiParam(name = "disCon", value = "是否断开会话连接")
            @RequestParam(value = "disCon", required = true) boolean disCon) {
        String result = "";
        try {
            //TODO 发送shell命令 消息
            System.out.println("发送shell请求==================");
            remoteShellService.sendShell(command, disCon);
            System.out.println("结果1:" + result);
            //TODO 接收shell命令执行结果 消息
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
//
//    //连接操作shell测试
//    @RequestMapping(value = "/shell", produces = "application/json;charset=UTF-8", method = RequestMethod.GET)
//    @ResponseBody
//    public String shellTest(String cmd, String disCon) {
//        String result = "";
//        try {
//            if (session==null){
//                session = sshLinuxTool.getsessionConn();
//            }
//            if ("false".equals(disCon)) {
//                //保持通道连接
//                System.out.println("循环开始1111111==================");
//                result = sshLinuxTool.sshShell(session, cmd, false);
//                System.out.println("结果:"+result);
//            } else {
//                //断开通道连接,会话
//                System.out.println("循环开始2222222222==================");
//                result = sshLinuxTool.sshShell(session, cmd, true);
//                session = null;
//                System.out.println("结果:"+result);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return result;
//    }
}

+ 46 - 0
src/main/java/com/yihu/hos/remoteManage/service/RemoteShellService.java

@ -0,0 +1,46 @@
package com.yihu.hos.remoteManage.service;
import com.yihu.hos.services.ServiceShellEventService;
import com.yihu.hos.web.framework.model.bo.ServiceShell;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.net.InetAddress;
import java.util.Date;
/**
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/5.
 */
@Service("RemoteShellService")
public class RemoteShellService {
    public static final String BEAN_ID = "RemoteShellService";
    @Autowired
    private ServiceShellEventService serviceShellEventService;
    public boolean sendShell(String command,boolean disConnection){
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
            String ip = addr.getHostAddress();
            ServiceShell serviceShell = new ServiceShell();
            serviceShell.setCommand(command);
            serviceShell.setFromHost(ip);
            serviceShell.setUpdated(new Date());
            serviceShell.setDisconnect(disConnection);
            serviceShellEventService.serviceShellSend(serviceShell);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}

+ 66 - 0
src/main/java/com/yihu/hos/services/ServiceShellEventService.java

@ -0,0 +1,66 @@
package com.yihu.hos.services;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.hos.common.constants.ContextAttributes;
import com.yihu.hos.core.log.Logger;
import com.yihu.hos.core.log.LoggerFactory;
import com.yihu.hos.interceptor.LocalContext;
import com.yihu.hos.web.framework.constant.ServiceFlowConstant;
import com.yihu.hos.web.framework.model.bo.ServiceShell;
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;
/**
 *  发送shell命令消息到MQ
 * @author HZY
 * @vsrsion 1.0
 * Created at 2017/1/5.
 */
@Component
public class ServiceShellEventService {
    static final Logger logger = LoggerFactory.getLogger(ServiceShellEventService.class);
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;
    @Resource(name = "shellQueue")
    private Queue shellQueue;
    @Autowired
    private ObjectMapper objectMapper;
    public void serviceShellSend(ServiceShell serviceShell) {
        serviceShell.setType(ServiceFlowConstant.ARBITER_SHELL_SEND);
        this.sendMsg(ServiceFlowConstant.ARBITER_SHELL_SEND, serviceShell);
    }
    public void serviceShellAcept(ServiceShell serviceShell) {
        serviceShell.setType(ServiceFlowConstant.ARBITER_SHELL_ACEPT);
        this.sendMsg(ServiceFlowConstant.ARBITER_SHELL_ACEPT, serviceShell);
    }
    private void sendMsg(String event, ServiceShell serviceShell) {
        try {
            Map<String, Object> header = new HashMap<>();
            String attachment = LocalContext.getContext().getAttachment(ContextAttributes.TENANT_NAME);
            serviceShell.setTenant(attachment);
            String msg = objectMapper.writeValueAsString(serviceShell);
            header.put("tenant", attachment);
            header.put("event", event);
            this.jmsMessagingTemplate.convertAndSend(this.shellQueue, msg, header);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
    }
}

+ 23 - 12
src/main/resources/application.yml

@ -60,29 +60,40 @@ spring:
spring:
  profiles: test
  #SAAS管理员账号,暂时配置在此处
  administrators: jkzl
  datasource:
      driverClassName: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.1.220:8066/global_db?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true
      username: hos
      password: 123456
      test-on-borrow: true
      validation-query: SELECT 1
      test-while-idle: true
      max-total: 100
      default-auto-commit: true
      max-idle: 50
      min-idle: 20
      initial-size: 10
  jpa:
    database-platform: org.hibernate.dialect.MySQL5Dialect
    hibernate:
      dialect: org.hibernate.dialect.MySQL5Dialect
    format-sql: true
    show-sql: false
  data:
    mongodb:
      host: 172.19.103.86
      host: 172.19.103.57
      port: 27017
      username: esb
      password: esb
      authenticationDatabase: admin
      gridFsDatabase: dfs
  activemq:
    broker-url: tcp://172.19.103.86:61616?wireFormat.maxInactivityDuration=0
    broker-url: tcp://172.19.103.57:61616?wireFormat.maxInactivityDuration=0
    user: admin
    password: admin
    pooled: false
#  data:
#    mongodb:
#      host: 172.19.103.86
#      port: 27017
#      username: esb
#      password: esb
#      authenticationDatabase: admin
#      database: configuration
  aop:
    proxy-target-class: true
---
spring:
  #SAAS管理员账号,暂时配置在此处