前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊PowerJob的ContainerTemplateGenerator

聊聊PowerJob的ContainerTemplateGenerator

作者头像
code4it
发布2024-02-21 15:51:54
680
发布2024-02-21 15:51:54
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下PowerJob的ContainerTemplateGenerator

ContainerTemplateGenerator

tech/powerjob/server/core/container/ContainerTemplateGenerator.java

代码语言:javascript
复制
public class ContainerTemplateGenerator {

    private static final String ORIGIN_FILE_NAME = "oms-template-origin";

    /**
     * 生成 container 的模版文件
     * @param group pom group标签
     * @param artifact pom artifact标签
     * @param name pom name标签
     * @param packageName 包名
     * @param javaVersion Java版本
     * @return 压缩包
     * @throws IOException 异常
     */
    public static File generate(String group, String artifact, String name, String packageName, Integer javaVersion) throws IOException {

        String workerDir = OmsFileUtils.genTemporaryWorkPath();
        File originJar = new File(workerDir + "tmp.jar");
        String tmpPath = workerDir + "/unzip/";

        // CentOS 7 上 getResource 会报 FileNotFoundException,原因不详...
        try (InputStream is = ContainerTemplateGenerator.class.getClassLoader().getResourceAsStream(ORIGIN_FILE_NAME + ".zip")) {
            Objects.requireNonNull(is, "generate container template failed, can't find zip file in classpath.");
            FileUtils.copyInputStreamToFile(is, originJar);
        }

        ZipFile zipFile = new ZipFile(originJar);
        zipFile.extractAll(tmpPath);
        String rootPath = tmpPath + ORIGIN_FILE_NAME;

        // 1. 修改 pom.xml (按行读,读取期间更改,然后回写)
        String pomPath = rootPath + "/pom.xml";

        String line;
        StringBuilder buffer = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new FileReader(pomPath))) {
            while ((line = br.readLine()) != null) {

                if (line.contains("<groupId>groupId</groupId>")) {
                    buffer.append("    <groupId>").append(group).append("</groupId>");
                }else if (line.contains("<artifactId>artifactId</artifactId>")) {
                    buffer.append("    <artifactId>").append(artifact).append("</artifactId>");
                }else if (line.contains("<name>name</name>")) {
                    buffer.append("    <name>").append(name).append("</name>");
                }else if (line.contains("<maven.compiler.source>")) {
                    buffer.append("        <maven.compiler.source>").append(javaVersion).append("</maven.compiler.source>");
                }else if (line.contains("<maven.compiler.target>")) {
                    buffer.append("        <maven.compiler.target>").append(javaVersion).append("</maven.compiler.target>");
                } else {
                    buffer.append(line);
                }
                buffer.append(System.lineSeparator());
            }
        }
        OmsFileUtils.string2File(buffer.toString(), new File(pomPath));

        // 2. 新建目录
        String packagePath = StringUtils.replace(packageName, ".", "/");
        String absPath = rootPath + "/src/main/java/" + packagePath;
        FileUtils.forceMkdir(new File(absPath));

        // 3. 修改 Spring 配置文件
        String resourcePath = rootPath + "/src/main/resources/";
        String springXMLPath = resourcePath + ContainerConstant.SPRING_CONTEXT_FILE_NAME;
        buffer.setLength(0);

        try (BufferedReader br = new BufferedReader(new FileReader(springXMLPath))) {
            while ((line = br.readLine()) != null) {

                if (line.contains("<context:component-scan base-package=\"")) {
                    buffer.append("    <context:component-scan base-package=\"").append(packageName).append("\"/>");
                }else {
                    buffer.append(line);
                }
                buffer.append(System.lineSeparator());
            }
        }
        OmsFileUtils.string2File(buffer.toString(), new File(springXMLPath));

        // 4. 写入 packageName,便于容器加载用户类
        String propertiesPath = resourcePath + ContainerConstant.CONTAINER_PROPERTIES_FILE_NAME;
        String properties = ContainerConstant.CONTAINER_PACKAGE_NAME_KEY + "=" + packageName;
        OmsFileUtils.string2File(properties, new File(propertiesPath));

        // 5. 再打包回去
        String finPath = tmpPath + "template.zip";
        ZipFile finZip = new ZipFile(finPath);
        finZip.addFolder(new File(rootPath));

        // 6. 删除源文件
        FileUtils.forceDelete(originJar);

        return finZip.getFile();
    }
}

ContainerTemplateGenerator的generate方法提供了生成外置动态加载的代码模版,它从classpath读取oms-template-origin.zip文件,然后解压到临时目录,之后按行读取pom.xml文件,替换掉group、name、javaVersion信息,接着在src/main/java下面写入包名对应的目录,然后替换src/main/resources/oms-worker-container-spring-context.xml中base-package的包名,在oms-worker-container.properties中写入PACKAGE_NAME,然后重新打包为template.zip

downloadContainerTemplate

tech/powerjob/server/web/controller/ContainerController.java

代码语言:javascript
复制
    @PostMapping("/downloadContainerTemplate")
    public void downloadContainerTemplate(@RequestBody GenerateContainerTemplateRequest req, HttpServletResponse response) throws IOException {
        File zipFile = ContainerTemplateGenerator.generate(req.getGroup(), req.getArtifact(), req.getName(), req.getPackageName(), req.getJavaVersion());
        OmsFileUtils.file2HttpResponse(zipFile, response);
    }

downloadContainerTemplate方法调用的就是ContainerTemplateGenerator.generate来生成模版代码

小结

PowerJob的ContainerTemplateGenerator的generate方法提供了生成外置动态加载的代码模版,它主要是新建包目录,替换了里头的pom.xml以及src/main/resources/oms-worker-container-spring-context.xml中base-package的包名,在oms-worker-container.properties中写入PACKAGE_NAME。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-02-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码匠的流水账 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ContainerTemplateGenerator
  • downloadContainerTemplate
  • 小结
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档