未验证 提交 b3ba2ae4 编写于 作者: 小东 提交者: Gitee

!40 git store插件

Merge pull request !40 from Sor1e/sorie_2.x_git2
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.0.0-alpha.4</version>
</parent>
<artifactId>magic-api-plugin-git-store</artifactId>
<packaging>jar</packaging>
<name>magic-api-plugin-git-store</name>
<description>magic-api-plugin-git-store</description>
<properties>
<jgit.version>5.13.0.202109080827-r</jgit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>${jgit.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.jsch</artifactId>
<version>${jgit.version}</version>
</dependency>
</dependencies>
</project>
package org.ssssssss.magicapi.git;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jgit.api.*;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.*;
import org.eclipse.jgit.util.FS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.ssssssss.magicapi.core.exception.MagicAPIException;
import java.io.File;
import java.io.IOException;
/**
* git仓库
*
* @author soriee
* @date 2022/2/20 22:48
*/
public class GitRepo {
private static final Logger logger = LoggerFactory.getLogger(GitRepo.class);
/**
* 文件路径地址
*/
private String rootPath;
private String gitFilePath;
private GitStoreProperties properties;
private Git git;
public GitRepo(String rootPath, GitStoreProperties properties) {
this.rootPath = rootPath;
this.gitFilePath = rootPath + File.separator + ".git";
this.properties = properties;
}
private void valid() {
File repoDir = new File(rootPath);
File gitFile = new File(gitFilePath);
// 如果文件夹不存在 则创建文件夹
if (!repoDir.exists()) {
repoDir.mkdirs();
}
if (!gitFile.exists() && repoDir.list().length > 0) {
throw new MagicAPIException("初次项目启动时,请保持文件夹为空。");
}
}
/**
* 设置ssh秘钥或者账号密码
*
* @param transportCommand
* @return
* @author soriee
* @date 2022/2/28 20:06
*/
private void setSshOrCredentials(TransportCommand transportCommand) {
if (this.getProperties().getPrivateKey() != null) {
// ssh
final SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
@Override
protected void configure(OpenSshConfig.Host host, Session session) {
}
@Override
protected JSch createDefaultJSch(FS fs) throws JSchException {
JSch defaultJSch = super.createDefaultJSch(fs);
defaultJSch.addIdentity(GitRepo.this.getProperties().getPrivateKey());
return defaultJSch;
}
};
transportCommand.setTransportConfigCallback(new TransportConfigCallback() {
@Override
public void configure(Transport transport) {
SshTransport sshTransport = (SshTransport) transport;
sshTransport.setSshSessionFactory(sshSessionFactory);
}
});
} else if (StringUtils.isNotBlank(properties.getUsername())
&& StringUtils.isNotBlank(properties.getPassword())) {
// 账号密码
transportCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(
properties.getUsername(),
properties.getPassword()));
}
}
/**
* 项目设置仓库
*
* @return
* @author soriee
* @date 2022/2/24 20:43
*/
public void setupRepo() throws IOException, GitAPIException {
this.valid();
File gitFile = new File(gitFilePath);
try {
if (gitFile.exists()) {
// 项目存在,则打开为仓库, 并且强制更新一次
FileRepositoryBuilder builder = new FileRepositoryBuilder();
Repository repository = builder.create(gitFile);
git = new Git(repository);
// 更新两次,避免删除文件未更新
this.update(false);
this.update(true);
} else {
CloneCommand cloneCommand = Git.cloneRepository()
.setURI(properties.getUrl())
.setDirectory(new File(rootPath))
.setBranch(properties.getBranch());
this.setSshOrCredentials(cloneCommand);
git = cloneCommand.call();
}
} catch (IOException | GitAPIException e) {
logger.error("初始化git仓库失败", e);
throw e;
}
}
/**
* 更新
* 1.git add .
* 2.git commit -m "同步数据"
* 3.git pull
* 4.git push
* @param update
* @return
* @author soriee
* @date 2022/2/20 22:54
*/
public boolean update(boolean update) {
try {
git.add().setUpdate(update).addFilepattern(".").call();
git.commit().setMessage("同步数据").call();
PullCommand pull = git.pull();
this.setSshOrCredentials(pull);
PullResult pullResult = pull.call();
if (!pullResult.isSuccessful()) {
throw new MagicAPIException("git更新失败, 请重试或尝试手动更新");
}
PushCommand pushCommand = git.push();
this.setSshOrCredentials(pushCommand);
pushCommand.call();
} catch (GitAPIException e) {
logger.error("git更新失败", e);
throw new MagicAPIException("git更新失败, 请重试或尝试手动更新");
}
return true;
}
public GitStoreProperties getProperties() {
return properties;
}
}
package org.ssssssss.magicapi.git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.ssssssss.magicapi.core.resource.FileResource;
import org.ssssssss.magicapi.core.resource.Resource;
import org.ssssssss.magicapi.core.resource.ResourceAdapter;
import org.ssssssss.magicapi.git.GitStoreProperties;
import org.ssssssss.magicapi.utils.IoUtils;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* 文件存储实现
*
* @author mxd
*/
public class GitResource extends FileResource {
private GitRepo gitRepo;
public static GitResource of(org.ssssssss.magicapi.core.config.Resource config, GitStoreProperties properties) throws IOException, GitAPIException {
File file = new File(config.getLocation());
GitRepo gitRepo = new GitRepo(file.getAbsolutePath(), properties);
GitResource gitResource = new GitResource(config.isReadonly(), file,
file.getAbsolutePath(), gitRepo);
// 初始化
gitResource.setup();
return gitResource;
}
public GitResource(boolean readonly, File file, String rootPath, GitRepo gitRepo) {
super(file, readonly, rootPath);
this.gitRepo = gitRepo;
}
/**
* 进行初始化操作, 仅仅在项目启动时进行初始化
* @author soriee
* @date 2022/2/20 22:30
* @return
*/
private void setup() throws IOException, GitAPIException {
synchronized(GitResource.class) {
gitRepo.setupRepo();
}
}
private boolean update(boolean update) {
return gitRepo.update(update);
}
@Override
public boolean delete() {
return super.delete() && this.update(true);
}
@Override
public boolean mkdir() {
return super.mkdir() && this.update(false);
}
@Override
public Resource getResource(String name) {
return new GitResource(super.readonly(), new File(super.file, name), super.rootPath, this.gitRepo);
}
@Override
public Resource getDirectory(String name) {
return getResource(name);
}
@Override
public boolean write(byte[] bytes) {
return super.write(bytes) && this.update(false);
}
@Override
public boolean write(String content) {
return super.write(content) && this.update(false);
}
@Override
public List<Resource> resources() {
File[] files = this.file.listFiles();
return files == null ? Collections.emptyList() : Arrays.stream(files).map(it -> new GitResource(this.readonly(),
it, this.rootPath, this.gitRepo)).collect(Collectors.toList());
}
@Override
public Resource parent() {
return this.rootPath.equals(this.file.getAbsolutePath()) ? null : new GitResource(this.readonly(),
this.file.getParentFile(), this.rootPath, this.gitRepo);
}
@Override
public List<Resource> dirs() {
return IoUtils.dirs(this.file).stream().map(it -> new GitResource(this.readonly(),
it, this.rootPath, this.gitRepo)).collect(Collectors.toList());
}
@Override
public List<Resource> files(String suffix) {
return IoUtils.files(this.file, suffix).stream().map(it -> new GitResource(this.readonly(),
it, this.rootPath, this.gitRepo)).collect(Collectors.toList());
}
@Override
public boolean renameTo(Resource resource) {
if (!this.readonly()) {
File target = ((GitResource) resource).file;
if (this.file.renameTo(target)) {
this.file = target;
// 更新两次,新增文件和删除文件都要更新
this.update(false);
this.update(true);
return true;
}
}
return false;
}
@Override
public String toString() {
return this.gitRepo.getProperties().getUrl();
}
}
package org.ssssssss.magicapi.git;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "magic-api.resource.git")
public class GitStoreProperties {
/**
* git仓库地址
*/
private String url;
/**
* git分支
*/
private String branch;
/**
* ssh 密钥地址
* 仅支持-m PEM参数生产的ssh key
*/
private String privateKey;
/**
* git账号
*/
private String username;
/**
* git密码
*/
private String password;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getBranch() {
return branch;
}
public void setBranch(String branch) {
this.branch = branch;
}
public String getPrivateKey() {
return privateKey;
}
public void setPrivateKey(String privateKey) {
this.privateKey = privateKey;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
package org.ssssssss.magicapi.git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.ssssssss.magicapi.core.config.MagicAPIProperties;
import org.ssssssss.magicapi.core.config.MagicPluginConfiguration;
import org.ssssssss.magicapi.core.config.Resource;
import org.ssssssss.magicapi.core.model.Plugin;
import org.ssssssss.magicapi.git.GitStoreProperties;
import java.io.IOException;
@Configuration
@EnableConfigurationProperties(GitStoreProperties.class)
public class MagicGitStoreConfiguration implements MagicPluginConfiguration {
private final MagicAPIProperties properties;
private final GitStoreProperties gitStoreProperties;
public MagicGitStoreConfiguration(MagicAPIProperties properties, GitStoreProperties gitStoreProperties) {
this.properties = properties;
this.gitStoreProperties = gitStoreProperties;
}
/**
* git存储
* @author soriee
* @date 2022/2/28 19:50
* @return
*/
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "magic-api", name = "resource.type", havingValue = "git")
public org.ssssssss.magicapi.core.resource.Resource magicGitResource() throws IOException, GitAPIException {
Resource resourceConfig = properties.getResource();
return GitResource.of(resourceConfig, this.gitStoreProperties);
}
@Override
public Plugin plugin() {
return new Plugin("Git");
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.ssssssss.magicapi.git.MagicGitStoreConfiguration
......@@ -20,6 +20,7 @@
<module>magic-api-plugin-mongo</module>
<module>magic-api-plugin-elasticsearch</module>
<module>magic-api-plugin-cluster</module>
<module>magic-api-plugin-git-store</module>
</modules>
<dependencies>
<dependency>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册