解决github的Webhooks无法通知本地内网jenkins(需要准备云服务器)

解决github的Webhooks无法通知本地内网jenkins

需要准备云服务器

github上, 事件的钩子函数只能通知外网ip, 先准备一台云服务器, 讲github上触发事件的钩子请求发送给云服务器, 云服务器在将请求的内容发送给内网程序, 由内网程序给jenkins发送请求

内网程序需要和云服务器建立TCP连接,这样云服务器接收到github的请求才能将数据发送给内网程序

先创建一个spring boot工程

pml.xml添加依赖
需要使用到json
lombok只是为了写日志用的,不要也可以

<dependency>
    <groupId>com.alibabagroupId>
    <artifactId>fastjsonartifactId>
    <version>1.2.71version>
dependency>

<dependency>
    <groupId>org.projectlombokgroupId>
    <artifactId>lombokartifactId>
dependency>

配置文件

# github发送请求的端口
server.port=13521
# 与内网程序建立连接的端口
serverSocket.port=13522

创建一个类用于封装参数

public class Bean implements Serializable {
    private static final long serialVersionUID = 1L;
    public static final String SPLIT = "这是一条华丽的分割线呐呐呐~";

    // 请求类型
    private String method;
    // 请求地址
    private String url;
    // 请求参数
    private String param;
    // 请求头
    private Map<String, String> headerMap;
    // 请求体
    private byte[] body;
    
    public void addHeader(String key, String header) {
        if (null == this.headerMap) this.headerMap = new HashMap<>();
        this.headerMap.put(key, header);
    }

    // get和set方法......
    
}

需要编写一个类监听TCP端口, 用于和内网程序进行连接

@Component
@Slf4j
public class Server {

    @Value("${serverSocket.port}")
    private String port;

    private List<Socket> clientList = new CopyOnWriteArrayList<>();

    @PostConstruct
    public void init() throws Exception {
        ServerSocket serverSocket = new ServerSocket(Integer.parseInt(port));
        log.info("监听端口号为: " + port);
        new Thread(() -> {
            while (true) {
                try {
                    Socket socket = serverSocket.accept();
                    log.info(socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "连接服务器");
                    clientList.add(socket);
                } catch (Exception ignored) { }
            }
        }).start();
    }

    public void send(Bean bean) {
        clientList.forEach(socket -> {
            try {
                OutputStream outputStream = socket.getOutputStream();
                String json = JSONObject.toJSONString(bean);
                outputStream.write((json + Bean.SPLIT).getBytes());
                log.info("向" + socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "发送了" + json);
            } catch (Exception e) {
                log.info(socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "离开了服务器");
                clientList.remove(socket);
            }
        });
    }
}

写一个controller接受所有的请求

@RestController
@CrossOrigin
@Slf4j
public class MainController {

    @Autowired
    private Server server;

    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @RequestMapping("/**")
    public String main(HttpServletRequest request) {
        log.info(simpleDateFormat.format(new Date()) + "接收到请求");

        Bean bean = new Bean();

        // 设置请求模式
        bean.setMethod(request.getMethod());

        // 设置请求路径
        bean.setUrl(request.getServletPath());

        // 设置请求参数
        String queryString = request.getQueryString();
        if (null != queryString) {
            bean.setParam(queryString);
        }

        // 设置请求头
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            bean.addHeader(key, request.getHeader(key));
        }

        // 设置请求体
        try {
            ServletInputStream inputStream = request.getInputStream();
            byte[] body = new byte[0];
            byte[] bytes = new byte[1024 * 8];
            int len;
            while ((len = inputStream.read(bytes)) != -1) {
                byte[] newBody = new byte[body.length + len];
                System.arraycopy(body, 0, newBody, 0, body.length);
                System.arraycopy(bytes, 0, newBody, body.length, len);
                body = newBody;
            }
            bean.setBody(body);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 发送数据
        server.send(bean);

        return "success";
    }

}

放在云服务器的工程写完了, 打包完放在云服务器上运行, 接下来写内网程序用来和云服务器进行连接

public class Client {

    // 云服务器ip
    private final static String SERVER_IP = "";
    // 云服务器监听TCP的端口
    private final static Integer SERVER_PORT = 13522;

    // 内网jenkins ip
    private static String JenkinsIp = "192.168.200.131";
    // 内网jenkins 端口
    private static Integer JenkinsPort = 8080;

    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(SERVER_IP, SERVER_PORT);
        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[1024 * 8];
        int len;
        StringBuilder stringBuilder = new StringBuilder();
        System.out.println("启动完成, 正在接受数据....");
        while (true) {
            len = inputStream.read(bytes);
            if (len != -1) {
                stringBuilder.append(new String(bytes, 0, len));
                stringBuilder = test(stringBuilder);
            }
        }
    }

    private static StringBuilder test(StringBuilder stringBuilder) {
        String text = stringBuilder.toString();
        if (text.contains(Bean.SPLIT)) {
            int index = text.indexOf(Bean.SPLIT);
            String json = text.substring(0, index);
            Bean bean = JSONObject.parseObject(json, Bean.class);
            send(bean);
            text = text.substring(index + Bean.SPLIT.length());
            return new StringBuilder(text);
        } else {
            return stringBuilder;
        }
    }

    private static void send(Bean bean) {
        try {

            String baseUrl = bean.getUrl();
            String uri = "http://" + JenkinsIp + ":" + JenkinsPort + (baseUrl.startsWith("/") ? baseUrl : "/" + baseUrl);
            if (null != bean.getParam()) uri += "?" + bean.getParam();
            System.out.println("开始部署: " + uri);
            URL url = new URL(uri);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);

            // 请求类型
            urlConnection.setRequestMethod(bean.getMethod());

            // 请求头
            bean.getHeaderMap().forEach(urlConnection::addRequestProperty);

            // 请求参数
            urlConnection.getOutputStream().write(bean.getBody());

            // 发送请求并且获取返回数据
            InputStream inputStream = urlConnection.getInputStream();
            byte[] bytes = new byte[1024 * 8];
            int len;
            StringBuilder stringBuilder = new StringBuilder();
            while ((len = inputStream.read(bytes)) != -1) {
                stringBuilder.append(new String(bytes, 0, len));
            }
            System.out.println("结果: " + stringBuilder.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

接下来在jenkins获取请求地址, 在github上设置将ip修改成云服务器的ip

完成

你可能感兴趣的:(解决github的Webhooks无法通知本地内网jenkins(需要准备云服务器))