From 83de265d7ea9f399ea9d024505475f3897ad5c4e Mon Sep 17 00:00:00 2001 From: youys <1272586223@qq.com> Date: Tue, 16 Aug 2022 18:26:21 +0800 Subject: [PATCH] init --- .gitignore | 18 ++ pom.xml | 59 ++++ .../net/educoder/SjtuBridgeApplication.java | 18 ++ .../educoder/controller/CloudController.java | 16 + .../educoder/controller/HelloController.java | 19 ++ .../educoder/exception/BridgeException.java | 42 +++ .../handler/GlobalExceptionHandler.java | 50 ++++ .../model/param/CreateCloudHostParam.java | 29 ++ .../java/net/educoder/util/JCloudUtil.java | 279 ++++++++++++++++++ src/main/resources/application.yml | 4 + src/main/resources/logback.xml | 55 ++++ 11 files changed, 589 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/net/educoder/SjtuBridgeApplication.java create mode 100644 src/main/java/net/educoder/controller/CloudController.java create mode 100644 src/main/java/net/educoder/controller/HelloController.java create mode 100644 src/main/java/net/educoder/exception/BridgeException.java create mode 100644 src/main/java/net/educoder/handler/GlobalExceptionHandler.java create mode 100644 src/main/java/net/educoder/model/param/CreateCloudHostParam.java create mode 100644 src/main/java/net/educoder/util/JCloudUtil.java create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/logback.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..71761d0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +/.classpath +/.project +/.settings/ +/target/ +/.idea +*.iml +.idea +*.project +*.classpath +.metadata +.settings +**/**/target +*.factorypath +out/ +logs/ +*.DS_Store +logs/ +log/ \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..5fdd642 --- /dev/null +++ b/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + net.educoder + sjtu-bridge + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-parent + 2.7.2 + + + + + + org.springframework.boot + spring-boot-starter-web + + + + cn.hutool + hutool-all + 5.7.11 + + + + org.projectlombok + lombok + 1.18.22 + + + + com.alibaba + fastjson + 1.2.83 + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/src/main/java/net/educoder/SjtuBridgeApplication.java b/src/main/java/net/educoder/SjtuBridgeApplication.java new file mode 100644 index 0000000..1d2f5f4 --- /dev/null +++ b/src/main/java/net/educoder/SjtuBridgeApplication.java @@ -0,0 +1,18 @@ +package net.educoder; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @Author: youys + * @Date: 2022/8/16 + * @Description: + */ +@SpringBootApplication +public class SjtuBridgeApplication { + + + public static void main(String[] args) { + SpringApplication.run(SjtuBridgeApplication.class, args); + } +} diff --git a/src/main/java/net/educoder/controller/CloudController.java b/src/main/java/net/educoder/controller/CloudController.java new file mode 100644 index 0000000..1439fc4 --- /dev/null +++ b/src/main/java/net/educoder/controller/CloudController.java @@ -0,0 +1,16 @@ +package net.educoder.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Author: youys + * @Date: 2022/8/16 + * @Description: 交大云交互接口 + */ +@RestController +@RequestMapping("/jcloud") +public class CloudController { + + +} diff --git a/src/main/java/net/educoder/controller/HelloController.java b/src/main/java/net/educoder/controller/HelloController.java new file mode 100644 index 0000000..a1bfa78 --- /dev/null +++ b/src/main/java/net/educoder/controller/HelloController.java @@ -0,0 +1,19 @@ +package net.educoder.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Author: youys + * @Date: 2022/8/16 + * @Description: + */ +@RestController +public class HelloController { + + + @GetMapping("/hello") + public String hello() { + return "hello,world"; + } +} diff --git a/src/main/java/net/educoder/exception/BridgeException.java b/src/main/java/net/educoder/exception/BridgeException.java new file mode 100644 index 0000000..2271f2e --- /dev/null +++ b/src/main/java/net/educoder/exception/BridgeException.java @@ -0,0 +1,42 @@ +package net.educoder.exception; + +import com.alibaba.fastjson.JSONObject; + +/** + * @Author: youys + * @Date: 2022/8/16 + * @Description: + */ +public class BridgeException extends RuntimeException{ + + private int code; + private String msg; + + public int getCode() { + return code; + } + + public String getMsg() { + return msg; + } + + public BridgeException(int code, String msg) { + super(msg); + this.code = code; + this.msg = msg; + } + + public BridgeException(String msg) { + super(msg); + this.code = -1; + this.msg = msg; + } + + @Override + public String toString() { + JSONObject str = new JSONObject(); + str.put("code", getCode()); + str.put("msg", getMsg()); + return str.toJSONString(); + } +} diff --git a/src/main/java/net/educoder/handler/GlobalExceptionHandler.java b/src/main/java/net/educoder/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..581f228 --- /dev/null +++ b/src/main/java/net/educoder/handler/GlobalExceptionHandler.java @@ -0,0 +1,50 @@ +package net.educoder.handler; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import net.educoder.exception.BridgeException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * @Author: youys + * @Date: 2022/8/16 + * @Description: 全局异常处理 + */ + +@Slf4j +@ControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(BridgeException.class) + @ResponseBody + public ResponseEntity handleBridgeExceptions(BridgeException e) { + log.error("捕获到BridgeException", e); + + JSONObject jsonObj = new JSONObject(); + jsonObj.put("code", e.getCode()); + jsonObj.put("msg", e.getMsg()); + + return new ResponseEntity<>(jsonObj, HttpStatus.OK); + } + + @ExceptionHandler(Exception.class) + @ResponseBody + public ResponseEntity handleOtherExceptions(Exception e) { + log.error("捕获到Exception", e); + + JSONObject jsonObj = new JSONObject(); + + if (e.getMessage().contains("Maximum upload size exceeded")) { + jsonObj.put("code", -1); + jsonObj.put("msg", "未知错误!" + e.getMessage()); + } + + return new ResponseEntity<>(jsonObj, HttpStatus.OK); + } + + +} diff --git a/src/main/java/net/educoder/model/param/CreateCloudHostParam.java b/src/main/java/net/educoder/model/param/CreateCloudHostParam.java new file mode 100644 index 0000000..21cc47b --- /dev/null +++ b/src/main/java/net/educoder/model/param/CreateCloudHostParam.java @@ -0,0 +1,29 @@ +package net.educoder.model.param; + +import lombok.Data; + +/** + * @Author: youys + * @Date: 2022/8/16 + * @Description: + */ +@Data +public class CreateCloudHostParam { + + /** + * 随机生成 + */ + private String name; + /** + * 镜像id + */ + private String imageRef; + /** + * 规格id x核xG + */ + private String flavorRef; + /** + * 网络id + */ + private String networkId; +} diff --git a/src/main/java/net/educoder/util/JCloudUtil.java b/src/main/java/net/educoder/util/JCloudUtil.java new file mode 100644 index 0000000..daba88a --- /dev/null +++ b/src/main/java/net/educoder/util/JCloudUtil.java @@ -0,0 +1,279 @@ +package net.educoder.util; + +import cn.hutool.core.util.RandomUtil; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import net.educoder.exception.BridgeException; +import net.educoder.model.param.CreateCloudHostParam; +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; + +/** + * @Author: youys + * @Date: 2022/7/14 + * @Description: 交大云工具类 + */ +@Slf4j +public class JCloudUtil { + + + /** + * 获取云主机列表详情 + * + * @param token + * @return + */ + public static String getCloudListDetail(String token) { + String url = "https://home.jcloud.sjtu.edu.cn:8774/v2.1/servers/detail"; + + long start = System.currentTimeMillis(); + String result = HttpRequest.get(url).header("Content-Type", "application/json").header("X-Auth-Token", token).execute().body(); + long end = System.currentTimeMillis(); + log.info("交大云获取云主机列表详情返回结果:{},耗时:{}ms", result, (end - start)); + + return result; + } + + /** + * 获取云主机详情 + * + * @param token + * @param serverId + * @return + */ + public static JSONObject getCloudDetail(String token, String serverId) { + String url = "https://home.jcloud.sjtu.edu.cn:8774/v2.1/servers/{server_id}".replaceAll("\\{server_id}", serverId); + + long start = System.currentTimeMillis(); + String result = HttpRequest.get(url).header("Content-Type", "application/json").header("X-Auth-Token", token).execute().body(); + long end = System.currentTimeMillis(); + log.info("交大云获取云主机serverId:{}详情返回结果:{},耗时:{}ms", serverId, result, (end - start)); + + if (StringUtils.isNotBlank(result)) { + return JSONObject.parseObject(result); + } + throw new BridgeException("获取云主机详情失败"); + } + + + /** + * 创建云主机 + * + * @param createCloudHost + * @return + */ + public static String createCloudHost(String token, CreateCloudHostParam createCloudHost) { + String url = "https://home.jcloud.sjtu.edu.cn:8774/v2.1/servers"; + + // 默认 + String body = "{\n" + + " \"server\":{\n" + + " \"name\": \"" + createCloudHost.getName() + "\",\n" + + " \"adminPass\": \"Educoder123\",\n" + + " \"imageRef\": \"" + createCloudHost.getImageRef() + "\",\n" + + " \"flavorRef\": \"" + createCloudHost.getFlavorRef() + "\",\n" + + " \"networks\":[\n" + + " {\n" + + " \"uuid\": \"" + createCloudHost.getNetworkId() + "\"\n" + + " }\n" + + " ],\n" + + " \"security_groups\": [\n" + + " {\n" + + " \"name\": \"default\"\n" + + " }\n" + + " ]" + + " }\n" + + "}"; + long start = System.currentTimeMillis(); + String result = HttpRequest.post(url).header("Content-Type", "application/json").header("X-Auth-Token", token).body(body).execute().body(); + long end = System.currentTimeMillis(); + log.info("交大云创建云主机返回结果:{},耗时:{}ms", result, (end - start)); + + return result; + } + + /** + * 更改密码 + * + * @param token + * @param serverId + * @param password + * @return + */ + public static boolean changePassword(String token, String serverId, String password) { + String url = "https://home.jcloud.sjtu.edu.cn:8774/v2.1/servers/{server_id}/action".replaceAll("\\{server_id}", serverId); + /** + * { + * "changePassword" : { + * "adminPass" : "foo" + * } + * } + */ + JSONObject changePassword = new JSONObject(); + changePassword.put("adminPass", password); + + JSONObject requestBody = new JSONObject(); + requestBody.put("changePassword", changePassword); + + long start = System.currentTimeMillis(); + String result = HttpRequest.post(url).header("Content-Type", "application/json").header("X-Auth-Token", token).body(requestBody.toJSONString()).execute().body(); + long end = System.currentTimeMillis(); + log.info("交大云更改云主机密码返回结果:{},耗时:{}ms", result, (end - start)); + return StringUtils.isNotBlank(result); + } + + /** + * 重置云主机 + * + * @param token + * @param serverId + * @return + */ + public static boolean rebuildCloud(String token, String serverId) { + String url = "https://home.jcloud.sjtu.edu.cn:8774/v2.1/servers/{server_id}/action".replaceAll("\\{server_id}", serverId); + /** + * { + * "rebuild" : { + * "imageRef" : "70a599e0-31e7-49b7-b260-868f441e862b", + * "adminPass" : "seekr3t" + * } + * } + */ + JSONObject rebuild = new JSONObject(); + rebuild.put("imageRef", "31a54313-bcfe-4c6e-9e19-dcad8360ef56"); + rebuild.put("adminPass", "Educoder123"); + + JSONObject requestBody = new JSONObject(); + requestBody.put("rebuild", rebuild); + + long start = System.currentTimeMillis(); + String result = HttpRequest.post(url).header("Content-Type", "application/json").header("X-Auth-Token", token).body(requestBody.toJSONString()).execute().body(); + long end = System.currentTimeMillis(); + log.info("交大云重新构建云主机密码返回结果:{},耗时:{}ms", result, (end - start)); + return true; + } + + /** + * 删除云主机 + * + * @param serverId + * @param token + * @return + */ + public static boolean deleteCloudHost(String serverId, String token) { + String url = "https://home.jcloud.sjtu.edu.cn:8774/v2.1/servers/{server_id}".replaceAll("\\{server_id}", serverId); + + long start = System.currentTimeMillis(); + String result = HttpRequest.delete(url).header("Content-Type", "application/json").header("X-Auth-Token", token).execute().body(); + long end = System.currentTimeMillis(); + log.info("交大云删除云主机返回结果:{},耗时:{}ms", result, (end - start)); + + return StringUtils.isBlank(result); + } + + + /** + * 获取api token + * + * @return token + */ + public static String getApiToken(String username, String password) { + /** + * { + * "auth": { + * "identity": { + * "methods": [ + * "password" + * ], + * "password": { + * "user": { + * "name": "admin", + * "domain": { + * "name": "Default" + * }, + * "password": "devstacker" + * } + * } + * } + * } + * } + */ + JSONObject domain = new JSONObject(); + domain.put("name", "Default"); + + JSONObject user = new JSONObject(); + user.put("name", username); + user.put("password", password); + user.put("domain", domain); + + JSONObject passwordJson = new JSONObject(); + passwordJson.put("user", user); + + JSONObject identity = new JSONObject(); + identity.put("methods", Arrays.asList("password")); + identity.put("password", passwordJson); + + JSONObject auth = new JSONObject(); + auth.put("identity", identity); + + JSONObject requestBody = new JSONObject(); + requestBody.put("auth", auth); + + HttpResponse response = HttpRequest.post("https://home.jcloud.sjtu.edu.cn:5000/v3/auth/tokens").header("Content-Type", "application/json").body(requestBody.toJSONString()).execute(); + if (response.isOk()) { + String token = response.header("X-Subject-Token"); + log.info("交我算平台获取token成功,token: {}", token); + return token; + } + log.info("交我算平台获取token失败,body:{}", response.body()); + return ""; + } + + public static void main(String[] args) { + String username = "educoder01"; + String password = "Educoder123"; + String apiToken = getApiToken(username, password); + + +// createCloudHost(apiToken, defaultCreateCloudHostParam()); + + + String serverId = "7c91c97b-37a4-4cf2-85be-fdddaef44f2b"; + + /** + * 重置云主机,并且需要修改密码 + */ +// rebuildCloud(apiToken, serverId); +// changePassword(apiToken, serverId, "Educoder123"); + +// getCloudDetail(apiToken, serverId); + + +// deleteCloudHost("902d0100-745c-4ef5-af44-edca4b1410d9",apiToken); + + + } + + + /** + * 默认创建云主机参数 + * 镜像:centos7.9 + * 规格:4核8G + * 内网网络:提前创建好 + * + * @return + */ + public static CreateCloudHostParam defaultCreateCloudHostParam() { + CreateCloudHostParam createCloudHost = new CreateCloudHostParam(); + createCloudHost.setName(RandomUtil.randomString(10)); + createCloudHost.setImageRef("31a54313-bcfe-4c6e-9e19-dcad8360ef56"); + createCloudHost.setFlavorRef("02723f5f-5518-4031-bd5e-dfecae675606"); + createCloudHost.setNetworkId("f41ece4b-ff14-4444-8d1d-c730779a0df2"); + return createCloudHost; + } + + +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..b167e67 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,4 @@ +server: + port: 8181 + servlet: + context-path: /sjtu-bridge diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..38ee493 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,55 @@ + + + + + + + + + + ${logPattern} + + + + + + + ${logPattern} + + + ${logPath}/info_%d{yyyy-MM-dd}_%i.log + 30 + + 10MB + + + + + + + + ERROR + + + ${logPattern} + + + ${logPath}/error_%d{yyyy-MM-dd}_%i.log + 30 + + 10MB + + + + + + + + + + + + + + + \ No newline at end of file