本文主要研究一下PowerJob的ContainerTemplateGenerator

ContainerTemplateGenerator

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

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

    @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。


codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...


引用和评论

0 条评论