diff --git a/eladmin-system/pom.xml b/eladmin-system/pom.xml index 8c350703..168b9d69 100644 --- a/eladmin-system/pom.xml +++ b/eladmin-system/pom.xml @@ -25,6 +25,11 @@ 2.3 + + org.springframework.boot + spring-boot-starter-websocket + + io.jsonwebtoken @@ -38,6 +43,18 @@ quartz + + ch.ethz.ganymed + ganymed-ssh2 + build210 + + + + com.jcraft + jsch + 0.1.55 + + @@ -56,4 +73,4 @@ - \ No newline at end of file + diff --git a/eladmin-system/src/main/java/me/zhengjie/config/WebSocketConfig.java b/eladmin-system/src/main/java/me/zhengjie/config/WebSocketConfig.java new file mode 100644 index 00000000..66bd61f5 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/config/WebSocketConfig.java @@ -0,0 +1,19 @@ +package me.zhengjie.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * @author: ZhangHouYing + * @date: 2019-08-24 15:44 + */ +@Configuration +public class WebSocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/App.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/App.java new file mode 100644 index 00000000..2806f912 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/App.java @@ -0,0 +1,70 @@ +package me.zhengjie.modules.mnt.domain; + +import lombok.Data; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import javax.persistence.*; +import java.io.Serializable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Entity +@Data +@Table(name="mnt_app") +public class App implements Serializable { + + /** + * 应用编号 + */ + @Id + @Column(name = "id") + private String id; + + /** + * 应用名称 + */ + @Column(name = "name") + private String name; + + /** + * 端口 + */ + @Column(name = "port") + private int port; + + /** + * 上传目录 + */ + @Column(name = "upload_path") + private String uploadPath; + + /** + * 部署目录 + */ + @Column(name = "deploy_path") + private String deployPath; + + /** + * 备份目录 + */ + @Column(name = "backup_path") + private String backupPath; + + /** + * 启动脚本 + */ + @Column(name = "start_script") + private String startScript; + + /** + * 部署脚本 + */ + @Column(name = "deploy_script") + private String deployScript; + + public void copy(App source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/Database.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/Database.java new file mode 100644 index 00000000..6e7ab00c --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/Database.java @@ -0,0 +1,53 @@ +package me.zhengjie.modules.mnt.domain; + +import lombok.Data; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import javax.persistence.*; +import java.io.Serializable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Entity +@Data +@Table(name="mnt_database") +public class Database implements Serializable { + + /** + * id + */ + @Id + @Column(name = "id") + private String id; + + /** + * 数据库名称 + */ + @Column(name = "name",nullable = false) + private String name; + + /** + * 数据库连接地址 + */ + @Column(name = "jdbc_url",nullable = false) + private String jdbcUrl; + + /** + * 数据库密码 + */ + @Column(name = "pwd",nullable = false) + private String pwd; + + /** + * 用户名 + */ + @Column(name = "user_name",nullable = false) + private String userName; + + + public void copy(Database source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/Deploy.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/Deploy.java new file mode 100644 index 00000000..cd9832c0 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/Deploy.java @@ -0,0 +1,40 @@ +package me.zhengjie.modules.mnt.domain; + +import lombok.Data; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import javax.persistence.*; +import java.io.Serializable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Entity +@Data +@Table(name="mnt_deploy") +public class Deploy implements Serializable { + + /** + * 部署编号 + */ + @Id + @Column(name = "id") + private String id; + + /** + * 应用编号 + */ + @Column(name = "app_id") + private String appId; + + /** + * IP列表 + */ + @Column(name = "ip") + private String ip; + + public void copy(Deploy source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/DeployHistory.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/DeployHistory.java new file mode 100644 index 00000000..748ba7ed --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/DeployHistory.java @@ -0,0 +1,58 @@ +package me.zhengjie.modules.mnt.domain; + +import lombok.Data; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import javax.persistence.*; +import java.io.Serializable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Entity +@Data +@Table(name="mnt_deploy_history") +public class DeployHistory implements Serializable { + + /** + * 编号 + */ + @Id + @Column(name = "id") + private String id; + + /** + * 应用名称 + */ + @Column(name = "app_name",nullable = false) + private String appName; + + /** + * 部署IP + */ + @Column(name = "ip",nullable = false) + private String ip; + + /** + * 部署时间 + */ + @Column(name = "deploy_date",nullable = false) + private String deployDate; + + /** + * 部署人员 + */ + @Column(name = "deploy_user",nullable = false) + private String deployUser; + + /** + * 部署编号 + */ + @Column(name = "deploy_id",nullable = false) + private String deployId; + + public void copy(DeployHistory source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/ServerAccount.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/ServerAccount.java new file mode 100644 index 00000000..86d62925 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/ServerAccount.java @@ -0,0 +1,46 @@ +package me.zhengjie.modules.mnt.domain; + +import lombok.Data; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import javax.persistence.*; +import java.io.Serializable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Entity +@Data +@Table(name="mnt_server_account") +public class ServerAccount implements Serializable { + + /** + * 编号 + */ + @Id + @Column(name = "id") + private String id; + + /** + * 名称 + */ + @Column(name = "name") + private String name; + + /** + * 账号 + */ + @Column(name = "account") + private String account; + + /** + * 密码 + */ + @Column(name = "password") + private String password; + + public void copy(ServerAccount source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/ServerDeploy.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/ServerDeploy.java new file mode 100644 index 00000000..49a2a07f --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/domain/ServerDeploy.java @@ -0,0 +1,34 @@ +package me.zhengjie.modules.mnt.domain; + +import lombok.Data; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import javax.persistence.*; +import java.io.Serializable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Entity +@Data +@Table(name="mnt_server") +public class ServerDeploy implements Serializable { + + /** + * 服务器IP + */ + @Id + @Column(name = "id") + private String id; + + /** + * 服务器账号 + */ + @Column(name = "account_id") + private String accountId; + + public void copy(ServerDeploy source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/AppRepository.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/AppRepository.java new file mode 100644 index 00000000..725d0e2b --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/AppRepository.java @@ -0,0 +1,12 @@ +package me.zhengjie.modules.mnt.repository; + +import me.zhengjie.modules.mnt.domain.App; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface AppRepository extends JpaRepository, JpaSpecificationExecutor { +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/DatabaseRepository.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/DatabaseRepository.java new file mode 100644 index 00000000..a998c442 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/DatabaseRepository.java @@ -0,0 +1,12 @@ +package me.zhengjie.modules.mnt.repository; + +import me.zhengjie.modules.mnt.domain.Database; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface DatabaseRepository extends JpaRepository, JpaSpecificationExecutor { +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/DeployHistoryRepository.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/DeployHistoryRepository.java new file mode 100644 index 00000000..d7439203 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/DeployHistoryRepository.java @@ -0,0 +1,12 @@ +package me.zhengjie.modules.mnt.repository; + +import me.zhengjie.modules.mnt.domain.DeployHistory; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface DeployHistoryRepository extends JpaRepository, JpaSpecificationExecutor { +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/DeployRepository.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/DeployRepository.java new file mode 100644 index 00000000..d4590d71 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/DeployRepository.java @@ -0,0 +1,12 @@ +package me.zhengjie.modules.mnt.repository; + +import me.zhengjie.modules.mnt.domain.Deploy; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface DeployRepository extends JpaRepository, JpaSpecificationExecutor { +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/ServerAccountRepository.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/ServerAccountRepository.java new file mode 100644 index 00000000..88e96b5d --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/ServerAccountRepository.java @@ -0,0 +1,12 @@ +package me.zhengjie.modules.mnt.repository; + +import me.zhengjie.modules.mnt.domain.ServerAccount; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface ServerAccountRepository extends JpaRepository, JpaSpecificationExecutor { +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/ServerDeployRepository.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/ServerDeployRepository.java new file mode 100644 index 00000000..4681216d --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/repository/ServerDeployRepository.java @@ -0,0 +1,12 @@ +package me.zhengjie.modules.mnt.repository; + +import me.zhengjie.modules.mnt.domain.ServerDeploy; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface ServerDeployRepository extends JpaRepository, JpaSpecificationExecutor { +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/AppController.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/AppController.java new file mode 100644 index 00000000..080963a1 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/AppController.java @@ -0,0 +1,66 @@ +package me.zhengjie.modules.mnt.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import me.zhengjie.aop.log.Log; +import me.zhengjie.modules.mnt.domain.App; +import me.zhengjie.modules.mnt.service.AppService; +import me.zhengjie.modules.mnt.service.dto.AppQueryCriteria; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Api(tags = "应用管理") +@RestController +@RequestMapping("/api/app") +public class AppController { + + @Autowired + private AppService appService; + + public AppController(AppService appService){ + this.appService = this.appService; + } + + @Log("查询App") + @ApiOperation(value = "查询App") + @GetMapping + @PreAuthorize("@el.check('app:list')") + public ResponseEntity getApps(AppQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity(appService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("新增App") + @ApiOperation(value = "新增App") + @PostMapping + @PreAuthorize("@el.check('app:add')") + public ResponseEntity create(@Validated @RequestBody App resources){ + return new ResponseEntity(appService.create(resources),HttpStatus.CREATED); + } + + @Log("修改App") + @ApiOperation(value = "修改App") + @PutMapping + @PreAuthorize("@el.check('app:edit')") + public ResponseEntity update(@Validated @RequestBody App resources){ + appService.update(resources); + return new ResponseEntity(HttpStatus.NO_CONTENT); + } + + @Log("删除App") + @ApiOperation(value = "删除App") + @DeleteMapping(value = "/{id}") + @PreAuthorize("@el.check('app:del')") + public ResponseEntity delete(@PathVariable String id){ + appService.delete(id); + return new ResponseEntity(HttpStatus.OK); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/DatabaseController.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/DatabaseController.java new file mode 100644 index 00000000..ea006e57 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/DatabaseController.java @@ -0,0 +1,62 @@ +package me.zhengjie.modules.mnt.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import me.zhengjie.aop.log.Log; +import me.zhengjie.modules.mnt.domain.Database; +import me.zhengjie.modules.mnt.service.DatabaseService; +import me.zhengjie.modules.mnt.service.dto.DatabaseQueryCriteria; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Api(tags = "数据库管理") +@RestController +@RequestMapping("/api/database") +public class DatabaseController { + + @Autowired + private DatabaseService databaseService; + + @Log("查询Database") + @ApiOperation(value = "查询Database") + @GetMapping + @PreAuthorize("@el.check('database:list')") + public ResponseEntity getDatabases(DatabaseQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity(databaseService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("新增Database") + @ApiOperation(value = "新增Database") + @PostMapping + @PreAuthorize("@el.check('database:add')") + public ResponseEntity create(@Validated @RequestBody Database resources){ + return new ResponseEntity(databaseService.create(resources),HttpStatus.CREATED); + } + + @Log("修改Database") + @ApiOperation(value = "修改Database") + @PutMapping + @PreAuthorize("@el.check('database:edit')") + public ResponseEntity update(@Validated @RequestBody Database resources){ + databaseService.update(resources); + return new ResponseEntity(HttpStatus.NO_CONTENT); + } + + @Log("删除Database") + @ApiOperation(value = "删除Database") + @DeleteMapping(value = "/{id}") + @PreAuthorize("@el.check('database:del')") + public ResponseEntity delete(@PathVariable String id){ + databaseService.delete(id); + return new ResponseEntity(HttpStatus.OK); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/DeployController.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/DeployController.java new file mode 100644 index 00000000..a50ae44a --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/DeployController.java @@ -0,0 +1,129 @@ +package me.zhengjie.modules.mnt.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import me.zhengjie.aop.log.Log; +import me.zhengjie.modules.mnt.domain.Deploy; +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.service.DeployService; +import me.zhengjie.modules.mnt.service.dto.DeployQueryCriteria; +import me.zhengjie.utils.FileUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Api(tags = "部署管理") +@RestController +@RequestMapping("/api/deploy") +public class DeployController { + + private String fileSavePath = System.getProperty("java.io.tmpdir"); + + @Autowired + private DeployService deployService; + + @Log("查询Deploy") + @ApiOperation(value = "查询Deploy") + @GetMapping + @PreAuthorize("@el.check('deploy:list')") + public ResponseEntity getDeploys(DeployQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity(deployService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("新增Deploy") + @ApiOperation(value = "新增Deploy") + @PostMapping + @PreAuthorize("@el.check('deploy:add')") + public ResponseEntity create(@Validated @RequestBody Deploy resources){ + return new ResponseEntity(deployService.create(resources),HttpStatus.CREATED); + } + + @Log("修改Deploy") + @ApiOperation(value = "修改Deploy") + @PutMapping + @PreAuthorize("@el.check('deploy:edit')") + public ResponseEntity update(@Validated @RequestBody Deploy resources){ + deployService.update(resources); + return new ResponseEntity(HttpStatus.NO_CONTENT); + } + + @Log("删除Deploy") + @ApiOperation(value = "删除Deploy") + @DeleteMapping(value = "/{id}") + @PreAuthorize("@el.check('deploy:del')") + public ResponseEntity delete(@PathVariable String id){ + deployService.delete(id); + return new ResponseEntity(HttpStatus.OK); + } + + @Log("上传文件Deploy") + @ApiOperation(value = "上传文件Deploy") + @PostMapping(value = "/upload") + @PreAuthorize("@el.check('deploy:edit')") + public ResponseEntity upload(@RequestBody MultipartFile file, HttpServletRequest request, HttpServletResponse response)throws Exception{ + String id = request.getParameter("id"); + String fileName = ""; + if(file != null){ + fileName = file.getOriginalFilename(); + File deployFile = new File(fileSavePath+fileName); + FileUtil.del(deployFile); + file.transferTo(deployFile); + //文件下一步要根据文件名字来 + deployService.deploy(fileSavePath+fileName ,id); + }else{ + System.out.println("没有找到相对应的文件"); + } + System.out.println("文件上传的原名称为:"+file.getOriginalFilename()); + Map map = new HashMap(2); + map.put("errno",0); + map.put("id",fileName); + return new ResponseEntity(map,HttpStatus.OK); + } + @Log("系统还原") + @ApiOperation(value = "系统还原") + @PostMapping(value = "/serverReduction") + @PreAuthorize("@el.check('deploy:edit')") + public ResponseEntity serverReduction(@Validated @RequestBody DeployHistory resources, HttpServletRequest request, HttpServletResponse response)throws Exception{ + String result = deployService.serverReduction(resources); + return new ResponseEntity(result,HttpStatus.OK); + } + @Log("服务运行状态") + @ApiOperation(value = "服务运行状态") + @PostMapping(value = "/serverStatus") + @PreAuthorize("@el.check('deploy:edit')") + public ResponseEntity serverStatus(@Validated @RequestBody Deploy resources, HttpServletRequest request, HttpServletResponse response)throws Exception{ + String result = deployService.serverStatus(resources); + return new ResponseEntity(result,HttpStatus.OK); + } + @Log("启动服务") + @ApiOperation(value = "启动服务") + @PostMapping(value = "/startServer") + @PreAuthorize("@el.check('deploy:edit')") + public ResponseEntity startServer(@Validated @RequestBody Deploy resources, HttpServletRequest request, HttpServletResponse response)throws Exception{ + String result = deployService.startServer(resources); + return new ResponseEntity(result,HttpStatus.OK); + } + @Log("停止服务") + @ApiOperation(value = "停止服务") + @PostMapping(value = "/stopServer") + @PreAuthorize("@el.check('deploy:edit')") + public ResponseEntity stopServer(@Validated @RequestBody Deploy resources, HttpServletRequest request, HttpServletResponse response)throws Exception{ + String result = deployService.stopServer(resources); + return new ResponseEntity(result,HttpStatus.OK); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/DeployHistoryController.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/DeployHistoryController.java new file mode 100644 index 00000000..e43f7c7c --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/DeployHistoryController.java @@ -0,0 +1,62 @@ +package me.zhengjie.modules.mnt.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import me.zhengjie.aop.log.Log; +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.service.DeployHistoryService; +import me.zhengjie.modules.mnt.service.dto.DeployHistoryQueryCriteria; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Api(tags = "部署历史管理") +@RestController +@RequestMapping("/api/deployHistory") +public class DeployHistoryController { + + @Autowired + private DeployHistoryService deployhistoryService; + + @Log("查询DeployHistory") + @ApiOperation(value = "查询DeployHistory") + @GetMapping + @PreAuthorize("@el.check('deployHistory:list')") + public ResponseEntity getDeployHistorys(DeployHistoryQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity(deployhistoryService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("新增DeployHistory") + @ApiOperation(value = "新增DeployHistory") + @PostMapping + @PreAuthorize("@el.check('deployHistory:add')") + public ResponseEntity create(@Validated @RequestBody DeployHistory resources){ + return new ResponseEntity(deployhistoryService.create(resources),HttpStatus.CREATED); + } + + @Log("修改DeployHistory") + @ApiOperation(value = "修改DeployHistory") + @PutMapping + @PreAuthorize("@el.check('deployHistory:edit')") + public ResponseEntity update(@Validated @RequestBody DeployHistory resources){ + deployhistoryService.update(resources); + return new ResponseEntity(HttpStatus.NO_CONTENT); + } + + @Log("删除DeployHistory") + @ApiOperation(value = "删除DeployHistory") + @DeleteMapping(value = "/{id}") + @PreAuthorize("hasAnyRole('deployHistory:del')") + public ResponseEntity delete(@PathVariable String id){ + deployhistoryService.delete(id); + return new ResponseEntity(HttpStatus.OK); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/ServerAccountController.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/ServerAccountController.java new file mode 100644 index 00000000..b6ebd255 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/ServerAccountController.java @@ -0,0 +1,61 @@ +package me.zhengjie.modules.mnt.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import me.zhengjie.aop.log.Log; +import me.zhengjie.modules.mnt.domain.ServerAccount; +import me.zhengjie.modules.mnt.service.dto.ServerAccountQueryCriteria; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Api(tags = "服务器账号管理") +@RestController +@RequestMapping("/api/serverAccount") +public class ServerAccountController { + + @Autowired + private me.zhengjie.modules.mnt.service.ServerAccountService ServerAccountService; + + @Log("查询ServerAccount") + @ApiOperation(value = "查询ServerAccount") + @GetMapping + @PreAuthorize("@el.check('serverAccount:list')") + public ResponseEntity getServerAccounts(ServerAccountQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity(ServerAccountService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("新增ServerAccount") + @ApiOperation(value = "新增ServerAccount") + @PostMapping + @PreAuthorize("@el.check('serverAccount:add')") + public ResponseEntity create(@Validated @RequestBody ServerAccount resources){ + return new ResponseEntity(ServerAccountService.create(resources),HttpStatus.CREATED); + } + + @Log("修改ServerAccount") + @ApiOperation(value = "修改ServerAccount") + @PutMapping + @PreAuthorize("@el.check('serverAccount:edit')") + public ResponseEntity update(@Validated @RequestBody ServerAccount resources){ + ServerAccountService.update(resources); + return new ResponseEntity(HttpStatus.NO_CONTENT); + } + + @Log("删除ServerAccount") + @ApiOperation(value = "删除ServerAccount") + @DeleteMapping(value = "/{id}") + @PreAuthorize("@el.check('serverAccount:del')") + public ResponseEntity delete(@PathVariable String id){ + ServerAccountService.delete(id); + return new ResponseEntity(HttpStatus.OK); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/ServerDeployController.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/ServerDeployController.java new file mode 100644 index 00000000..58400c48 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/rest/ServerDeployController.java @@ -0,0 +1,62 @@ +package me.zhengjie.modules.mnt.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import me.zhengjie.aop.log.Log; +import me.zhengjie.modules.mnt.domain.ServerDeploy; +import me.zhengjie.modules.mnt.service.ServerDeployService; +import me.zhengjie.modules.mnt.service.dto.ServerDeployQueryCriteria; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Api(tags = "服务器部署管理") +@RestController +@RequestMapping("/api/serverDeploy") +public class ServerDeployController { + + @Autowired + private ServerDeployService serverDeployService; + + @Log("查询Server") + @ApiOperation(value = "查询Server") + @GetMapping + @PreAuthorize("@el.check('serverDeploy:list')") + public ResponseEntity getServers(ServerDeployQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity(serverDeployService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @Log("新增Server") + @ApiOperation(value = "新增Server") + @PostMapping + @PreAuthorize("@el.check('serverDeploy:add')") + public ResponseEntity create(@Validated @RequestBody ServerDeploy resources){ + return new ResponseEntity(serverDeployService.create(resources),HttpStatus.CREATED); + } + + @Log("修改Server") + @ApiOperation(value = "修改Server") + @PutMapping + @PreAuthorize("@el.check('serverDeploy:edit')") + public ResponseEntity update(@Validated @RequestBody ServerDeploy resources){ + serverDeployService.update(resources); + return new ResponseEntity(HttpStatus.NO_CONTENT); + } + + @Log("删除Server") + @ApiOperation(value = "删除Server") + @DeleteMapping(value = "/{id:.+}") + @PreAuthorize("@el.check('serverDeploy:del')") + public ResponseEntity delete(@PathVariable String id){ + serverDeployService.delete(id); + return new ResponseEntity(HttpStatus.OK); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/AppService.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/AppService.java new file mode 100644 index 00000000..ef5dcdd4 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/AppService.java @@ -0,0 +1,54 @@ +package me.zhengjie.modules.mnt.service; + +import me.zhengjie.modules.mnt.domain.App; +import me.zhengjie.modules.mnt.service.dto.AppDTO; +import me.zhengjie.modules.mnt.service.dto.AppQueryCriteria; +import org.springframework.data.domain.Pageable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface AppService { + + /** + * queryAll 分页 + * @param criteria + * @param pageable + * @return + */ + Object queryAll(AppQueryCriteria criteria, Pageable pageable); + + /** + * queryAll 不分页 + * @param criteria + * @return + */ + public Object queryAll(AppQueryCriteria criteria); + + /** + * findById + * @param id + * @return + */ + AppDTO findById(String id); + + /** + * create + * @param resources + * @return + */ + AppDTO create(App resources); + + /** + * update + * @param resources + */ + void update(App resources); + + /** + * delete + * @param id + */ + void delete(String id); +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/DatabaseService.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/DatabaseService.java new file mode 100644 index 00000000..5915789b --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/DatabaseService.java @@ -0,0 +1,54 @@ +package me.zhengjie.modules.mnt.service; + +import me.zhengjie.modules.mnt.domain.Database; +import me.zhengjie.modules.mnt.service.dto.DatabaseDTO; +import me.zhengjie.modules.mnt.service.dto.DatabaseQueryCriteria; +import org.springframework.data.domain.Pageable; + +/** + * @author: ZhangHouYing + * @date 2019-08-24 + */ +public interface DatabaseService { + + /** + * queryAll 分页 + * @param criteria + * @param pageable + * @return + */ + Object queryAll(DatabaseQueryCriteria criteria, Pageable pageable); + + /** + * queryAll 不分页 + * @param criteria + * @return + */ + public Object queryAll(DatabaseQueryCriteria criteria); + + /** + * findById + * @param id + * @return + */ + DatabaseDTO findById(String id); + + /** + * create + * @param resources + * @return + */ + DatabaseDTO create(Database resources); + + /** + * update + * @param resources + */ + void update(Database resources); + + /** + * delete + * @param id + */ + void delete(String id); +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/DeployHistoryService.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/DeployHistoryService.java new file mode 100644 index 00000000..b9f16b63 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/DeployHistoryService.java @@ -0,0 +1,55 @@ +package me.zhengjie.modules.mnt.service; + +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.service.dto.DeployHistoryDTO; +import me.zhengjie.modules.mnt.service.dto.DeployHistoryQueryCriteria; +import org.springframework.data.domain.Pageable; + +/** + * + * @author: ZhangHouYing + * @date 2019-08-24 + */ +public interface DeployHistoryService { + + /** + * queryAll 分页 + * @param criteria + * @param pageable + * @return + */ + Object queryAll(DeployHistoryQueryCriteria criteria, Pageable pageable); + + /** + * queryAll 不分页 + * @param criteria + * @return + */ + public Object queryAll(DeployHistoryQueryCriteria criteria); + + /** + * findById + * @param id + * @return + */ + DeployHistoryDTO findById(String id); + + /** + * create + * @param resources + * @return + */ + DeployHistoryDTO create(DeployHistory resources); + + /** + * update + * @param resources + */ + void update(DeployHistory resources); + + /** + * delete + * @param id + */ + void delete(String id); +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/DeployService.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/DeployService.java new file mode 100644 index 00000000..51041037 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/DeployService.java @@ -0,0 +1,92 @@ +package me.zhengjie.modules.mnt.service; + +import me.zhengjie.modules.mnt.domain.Deploy; +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.service.dto.DeployDTO; +import me.zhengjie.modules.mnt.service.dto.DeployQueryCriteria; +import org.springframework.data.domain.Pageable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface DeployService { + + /** + * queryAll 分页 + * @param criteria + * @param pageable + * @return + */ + Object queryAll(DeployQueryCriteria criteria, Pageable pageable); + + /** + * queryAll 不分页 + * @param criteria + * @return + */ + public Object queryAll(DeployQueryCriteria criteria); + + /** + * findById + * @param id + * @return + */ + DeployDTO findById(String id); + + /** + * create + * @CacheEvict(allEntries = true) + * @param resources + * @return + */ + DeployDTO create(Deploy resources); + + /** + * update + * @CacheEvict(allEntries = true) + * @param resources + */ + void update(Deploy resources); + + /** + * delete + * @CacheEvict(allEntries = true) + * @param id + */ + void delete(String id); + + /** + * 部署文件到服务器 + * @param fileSavePath + * @param appId + * @return + */ + public String deploy(String fileSavePath, String appId); + + /** + * 查询部署状态 + * @param resources + * @return + */ + public String serverStatus(Deploy resources); + /** + * 启动服务 + * @param resources + * @return + */ + public String startServer(Deploy resources); + /** + * 停止服务 + * @param resources + * @return + */ + public String stopServer(Deploy resources); + + /** + * 停止服务 + * @param resources + * @return + */ + public String serverReduction(DeployHistory resources); +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/ServerAccountService.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/ServerAccountService.java new file mode 100644 index 00000000..c1b3cb96 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/ServerAccountService.java @@ -0,0 +1,54 @@ +package me.zhengjie.modules.mnt.service; + +import me.zhengjie.modules.mnt.domain.ServerAccount; +import me.zhengjie.modules.mnt.service.dto.ServerAccountDTO; +import me.zhengjie.modules.mnt.service.dto.ServerAccountQueryCriteria; +import org.springframework.data.domain.Pageable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface ServerAccountService { + + /** + * queryAll 分页 + * @param criteria + * @param pageable + * @return + */ + Object queryAll(ServerAccountQueryCriteria criteria, Pageable pageable); + + /** + * queryAll 不分页 + * @param criteria + * @return + */ + public Object queryAll(ServerAccountQueryCriteria criteria); + + /** + * findById + * @param id + * @return + */ + ServerAccountDTO findById(String id); + + /** + * create + * @param resources + * @return + */ + ServerAccountDTO create(ServerAccount resources); + + /** + * update + * @param resources + */ + void update(ServerAccount resources); + + /** + * delete + * @param id + */ + void delete(String id); +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/ServerDeployService.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/ServerDeployService.java new file mode 100644 index 00000000..68f155e2 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/ServerDeployService.java @@ -0,0 +1,54 @@ +package me.zhengjie.modules.mnt.service; + +import me.zhengjie.modules.mnt.domain.ServerDeploy; +import me.zhengjie.modules.mnt.service.dto.ServerDeployDTO; +import me.zhengjie.modules.mnt.service.dto.ServerDeployQueryCriteria; +import org.springframework.data.domain.Pageable; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +public interface ServerDeployService { + + /** + * queryAll 分页 + * @param criteria + * @param pageable + * @return + */ + Object queryAll(ServerDeployQueryCriteria criteria, Pageable pageable); + + /** + * queryAll 不分页 + * @param criteria + * @return + */ + public Object queryAll(ServerDeployQueryCriteria criteria); + + /** + * findById + * @param id + * @return + */ + ServerDeployDTO findById(String id); + + /** + * create + * @param resources + * @return + */ + ServerDeployDTO create(ServerDeploy resources); + + /** + * update + * @param resources + */ + void update(ServerDeploy resources); + + /** + * delete + * @param id + */ + void delete(String id); +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/AppDTO.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/AppDTO.java new file mode 100644 index 00000000..ef137449 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/AppDTO.java @@ -0,0 +1,55 @@ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; + +import java.io.Serializable; + + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class AppDTO implements Serializable { + + /** + * 应用编号 + */ + private String id; + + /** + * 应用名称 + */ + private String name; + + /** + * 端口 + */ + private int port; + + /** + * 上传目录 + */ + private String uploadPath; + + /** + * 部署目录 + */ + private String deployPath; + + /** + * 备份目录 + */ + private String backupPath; + + /** + * 启动脚本 + */ + private String startScript; + + /** + * 部署脚本 + */ + private String deployScript; + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/AppQueryCriteria.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/AppQueryCriteria.java new file mode 100644 index 00000000..a52007e8 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/AppQueryCriteria.java @@ -0,0 +1,18 @@ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class AppQueryCriteria{ + + /** + * 模糊 + */ + @Query(type = Query.Type.INNER_LIKE) + private String name; +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DatabaseDTO.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DatabaseDTO.java new file mode 100644 index 00000000..90ac5653 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DatabaseDTO.java @@ -0,0 +1,39 @@ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import java.io.Serializable; + + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class DatabaseDTO implements Serializable { + + /** + * id + */ + private String id; + + /** + * 数据库名称 + */ + private String name; + + /** + * 数据库连接地址 + */ + private String jdbcUrl; + + /** + * 数据库密码 + */ + private String pwd; + + /** + * 用户名 + */ + private String userName; + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DatabaseQueryCriteria.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DatabaseQueryCriteria.java new file mode 100644 index 00000000..8ac919ec --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DatabaseQueryCriteria.java @@ -0,0 +1,24 @@ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class DatabaseQueryCriteria{ + + /** + * 模糊 + */ + @Query(type = Query.Type.INNER_LIKE) + private String name; + + /** + * 精确 + */ + @Query + private String jdbcUrl; +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployDTO.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployDTO.java new file mode 100644 index 00000000..4d65da68 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployDTO.java @@ -0,0 +1,35 @@ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import java.io.Serializable; + + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class DeployDTO implements Serializable { + + /** + * 部署编号 + */ + private String id; + + /** + * 应用编号 + */ + private String appId; + + /** + * IP列表 + */ + private String ip; + + + /** + * 服务状态 + */ + private String status; + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployHistoryDTO.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployHistoryDTO.java new file mode 100644 index 00000000..19da3b5a --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployHistoryDTO.java @@ -0,0 +1,43 @@ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import java.io.Serializable; + + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class DeployHistoryDTO implements Serializable { + + /** + * 编号 + */ + private String id; + + /** + * 应用名称 + */ + private String appName; + + /** + * 部署IP + */ + private String ip; + + /** + * 部署时间 + */ + private String deployDate; + + /** + * 部署人员 + */ + private String deployUser; + + /** + * 部署编号 + */ + private String deployId; +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployHistoryQueryCriteria.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployHistoryQueryCriteria.java new file mode 100644 index 00000000..e869e471 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployHistoryQueryCriteria.java @@ -0,0 +1,23 @@ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class DeployHistoryQueryCriteria{ + + /** + * 精确 + */ + @Query + private String deployId; + /** + * 模糊 + */ + @Query(type = Query.Type.INNER_LIKE) + private String deployDate; +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployQueryCriteria.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployQueryCriteria.java new file mode 100644 index 00000000..bf93a8a4 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/DeployQueryCriteria.java @@ -0,0 +1,25 @@ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class DeployQueryCriteria{ + + /** + * 模糊 + */ + @Query(type = Query.Type.EQUAL) + private String appId; + + /** + * 模糊 + */ + @Query(type = Query.Type.INNER_LIKE) + private String ip; + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerAccountDTO.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerAccountDTO.java new file mode 100644 index 00000000..59887cf1 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerAccountDTO.java @@ -0,0 +1,33 @@ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import java.io.Serializable; + + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class ServerAccountDTO implements Serializable { + + /** + * 编号 + */ + private String id; + + /** + * 名称 + */ + private String name; + + /** + * 账号 + */ + private String account; + + /** + * 密码 + */ + private String password; +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerAccountQueryCriteria.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerAccountQueryCriteria.java new file mode 100644 index 00000000..348f4833 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerAccountQueryCriteria.java @@ -0,0 +1,25 @@ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class ServerAccountQueryCriteria{ + + /** + * 模糊 + */ + @Query(type = Query.Type.INNER_LIKE) + private String name; + + /** + * 模糊 + */ + @Query(type = Query.Type.INNER_LIKE) + private String account; + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerDeployDTO.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerDeployDTO.java new file mode 100644 index 00000000..e17c08f1 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerDeployDTO.java @@ -0,0 +1,23 @@ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import java.io.Serializable; + + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class ServerDeployDTO implements Serializable { + + /** + * 服务器IP + */ + private String id; + + /** + * 服务器账号 + */ + private String accountId; +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerDeployQueryCriteria.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerDeployQueryCriteria.java new file mode 100644 index 00000000..c37aae2a --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/dto/ServerDeployQueryCriteria.java @@ -0,0 +1,19 @@ +package me.zhengjie.modules.mnt.service.dto; + +import lombok.Data; +import me.zhengjie.annotation.Query; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Data +public class ServerDeployQueryCriteria{ + + /** + * 模糊 + */ + @Query(type = Query.Type.INNER_LIKE) + private String id; + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/AppServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/AppServiceImpl.java new file mode 100644 index 00000000..2a25f1af --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/AppServiceImpl.java @@ -0,0 +1,78 @@ +package me.zhengjie.modules.mnt.service.impl; + +import cn.hutool.core.util.IdUtil; +import me.zhengjie.modules.mnt.domain.App; +import me.zhengjie.modules.mnt.repository.AppRepository; +import me.zhengjie.modules.mnt.service.AppService; +import me.zhengjie.modules.mnt.service.dto.AppDTO; +import me.zhengjie.modules.mnt.service.dto.AppQueryCriteria; +import me.zhengjie.modules.mnt.service.mapper.AppMapper; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import me.zhengjie.utils.ValidationUtil; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class AppServiceImpl implements AppService { + + private AppRepository appRepository; + + private AppMapper appMapper; + + public AppServiceImpl(AppRepository appRepository, AppMapper appMapper) { + this.appMapper = appMapper; + this.appRepository = appRepository; + } + + @Override + public Object queryAll(AppQueryCriteria criteria, Pageable pageable){ + Page page = appRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(appMapper::toDto)); + } + + @Override + public Object queryAll(AppQueryCriteria criteria){ + return appMapper.toDto(appRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + } + + @Override + public AppDTO findById(String id) { + Optional app = appRepository.findById(id); + ValidationUtil.isNull(app,"App","id",id); + return appMapper.toDto(app.get()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public AppDTO create(App resources) { + resources.setId(IdUtil.fastUUID()); + return appMapper.toDto(appRepository.save(resources)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(App resources) { + Optional optionalApp = appRepository.findById(resources.getId()); + ValidationUtil.isNull( optionalApp,"App","id",resources.getId()); + App App = optionalApp.get(); + App.copy(resources); + appRepository.save(App); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(String id) { + appRepository.deleteById(id); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DatabaseServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DatabaseServiceImpl.java new file mode 100644 index 00000000..10c5585d --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DatabaseServiceImpl.java @@ -0,0 +1,78 @@ +package me.zhengjie.modules.mnt.service.impl; + +import cn.hutool.core.util.IdUtil; +import me.zhengjie.modules.mnt.domain.Database; +import me.zhengjie.modules.mnt.repository.DatabaseRepository; +import me.zhengjie.modules.mnt.service.DatabaseService; +import me.zhengjie.modules.mnt.service.dto.DatabaseDTO; +import me.zhengjie.modules.mnt.service.dto.DatabaseQueryCriteria; +import me.zhengjie.modules.mnt.service.mapper.DatabaseMapper; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import me.zhengjie.utils.ValidationUtil; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class DatabaseServiceImpl implements DatabaseService { + + private DatabaseRepository databaseRepository; + + private DatabaseMapper databaseMapper; + + public DatabaseServiceImpl(DatabaseRepository databaseRepository,DatabaseMapper databaseMapper){ + this.databaseMapper = databaseMapper; + this.databaseRepository = databaseRepository; + } + + @Override + public Object queryAll(DatabaseQueryCriteria criteria, Pageable pageable){ + Page page = databaseRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(databaseMapper::toDto)); + } + + @Override + public Object queryAll(DatabaseQueryCriteria criteria){ + return databaseMapper.toDto(databaseRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + } + + @Override + public DatabaseDTO findById(String id) { + Optional database = databaseRepository.findById(id); + ValidationUtil.isNull(database,"Database","id",id); + return databaseMapper.toDto(database.get()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public DatabaseDTO create(Database resources) { + resources.setId(IdUtil.simpleUUID()); + return databaseMapper.toDto(databaseRepository.save(resources)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Database resources) { + Optional optionalDatabase = databaseRepository.findById(resources.getId()); + ValidationUtil.isNull( optionalDatabase,"Database","id",resources.getId()); + Database database = optionalDatabase.get(); + database.copy(resources); + databaseRepository.save(database); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(String id) { + databaseRepository.deleteById(id); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployHistoryServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployHistoryServiceImpl.java new file mode 100644 index 00000000..465cba74 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployHistoryServiceImpl.java @@ -0,0 +1,76 @@ +package me.zhengjie.modules.mnt.service.impl; + +import cn.hutool.core.util.IdUtil; +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.repository.DeployHistoryRepository; +import me.zhengjie.modules.mnt.service.DeployHistoryService; +import me.zhengjie.modules.mnt.service.dto.DeployHistoryDTO; +import me.zhengjie.modules.mnt.service.dto.DeployHistoryQueryCriteria; +import me.zhengjie.modules.mnt.service.mapper.DeployHistoryMapper; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import me.zhengjie.utils.ValidationUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class DeployHistoryServiceImpl implements DeployHistoryService { + + @Autowired + private DeployHistoryRepository deployhistoryRepository; + + @Autowired + private DeployHistoryMapper deployhistoryMapper; + + @Override + public Object queryAll(DeployHistoryQueryCriteria criteria, Pageable pageable){ + Page page = deployhistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(deployhistoryMapper::toDto)); + } + + @Override + public Object queryAll(DeployHistoryQueryCriteria criteria){ + return deployhistoryMapper.toDto(deployhistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + } + + @Override + public DeployHistoryDTO findById(String id) { + Optional deployhistory = deployhistoryRepository.findById(id); + ValidationUtil.isNull(deployhistory,"DeployHistory","id",id); + return deployhistoryMapper.toDto(deployhistory.get()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public DeployHistoryDTO create(DeployHistory resources) { + resources.setId(IdUtil.simpleUUID()); + return deployhistoryMapper.toDto(deployhistoryRepository.save(resources)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(DeployHistory resources) { + Optional optionalDeployHistory = deployhistoryRepository.findById(resources.getId()); + ValidationUtil.isNull( optionalDeployHistory,"DeployHistory","id",resources.getId()); + DeployHistory deployhistory = optionalDeployHistory.get(); + deployhistory.copy(resources); + deployhistoryRepository.save(deployhistory); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(String id) { + deployhistoryRepository.deleteById(id); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployServiceImpl.java new file mode 100644 index 00000000..ae7e71c5 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployServiceImpl.java @@ -0,0 +1,427 @@ +package me.zhengjie.modules.mnt.service.impl; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.mnt.domain.Deploy; +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.repository.DeployRepository; +import me.zhengjie.modules.mnt.service.*; +import me.zhengjie.modules.mnt.service.dto.*; +import me.zhengjie.modules.mnt.service.mapper.DeployMapper; +import me.zhengjie.modules.mnt.util.ExecuteShellUtil; +import me.zhengjie.modules.mnt.util.ScpClientUtil; +import me.zhengjie.modules.mnt.websocket.MsgType; +import me.zhengjie.modules.mnt.websocket.SocketMsg; +import me.zhengjie.modules.mnt.websocket.WebSocketServer; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import me.zhengjie.utils.SecurityUtils; +import me.zhengjie.utils.ValidationUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.io.IOException; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +/** + * @author zhanghouying + * @date 2019-08-24 + */ +@Slf4j +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class DeployServiceImpl implements DeployService { + + private final String FILE_SEPARATOR = File.separatorChar + ""; + + @Autowired + private DeployRepository deployRepository; + + @Autowired + private DeployMapper deployMapper; + + @Autowired + private AppService appService; + + @Autowired + private ServerDeployService serverDeployService; + + @Autowired + private DeployHistoryService deployHistoryService; + + @Autowired + private ServerAccountService serverAccountService; + + @Autowired + private DatabaseService databaseService; + + + @Override + public Object queryAll(DeployQueryCriteria criteria, Pageable pageable) { + Page page = deployRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); + return PageUtil.toPage(page.map(deployMapper::toDto)); + } + + @Override + public List queryAll(DeployQueryCriteria criteria) { + return deployMapper.toDto(deployRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder))); + } + + @Override + public DeployDTO findById(String id) { + Optional Deploy = deployRepository.findById(id); + ValidationUtil.isNull(Deploy, "Deploy", "id", id); + return deployMapper.toDto(Deploy.get()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public DeployDTO create(Deploy resources) { + resources.setId(IdUtil.simpleUUID()); + return deployMapper.toDto(deployRepository.save(resources)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(Deploy resources) { + Optional optionalDeploy = deployRepository.findById(resources.getId()); + ValidationUtil.isNull(optionalDeploy, "Deploy", "id", resources.getId()); + Deploy Deploy = optionalDeploy.get(); + Deploy.copy(resources); + deployRepository.save(Deploy); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(String id) { + deployRepository.deleteById(id); + } + + @Override + public String deploy(String fileSavePath, String id) { + return deployApp(fileSavePath, id); + } + + /** + * @param fileSavePath 本机路径 + * @param id + * @return + */ + private String deployApp(String fileSavePath, String id) { + + DeployDTO deploy = findById(id); + if (deploy == null) { + sendMsg("部署信息不存在", MsgType.ERROR); + throw new BadRequestException("部署信息不存在"); + } + AppDTO app = appService.findById(deploy.getAppId()); + if (app == null) { + sendMsg("包对应应用信息不存在", MsgType.ERROR); + throw new BadRequestException("包对应应用信息不存在"); + } + int port = app.getPort(); + //这个是服务器部署路径 + String uploadPath = app.getUploadPath(); + StringBuilder sb = new StringBuilder(); + String msg = ""; + String ip = deploy.getIp(); + ExecuteShellUtil executeShellUtil = getExecuteShellUtil(ip); + //判断是否第一次部署 + boolean flag = checkFile(executeShellUtil, app); + //第一步要确认服务器上有这个目录 + executeShellUtil.execute("mkdir -p " + uploadPath); + //上传文件 + msg = String.format("登陆到服务器:%s", ip); + ScpClientUtil scpClientUtil = getScpClientUtil(ip); + log.info(msg); + sendMsg(msg, MsgType.INFO); + msg = String.format("上传文件到服务器:%s
目录:%s下", fileSavePath, ip, uploadPath); + sendMsg(msg, MsgType.INFO); + scpClientUtil.putFile(fileSavePath, uploadPath); + if (flag) { + sendMsg("停止原来应用", MsgType.INFO); + //停止应用 + stopApp(port, executeShellUtil); + sendMsg("备份原来应用", MsgType.INFO); + //备份应用 + backupApp(executeShellUtil, ip, app.getDeployPath(), app.getName(), app.getBackupPath(), id); + } + sendMsg("部署应用", MsgType.INFO); + //部署文件,并启动应用 + String deployScript = app.getDeployScript(); + executeShellUtil.execute(deployScript); + + sendMsg("启动应用", MsgType.INFO); + String startScript = app.getStartScript(); + executeShellUtil.execute(startScript); + //只有过5秒才能知道到底是不是启动成功了。 + sleep(5); + boolean result = checkIsRunningStatus(port, executeShellUtil); + sb.append("服务器:").append(ip).append("
应用:").append(app.getName()); + sendResultMsg(result, sb); + + return "部署结束"; + } + + private void sleep(int second) { + try { + Thread.sleep(second * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + private void backupApp(ExecuteShellUtil executeShellUtil, String ip, String fileSavePath, String appName, String backupPath, String id) { + String deployDate = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN); + StringBuilder sb = new StringBuilder(); + if (!backupPath.endsWith(FILE_SEPARATOR)) { + backupPath += FILE_SEPARATOR; + } + backupPath += appName + FILE_SEPARATOR + deployDate + "\n"; + sb.append("mkdir -p ").append(backupPath); + sb.append("mv -f ").append(fileSavePath); + if (!fileSavePath.endsWith(FILE_SEPARATOR)) { + sb.append(FILE_SEPARATOR); + } + sb.append(appName).append(" ").append(backupPath); + log.info("备份应用脚本:" + sb.toString()); + executeShellUtil.execute(sb.toString()); + //还原信息入库 + DeployHistory deployHistory = new DeployHistory(); + deployHistory.setAppName(appName); + deployHistory.setDeployDate(deployDate); + deployHistory.setDeployUser(SecurityUtils.getUsername()); + deployHistory.setIp(ip); + deployHistory.setDeployId(id); + deployHistoryService.create(deployHistory); + } + + /** + * 停App + * + * @param port + * @param executeShellUtil + * @return + */ + private void stopApp(int port, ExecuteShellUtil executeShellUtil) { + //发送停止命令 + executeShellUtil.execute(String.format("lsof -i :%d|grep -v \"PID\"|awk '{print \"kill -9\",$2}'|sh", port)); + + } + + /** + * 指定端口程序是否在运行 + * + * @param port + * @param executeShellUtil + * @return true 正在运行 false 已经停止 + */ + private boolean checkIsRunningStatus(int port, ExecuteShellUtil executeShellUtil) { + String statusResult = executeShellUtil.executeForResult(String.format("fuser -n tcp %d", port)); + if ("".equals(statusResult.trim())) { + return false; + } else { + return true; + } + } + + private void sendMsg(String msg, MsgType msgType) { + try { + WebSocketServer.sendInfo(new SocketMsg(msg, msgType), "deploy"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + @Override + public String serverStatus(Deploy resources) { + String ip = resources.getIp(); + String appId = resources.getAppId(); + AppDTO app = appService.findById(appId); + StringBuffer sb = new StringBuffer(); + ExecuteShellUtil executeShellUtil = getExecuteShellUtil(ip); + sb.append("服务器:").append(ip).append("
应用:").append(app.getName()); + boolean result = checkIsRunningStatus(app.getPort(), executeShellUtil); + if (result) { + sb.append("
正在运行"); + sendMsg(sb.toString(), MsgType.INFO); + } else { + sb.append("
已停止!"); + sendMsg(sb.toString(), MsgType.ERROR); + } + log.info(sb.toString()); + return "执行完毕"; + } + + + private boolean checkFile(ExecuteShellUtil executeShellUtil, AppDTO appDTO) { + StringBuffer sb = new StringBuffer(); + sb.append("find "); + sb.append(appDTO.getDeployPath()); + sb.append(" -name "); + sb.append(appDTO.getName()); + boolean flag = executeShellUtil.executeShell(sb.toString()); + return flag; + } + + /** + * 启动服务 + * + * @param resources + * @return + */ + @Override + public String startServer(Deploy resources) { + String ip = resources.getIp(); + String appId = resources.getAppId(); + AppDTO app = appService.findById(appId); + StringBuilder sb = new StringBuilder(); + ExecuteShellUtil executeShellUtil = getExecuteShellUtil(ip); + //为了防止重复启动,这里先停止应用 + stopApp(app.getPort(), executeShellUtil); + sb.append("服务器:").append(ip).append("
应用:").append(app.getName()); + sendMsg("下发启动命令", MsgType.INFO); + executeShellUtil.execute(app.getStartScript()); + //停止3秒,防止应用没有启动完成 + sleep(3); + boolean result = checkIsRunningStatus(app.getPort(), executeShellUtil); + sendResultMsg(result, sb); + log.info(sb.toString()); + return "执行完毕"; + } + + ; + + /** + * 停止服务 + * + * @param resources + * @return + */ + @Override + public String stopServer(Deploy resources) { + String ip = resources.getIp(); + String appId = resources.getAppId(); + AppDTO app = appService.findById(appId); + StringBuffer sb = new StringBuffer(); + ExecuteShellUtil executeShellUtil = getExecuteShellUtil(ip); + sb.append("服务器:").append(ip).append("
应用:").append(app.getName()); + sendMsg("下发停止命令", MsgType.INFO); + //停止应用 + stopApp(app.getPort(), executeShellUtil); + sleep(1); + boolean result = checkIsRunningStatus(app.getPort(), executeShellUtil); + if (result) { + sb.append("
关闭失败!"); + sendMsg(sb.toString(), MsgType.ERROR); + } else { + sb.append("
关闭成功!"); + sendMsg(sb.toString(), MsgType.INFO); + } + log.info(sb.toString()); + return "执行完毕"; + } + + ; + + @Override + public String serverReduction(DeployHistory resources) { + String deployId = resources.getDeployId(); + Deploy deployInfo = deployRepository.findById(deployId).get(); + String deployDate = resources.getDeployDate(); + AppDTO app = appService.findById(deployInfo.getAppId()); + if (app == null) { + sendMsg("应用信息不存在:" + resources.getAppName(), MsgType.ERROR); + throw new BadRequestException("应用信息不存在:" + resources.getAppName()); + } + String backupPath = app.getBackupPath(); + if (!backupPath.endsWith(FILE_SEPARATOR)) { + backupPath += FILE_SEPARATOR; + } + backupPath += resources.getAppName() + FILE_SEPARATOR + deployDate; + //这个是服务器部署路径 + String deployPath = app.getDeployPath(); + String ip = resources.getIp(); + ExecuteShellUtil executeShellUtil = getExecuteShellUtil(ip); + String msg = ""; + + msg = String.format("登陆到服务器:%s", ip); + log.info(msg); + sendMsg(msg, MsgType.INFO); + sendMsg("停止原来应用", MsgType.INFO); + //停止应用 + stopApp(app.getPort(), executeShellUtil); + //删除原来应用 + sendMsg("删除应用", MsgType.INFO); + //考虑到系统安全性,必须限制下操作目录 + if (!deployPath.startsWith("/opt")) { + throw new BadRequestException("部署路径必须在opt目录下:" + deployPath); + } + executeShellUtil.execute("rm -rf " + deployPath + FILE_SEPARATOR + resources.getAppName()); + + //还原应用 + sendMsg("还原应用", MsgType.INFO); + executeShellUtil.execute("cp -r " + backupPath + "/. " + deployPath); + sendMsg("启动应用", MsgType.INFO); + executeShellUtil.execute(app.getStartScript()); + //只有过5秒才能知道到底是不是启动成功了。 + sleep(5); + boolean result = checkIsRunningStatus(app.getPort(), executeShellUtil); + StringBuilder sb = new StringBuilder(); + sb.append("服务器:").append(ip).append("
应用:").append(resources.getAppName()); + sendResultMsg(result, sb); + return ""; + } + + private ExecuteShellUtil getExecuteShellUtil(String ip) { + ServerDeployDTO serverDeployDTO = serverDeployService.findById(ip); + if (serverDeployDTO == null) { + sendMsg("IP对应服务器信息不存在:" + ip, MsgType.ERROR); + throw new BadRequestException("IP对应服务器信息不存在:" + ip); + } + String accountId = serverDeployDTO.getAccountId(); + ServerAccountDTO serverAccountDTO = serverAccountService.findById(accountId); + if (serverAccountDTO == null) { + sendMsg("IP对账号信息不存在:" + ip, MsgType.ERROR); + throw new BadRequestException("IP对账号信息不存在:" + ip); + } + return new ExecuteShellUtil(ip, serverAccountDTO.getAccount(), serverAccountDTO.getPassword()); + } + + + private ScpClientUtil getScpClientUtil(String ip) { + ServerDeployDTO serverDeployDTO = serverDeployService.findById(ip); + if (serverDeployDTO == null) { + sendMsg("IP对应服务器信息不存在:" + ip, MsgType.ERROR); + throw new BadRequestException("IP对应服务器信息不存在:" + ip); + } + String accountId = serverDeployDTO.getAccountId(); + ServerAccountDTO serverAccountDTO = serverAccountService.findById(accountId); + if (serverAccountDTO == null) { + sendMsg("IP对账号信息不存在:" + ip, MsgType.ERROR); + throw new BadRequestException("IP对账号信息不存在:" + ip); + } + return ScpClientUtil.getInstance(ip, 22, serverAccountDTO.getAccount(), serverAccountDTO.getPassword()); + } + + public void sendResultMsg(boolean result, StringBuilder sb) { + if (result) { + sb.append("
启动成功!"); + sendMsg(sb.toString(), MsgType.INFO); + } else { + sb.append("
启动失败!"); + sendMsg(sb.toString(), MsgType.ERROR); + } + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/ServerAccountServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/ServerAccountServiceImpl.java new file mode 100644 index 00000000..f54ad903 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/ServerAccountServiceImpl.java @@ -0,0 +1,76 @@ +package me.zhengjie.modules.mnt.service.impl; + +import cn.hutool.core.util.IdUtil; +import me.zhengjie.modules.mnt.domain.ServerAccount; +import me.zhengjie.modules.mnt.repository.ServerAccountRepository; +import me.zhengjie.modules.mnt.service.ServerAccountService; +import me.zhengjie.modules.mnt.service.dto.ServerAccountDTO; +import me.zhengjie.modules.mnt.service.dto.ServerAccountQueryCriteria; +import me.zhengjie.modules.mnt.service.mapper.ServerAccountMapper; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import me.zhengjie.utils.ValidationUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class ServerAccountServiceImpl implements ServerAccountService { + + @Autowired + private ServerAccountRepository serverAccountRepository; + + @Autowired + private ServerAccountMapper serverAccountMapper; + + @Override + public Object queryAll(ServerAccountQueryCriteria criteria, Pageable pageable){ + Page page = serverAccountRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(serverAccountMapper::toDto)); + } + + @Override + public Object queryAll(ServerAccountQueryCriteria criteria){ + return serverAccountMapper.toDto(serverAccountRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + } + + @Override + public ServerAccountDTO findById(String id) { + Optional ServerAccount = serverAccountRepository.findById(id); + ValidationUtil.isNull(ServerAccount,"ServerAccount","id",id); + return serverAccountMapper.toDto(ServerAccount.get()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public ServerAccountDTO create(ServerAccount resources) { + resources.setId(IdUtil.simpleUUID()); + return serverAccountMapper.toDto(serverAccountRepository.save(resources)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(ServerAccount resources) { + Optional optionalServerAccount = serverAccountRepository.findById(resources.getId()); + ValidationUtil.isNull( optionalServerAccount,"ServerAccount","id",resources.getId()); + ServerAccount ServerAccount = optionalServerAccount.get(); + ServerAccount.copy(resources); + serverAccountRepository.save(ServerAccount); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(String id) { + serverAccountRepository.deleteById(id); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/ServerDeployServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/ServerDeployServiceImpl.java new file mode 100644 index 00000000..3446fe33 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/ServerDeployServiceImpl.java @@ -0,0 +1,76 @@ +package me.zhengjie.modules.mnt.service.impl; + +import me.zhengjie.modules.mnt.domain.ServerDeploy; +import me.zhengjie.modules.mnt.repository.ServerDeployRepository; +import me.zhengjie.modules.mnt.service.ServerDeployService; +import me.zhengjie.modules.mnt.service.dto.ServerDeployDTO; +import me.zhengjie.modules.mnt.service.dto.ServerDeployQueryCriteria; +import me.zhengjie.modules.mnt.service.mapper.ServerDeployMapper; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import me.zhengjie.utils.ValidationUtil; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class ServerDeployServiceImpl implements ServerDeployService { + + private ServerDeployRepository serverDeployRepository; + + private ServerDeployMapper serverDeployMapper; + + public ServerDeployServiceImpl(ServerDeployRepository serverDeployRepository,ServerDeployMapper serverDeployMapper){ + this.serverDeployRepository = serverDeployRepository; + this.serverDeployMapper = serverDeployMapper; + } + + @Override + public Object queryAll(ServerDeployQueryCriteria criteria, Pageable pageable){ + Page page = serverDeployRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + return PageUtil.toPage(page.map(serverDeployMapper::toDto)); + } + + @Override + public Object queryAll(ServerDeployQueryCriteria criteria){ + return serverDeployMapper.toDto(serverDeployRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + } + + @Override + public ServerDeployDTO findById(String id) { + Optional server = serverDeployRepository.findById(id); + ValidationUtil.isNull(server,"ServerDeploy","id",id); + return serverDeployMapper.toDto(server.get()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public ServerDeployDTO create(ServerDeploy resources) { + return serverDeployMapper.toDto(serverDeployRepository.save(resources)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(ServerDeploy resources) { + Optional optionalServer = serverDeployRepository.findById(resources.getId()); + ValidationUtil.isNull( optionalServer,"ServerDeploy","id",resources.getId()); + ServerDeploy serverDeploy = optionalServer.get(); + serverDeploy.copy(resources); + serverDeployRepository.save(serverDeploy); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(String id) { + serverDeployRepository.deleteById(id); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/AppMapper.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/AppMapper.java new file mode 100644 index 00000000..bdda85f6 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/AppMapper.java @@ -0,0 +1,16 @@ +package me.zhengjie.modules.mnt.service.mapper; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.mnt.domain.App; +import me.zhengjie.modules.mnt.service.dto.AppDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Mapper(componentModel = "spring",uses = {},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface AppMapper extends BaseMapper { + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/DatabaseMapper.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/DatabaseMapper.java new file mode 100644 index 00000000..244b28d4 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/DatabaseMapper.java @@ -0,0 +1,16 @@ +package me.zhengjie.modules.mnt.service.mapper; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.mnt.domain.Database; +import me.zhengjie.modules.mnt.service.dto.DatabaseDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DatabaseMapper extends BaseMapper { + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/DeployHistoryMapper.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/DeployHistoryMapper.java new file mode 100644 index 00000000..811b68da --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/DeployHistoryMapper.java @@ -0,0 +1,16 @@ +package me.zhengjie.modules.mnt.service.mapper; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.mnt.domain.DeployHistory; +import me.zhengjie.modules.mnt.service.dto.DeployHistoryDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Mapper(componentModel = "spring",uses = {},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DeployHistoryMapper extends BaseMapper { + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/DeployMapper.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/DeployMapper.java new file mode 100644 index 00000000..7d2779e5 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/DeployMapper.java @@ -0,0 +1,16 @@ +package me.zhengjie.modules.mnt.service.mapper; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.mnt.domain.Deploy; +import me.zhengjie.modules.mnt.service.dto.DeployDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Mapper(componentModel = "spring",uses = {},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface DeployMapper extends BaseMapper { + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/ServerAccountMapper.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/ServerAccountMapper.java new file mode 100644 index 00000000..ece03299 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/ServerAccountMapper.java @@ -0,0 +1,16 @@ +package me.zhengjie.modules.mnt.service.mapper; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.mnt.domain.ServerAccount; +import me.zhengjie.modules.mnt.service.dto.ServerAccountDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Mapper(componentModel = "spring",uses = {},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface ServerAccountMapper extends BaseMapper { + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/ServerDeployMapper.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/ServerDeployMapper.java new file mode 100644 index 00000000..757e1909 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/mapper/ServerDeployMapper.java @@ -0,0 +1,16 @@ +package me.zhengjie.modules.mnt.service.mapper; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.mnt.domain.ServerDeploy; +import me.zhengjie.modules.mnt.service.dto.ServerDeployDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @author zhanghouying +* @date 2019-08-24 +*/ +@Mapper(componentModel = "spring",uses = {},unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface ServerDeployMapper extends BaseMapper { + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ExecuteShellUtil.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ExecuteShellUtil.java new file mode 100644 index 00000000..8071dbc2 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ExecuteShellUtil.java @@ -0,0 +1,106 @@ +package me.zhengjie.modules.mnt.util; + +import com.jcraft.jsch.*; +import lombok.extern.slf4j.Slf4j; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.Vector; + +/** + * 执行shell命令 + * @author: ZhangHouYing + * @date: 2019/8/10 + */ +@Slf4j +public class ExecuteShellUtil { + + private String ipAddress; + + private String username; + + private String password; + + public final int DEFAULT_SSH_PORT = 22; + + private Vector stdout; + + public ExecuteShellUtil(final String ipAddress, final String username, final String password) { + this.ipAddress = ipAddress; + this.username = username; + this.password = password; + stdout = new Vector(); + } + + public int execute(final String command) { + int returnCode = 0; + JSch jsch = new JSch(); + try { + Session session = jsch.getSession(username, ipAddress, DEFAULT_SSH_PORT); + session.setPassword(password); + session.setConfig("StrictHostKeyChecking", "no"); + session.connect(30000); + + Channel channel = session.openChannel("exec"); + ((ChannelExec) channel).setCommand(command); + + channel.setInputStream(null); + BufferedReader input = new BufferedReader(new InputStreamReader(channel.getInputStream())); + + channel.connect(); + log.info("The remote command is: " + command); + + String line; + while ((line = input.readLine()) != null) { + stdout.add(line); + } + input.close(); + + if (channel.isClosed()) { + returnCode = channel.getExitStatus(); + } + channel.disconnect(); + session.disconnect(); + } catch (JSchException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + return returnCode; + } + + public boolean executeShell(String command) { + int result = execute(command); + for (String str : stdout) { + log.info(str); + } + if (result == 0) { + return true; + } else { + return false; + } + } + public String executeForResult(String command) { + execute(command); + StringBuilder sb = new StringBuilder(); + for (String str : stdout) { + sb.append(str); + log.info(str); + } + return sb.toString(); + } + + /** + * 返回值有三条就代表成功了,2条是没启动,多余三条代表脚本有问题 + * @param command + * @return + */ + public int checkAppStatus(String command) { + execute(command); + for (String str : stdout) { + log.info(str); + } + return stdout.size(); + } + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ScpClientUtil.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ScpClientUtil.java new file mode 100644 index 00000000..a5dd59bc --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ScpClientUtil.java @@ -0,0 +1,88 @@ +package me.zhengjie.modules.mnt.util; + +import ch.ethz.ssh2.Connection; +import ch.ethz.ssh2.SCPClient; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * 远程执行linux命令 + * @author: ZhangHouYing + * @date: 2019-08-10 10:06 + */ +public class ScpClientUtil { + + static private ScpClientUtil instance; + + static synchronized public ScpClientUtil getInstance(String IP, int port, String username, String passward) { + if (instance == null) { + instance = new ScpClientUtil(IP, port, username, passward); + } + return instance; + } + + public ScpClientUtil(String IP, int port, String username, String passward) { + this.ip = IP; + this.port = port; + this.username = username; + this.password = passward; + } + + public void getFile(String remoteFile, String localTargetDirectory) { + Connection conn = new Connection(ip, port); + try { + conn.connect(); + boolean isAuthenticated = conn.authenticateWithPassword(username, password); + if (!isAuthenticated) { + System.err.println("authentication failed"); + } + SCPClient client = new SCPClient(conn); + client.get(remoteFile, localTargetDirectory); + } catch (IOException ex) { + Logger.getLogger(SCPClient.class.getName()).log(Level.SEVERE, null, ex); + }finally{ + conn.close(); + } + } + + public void putFile(String localFile, String remoteTargetDirectory) { + putFile(localFile, null, remoteTargetDirectory); + } + + public void putFile(String localFile, String remoteFileName, String remoteTargetDirectory) { + putFile(localFile, remoteFileName, remoteTargetDirectory,null); + } + + public void putFile(String localFile, String remoteFileName, String remoteTargetDirectory, String mode) { + Connection conn = new Connection(ip, port); + try { + conn.connect(); + boolean isAuthenticated = conn.authenticateWithPassword(username, password); + if (!isAuthenticated) { + System.err.println("authentication failed"); + } + SCPClient client = new SCPClient(conn); + if ((mode == null) || (mode.length() == 0)) { + mode = "0600"; + } + if (remoteFileName == null) { + client.put(localFile, remoteTargetDirectory); + } else { + client.put(localFile, remoteFileName, remoteTargetDirectory, mode); + } + } catch (IOException ex) { + Logger.getLogger(ScpClientUtil.class.getName()).log(Level.SEVERE, null, ex); + }finally{ + conn.close(); + } + } + + private String ip; + private int port; + private String username; + private String password; + + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ZipUtils.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ZipUtils.java new file mode 100644 index 00000000..b0e0697a --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ZipUtils.java @@ -0,0 +1,132 @@ +package me.zhengjie.modules.mnt.util; + +import java.io.*; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipException; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @author: ZhangHouYing + * @date: 2019-08-10 13:34 + */ +public class ZipUtils { + /** + * 解压文件 + * + * @param zipFilePath 解压文件路径 + * @param outputFolder 输出解压文件路径 + */ + public static void unZipIt(String zipFilePath, String outputFolder) { + byte[] buffer = new byte[1024]; + + File folder = new File(outputFolder); + if (!folder.exists()) { + folder.mkdir(); + } + try { + //get the zip file content + ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath)); + ZipEntry ze = zis.getNextEntry(); + while (ze != null) { + String fileName = ze.getName(); + File newFile = new File(outputFolder + File.separator + fileName); + System.out.println("file unzip : " + newFile.getAbsoluteFile()); + //大部分网络上的源码,这里没有判断子目录 + if (ze.isDirectory()) { + newFile.mkdirs(); + } else { + new File(newFile.getParent()).mkdirs(); + FileOutputStream fos = new FileOutputStream(newFile); + int len; + while ((len = zis.read(buffer)) != -1) { + fos.write(buffer, 0, len); + } + fos.close(); + } + ze = zis.getNextEntry(); + } + zis.closeEntry(); + zis.close(); + System.out.println("Done"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void unzip(File source, String out) throws IOException { + try (ZipInputStream zis = new ZipInputStream(new FileInputStream(source))) { + + ZipEntry entry = zis.getNextEntry(); + + while (entry != null) { + + File file = new File(out, entry.getName()); + + if (entry.isDirectory()) { + file.mkdirs(); + } else { + File parent = file.getParentFile(); + + if (!parent.exists()) { + parent.mkdirs(); + } + + try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) { + + byte[] buffer = new byte[Math.toIntExact(entry.getSize())]; + + int location; + + while ((location = zis.read(buffer)) != -1) { + bos.write(buffer, 0, location); + } + } + } + entry = zis.getNextEntry(); + } + } + } + + /** + * 把所有文件都直接解压到指定目录(忽略子文件夹) + * + * @param zipFile + * @param folderPath + * @throws ZipException + * @throws IOException + */ + public static void upZipFile(File zipFile, String folderPath) throws ZipException, IOException { + File desDir = new File(folderPath); + if (!desDir.exists()) { + desDir.mkdirs(); + } + ZipFile zf = new ZipFile(zipFile); + for (Enumeration entries = zf.entries(); entries.hasMoreElements(); ) { + ZipEntry entry = ((ZipEntry) entries.nextElement()); + InputStream in = zf.getInputStream(entry); + String str = folderPath; + File desFile = new File(str, java.net.URLEncoder.encode(entry.getName(), "UTF-8")); + + if (!desFile.exists()) { + File fileParentDir = desFile.getParentFile(); + if (!fileParentDir.exists()) { + fileParentDir.mkdirs(); + } + } + + OutputStream out = new FileOutputStream(desFile); + byte[] buffer = new byte[1024 * 1024]; + int realLength = in.read(buffer); + while (realLength != -1) { + out.write(buffer, 0, realLength); + realLength = in.read(buffer); + } + + out.close(); + in.close(); + + } + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/MsgType.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/MsgType.java new file mode 100644 index 00000000..1efd4de2 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/MsgType.java @@ -0,0 +1,9 @@ +package me.zhengjie.modules.mnt.websocket; + +/** + * @author: ZhangHouYing + * @date: 2019-08-10 9:56 + */ +public enum MsgType { + CONNECT,CLOSE,INFO,ERROR +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/SocketMsg.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/SocketMsg.java new file mode 100644 index 00000000..8a3fc9ee --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/SocketMsg.java @@ -0,0 +1,18 @@ +package me.zhengjie.modules.mnt.websocket; + +import lombok.Data; + +/** + * @author: ZhangHouYing + * @date: 2019-08-10 9:55 + */ +@Data +public class SocketMsg { + private String msg; + private MsgType msgType; + + public SocketMsg(String msg, MsgType msgType) { + this.msg = msg; + this.msgType = msgType; + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/WebSocketServer.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/WebSocketServer.java new file mode 100644 index 00000000..627d65c7 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/WebSocketServer.java @@ -0,0 +1,113 @@ +package me.zhengjie.modules.mnt.websocket; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.concurrent.CopyOnWriteArraySet; +/** + * @author: ZhangHouYing + * @date: 2019-08-10 15:46 + */ +@ServerEndpoint("/webSocket/{sid}") +@Slf4j +@Component +public class WebSocketServer { + + /** + * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 + */ + private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet(); + + /** + * 与某个客户端的连接会话,需要通过它来给客户端发送数据 + */ + private Session session; + + /** + * 接收sid + */ + private String sid=""; + /** + * 连接建立成功调用的方法 + * */ + @OnOpen + public void onOpen(Session session,@PathParam("sid") String sid) { + this.session = session; + //如果存在就先删除一个,防止重复推送消息 + for (WebSocketServer webSocket:webSocketSet) { + if (webSocket.sid.equals(sid)) { + webSocketSet.remove(webSocket); + } + } + webSocketSet.add(this); + this.sid=sid; + } + + /** + * 连接关闭调用的方法 + */ + @OnClose + public void onClose() { + webSocketSet.remove(this); + } + + /** + * 收到客户端消息后调用的方法 + * + * @param message 客户端发送过来的消息*/ + @OnMessage + public void onMessage(String message, Session session) { + log.info("收到来"+sid+"的信息:"+message); + //群发消息 + for (WebSocketServer item : webSocketSet) { + try { + item.sendMessage(message); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * + * @param session + * @param error + */ + @OnError + public void onError(Session session, Throwable error) { + log.error("发生错误"); + error.printStackTrace(); + } + /** + * 实现服务器主动推送 + */ + public void sendMessage(String message) throws IOException { + this.session.getBasicRemote().sendText(message); + } + + + /** + * 群发自定义消息 + * */ + public static void sendInfo(SocketMsg socketMsg,@PathParam("sid") String sid) throws IOException { + String message = JSONObject.toJSONString(socketMsg); + log.info("推送消息到"+sid+",推送内容:"+message); + for (WebSocketServer item : webSocketSet) { + try { + //这里可以设定只推送给这个sid的,为null则全部推送 + if(sid==null) { + item.sendMessage(message); + }else if(item.sid.equals(sid)){ + item.sendMessage(message); + } + } catch (IOException e) { + continue; + } + } + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java index 786fca90..1b097a1b 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java @@ -1,7 +1,6 @@ package me.zhengjie.modules.security.config; import me.zhengjie.annotation.AnonymousAccess; -import me.zhengjie.config.ElPermissionConfig; import me.zhengjie.modules.security.security.JwtAuthenticationEntryPoint; import me.zhengjie.modules.security.security.JwtAuthorizationTokenFilter; import me.zhengjie.modules.security.service.JwtUserDetailsService; @@ -108,7 +107,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { "/*.html", "/**/*.html", "/**/*.css", - "/**/*.js" + "/**/*.js", + "/webSocket/**" ).anonymous() // swagger start .antMatchers("/swagger-ui.html").permitAll() diff --git a/sql/eladmin-mnt.sql b/sql/eladmin-mnt.sql new file mode 100644 index 00000000..9f8ae3d3 --- /dev/null +++ b/sql/eladmin-mnt.sql @@ -0,0 +1,112 @@ + +-- ---------------------------- +-- Records of menu +-- ---------------------------- + +INSERT INTO `menu` VALUES (90, b'0', '运维管理', '', 0, 920, 'sys-tools', 'mnt', b'0', b'0', 'Mnt', '2019-11-09 10:31:08', NULL, 1); +INSERT INTO `menu` VALUES (91, b'0', '账号管理', 'mnt/account/index', 90, 100, 'user', 'mnt/account', b'0', b'0', 'Account', '2019-11-09 10:32:05', 'serverAccount:list', 1); +INSERT INTO `menu` VALUES (92, b'0', '服务器管理', 'mnt/serverDeploy/index', 90, 200, 'codeConsole', 'mnt/serverDeploy', b'0', b'0', 'ServerDeploy', '2019-11-10 10:29:25', 'serverDeploy:list', 1); +INSERT INTO `menu` VALUES (93, b'0', '应用管理', 'mnt/app/index', 90, 300, 'java', 'mnt/app', b'0', b'0', 'App', '2019-11-10 11:05:16', 'app:list', 1); +INSERT INTO `menu` VALUES (94, b'0', '部署管理', 'mnt/deploy/index', 90, 400, 'ipvisits', 'mnt/deploy', b'0', b'0', 'Deploy', '2019-11-10 15:56:55', 'deploy:list', 1); +INSERT INTO `menu` VALUES (97, b'0', '部署备份管理', 'mnt/deployHistory/index', 90, 500, 'ipvisits', 'mnt/deployHistory', b'0', b'0', 'DeployHistory', '2019-11-10 16:49:44', 'deployHistory:list', 1); +INSERT INTO `menu` VALUES (98, b'0', '数据库管理', 'mnt/database/index', 90, 600, 'zujian', 'mnt/database', b'0', b'0', 'Database', '2019-11-10 20:40:04', 'database:list', 1); +INSERT INTO `menu` VALUES (99, b'0', '账户新增', '', 91, 1, '', '', b'0', b'0', '', '2019-11-16 14:03:05', 'serverAccount:add', 2); +INSERT INTO `menu` VALUES (100, b'0', '账户编辑', '', 91, 2, '', '', b'0', b'0', '', '2019-11-16 14:06:26', 'serverAccount:edit', 2); +INSERT INTO `menu` VALUES (101, b'0', '账户删除', '', 91, 3, '', '', b'0', b'0', '', '2019-11-16 14:06:45', 'serverAccount:del', 2); +INSERT INTO `menu` VALUES (102, b'0', '删除', '', 97, 999, '', '', b'0', b'0', '', '2019-11-17 09:32:48', 'deployHistory:del', 2); +INSERT INTO `menu` VALUES (103, b'0', '服务器新增', '', 92, 999, '', '', b'0', b'0', '', '2019-11-17 11:08:33', 'serverDeploy:add', 2); +INSERT INTO `menu` VALUES (104, b'0', '服务器编辑', '', 92, 999, '', '', b'0', b'0', '', '2019-11-17 11:08:57', 'serverDeploy:edit', 2); +INSERT INTO `menu` VALUES (105, b'0', '服务器删除', '', 92, 999, '', '', b'0', b'0', '', '2019-11-17 11:09:15', 'serverDeploy:del', 2); +INSERT INTO `menu` VALUES (106, b'0', '应用新增', '', 93, 999, '', '', b'0', b'0', '', '2019-11-17 11:10:03', 'app:add', 2); +INSERT INTO `menu` VALUES (107, b'0', '应用编辑', '', 93, 999, '', '', b'0', b'0', '', '2019-11-17 11:10:28', 'app:edit', 2); +INSERT INTO `menu` VALUES (108, b'0', '应用删除', '', 93, 999, '', '', b'0', b'0', '', '2019-11-17 11:10:55', 'app:del', 2); +INSERT INTO `menu` VALUES (109, b'0', '部署新增', '', 94, 999, '', '', b'0', b'0', '', '2019-11-17 11:11:22', 'deploy:add', 2); +INSERT INTO `menu` VALUES (110, b'0', '部署编辑', '', 94, 999, '', '', b'0', b'0', '', '2019-11-17 11:11:41', 'deploy:edit', 2); +INSERT INTO `menu` VALUES (111, b'0', '部署删除', '', 94, 999, '', '', b'0', b'0', '', '2019-11-17 11:12:01', 'deploy:del', 2); +INSERT INTO `menu` VALUES (112, b'0', '数据库新增', '', 98, 999, '', '', b'0', b'0', '', '2019-11-17 11:12:43', 'database:add', 2); +INSERT INTO `menu` VALUES (113, b'0', '数据库编辑', '', 98, 999, '', '', b'0', b'0', '', '2019-11-17 11:12:58', 'database:edit', 2); +INSERT INTO `menu` VALUES (114, b'0', '数据库删除', '', 98, 999, '', '', b'0', b'0', '', '2019-11-17 11:13:14', 'database:del', 2); + +-- ---------------------------- +-- Table structure for mnt_app +-- ---------------------------- +DROP TABLE IF EXISTS `mnt_app`; +CREATE TABLE `mnt_app` ( + `id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '应用编号', + `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '应用名称', + `upload_path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '上传目录', + `deploy_path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '部署路径', + `backup_path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备份路径', + `port` int(255) NULL DEFAULT NULL COMMENT '应用端口', + `start_script` varchar(4000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '启动脚本', + `deploy_script` varchar(4000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '部署脚本', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of mnt_app +-- ---------------------------- +INSERT INTO `mnt_app` VALUES ('04a27b0a-6570-4fac-88be-abad072028ac', 'eladmin-monitor-2.2.jar', '/opt/upload', '/opt/monitor', '/opt/backup', 8777, 'cd /opt/monitor/\nnohup java -jar eladmin-monitor-2.2.jar >nohup.out 2>&1 &\n', 'mv /opt/upload/eladmin-monitor-2.2.jar /opt/monitor/\ncd /opt/monitor\nnohup java -jar eladmin-monitor-2.2.jar >nohup.out 2>&1 &\n'); + +-- ---------------------------- +-- Table structure for mnt_database +-- ---------------------------- +DROP TABLE IF EXISTS `mnt_database`; +CREATE TABLE `mnt_database` ( + `id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '编号', + `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '名称', + `jdbc_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'jdbc连接', + `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '账号', + `pwd` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for mnt_deploy +-- ---------------------------- +DROP TABLE IF EXISTS `mnt_deploy`; +CREATE TABLE `mnt_deploy` ( + `id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '编号', + `app_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '应用编号', + `ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'IP地址', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for mnt_deploy_history +-- ---------------------------- +DROP TABLE IF EXISTS `mnt_deploy_history`; +CREATE TABLE `mnt_deploy_history` ( + `id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '编号', + `app_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '应用名称', + `deploy_date` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '部署日期', + `deploy_user` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '部署用户', + `ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '服务器IP', + `deploy_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '部署编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + + +-- ---------------------------- +-- Table structure for mnt_server +-- ---------------------------- +DROP TABLE IF EXISTS `mnt_server`; +CREATE TABLE `mnt_server` ( + `id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'IP地址', + `account_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '账号编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + + +-- ---------------------------- +-- Table structure for mnt_server_account +-- ---------------------------- +DROP TABLE IF EXISTS `mnt_server_account`; +CREATE TABLE `mnt_server_account` ( + `id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '编号', + `account` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '账户', + `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '名称', + `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + \ No newline at end of file