diff --git a/pom.xml b/pom.xml index f115ca6..16ab815 100644 --- a/pom.xml +++ b/pom.xml @@ -218,6 +218,12 @@ ip2region 2.6.5 + + + org.apache.httpcomponents + httpmime + 4.5.14 + diff --git a/src/main/java/com/sztzjy/resource_center/config/Constant.java b/src/main/java/com/sztzjy/resource_center/config/Constant.java index ab81e52..693bd17 100644 --- a/src/main/java/com/sztzjy/resource_center/config/Constant.java +++ b/src/main/java/com/sztzjy/resource_center/config/Constant.java @@ -33,4 +33,7 @@ public class Constant { // public static final String THEORY = "理论考试模块"; // public static final String RESOURCE = "资源中心模块"; + public static final String JUPYTERHUB_API_URL = "http://120.78.220.29:8000/hub/api"; + public static final String ADMIN_TOKEN = "170bed30b34242cfb3fda3171e1a111d"; // 替换为你的JupyterHub管理员API令牌 + } diff --git a/src/main/java/com/sztzjy/resource_center/controller/new_module/stu/JupyterhubController.java b/src/main/java/com/sztzjy/resource_center/controller/new_module/stu/JupyterhubController.java new file mode 100644 index 0000000..bd52a30 --- /dev/null +++ b/src/main/java/com/sztzjy/resource_center/controller/new_module/stu/JupyterhubController.java @@ -0,0 +1,215 @@ +package com.sztzjy.resource_center.controller.new_module.stu; + + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.sztzjy.resource_center.annotation.AnonymousAccess; +import com.sztzjy.resource_center.config.Constant; +import com.sztzjy.resource_center.util.ResultEntity; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.ByteArrayBody; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.Optional; + +/** + * @author 17803 + * @date 2024-07-30 15:23 + */ + +@Api(tags = "jupyterhub的Api接口") +@RequestMapping("api/jupyterhub") +@RestController +public class JupyterhubController { + + + + @ApiOperation("创建容器") + @GetMapping("/jumpJupyerHub") + public ResultEntity jumpJupyerHub() throws IOException { + startServer("jupyterhub"); + System.out.println("启动服务!"); + String url = generateToken("jupyterhub"); + return new ResultEntity<>(HttpStatus.OK,"容器创建成功!",url); + } + + + public static String generateToken(String username) throws IOException { + CloseableHttpClient client = HttpClients.createDefault(); + HttpPost request = new HttpPost(Constant.JUPYTERHUB_API_URL + "/users/" + username + "/tokens"); + request.addHeader("Authorization", "Bearer " + Constant.ADMIN_TOKEN); + request.addHeader("Content-Type", "application/json"); + + String json = "{\"note\": \"" + username + "\"}"; + StringEntity entity = new StringEntity(json); + request.setEntity(entity); + + HttpResponse response = client.execute(request); + HttpEntity responseEntity = response.getEntity(); + String responseBody = EntityUtils.toString(responseEntity); + + if (response.getStatusLine().getStatusCode() == 201) { + + // 解析 JSON 响应体 + JSONObject jsonObject = JSON.parseObject(responseBody); + // 提取生成的令牌 + String token = jsonObject.getString("token"); + + + System.out.println("Token : " + token); + + String url = "http://jrdsj.sztzjy.com:8000/user/" + username + "/?token=" + token; + + return url; + } else { + System.err.println("Failed to generate token. Status code: " + response.getStatusLine().getStatusCode()); + System.err.println("Response: " + responseBody); + return null; + } + } + + // 启动用户的 Jupyter 服务器 + public static void startServer(String username) throws IOException { + + // 启动服务器后将需要的文件复制到刚创建的容器内 模拟实现文件挂载 + CloseableHttpClient client = HttpClients.createDefault(); + HttpPost request = new HttpPost(Constant.JUPYTERHUB_API_URL + "/users/" + username + "/server"); + request.addHeader("Authorization", "Bearer " + Constant.ADMIN_TOKEN); + request.addHeader("Content-Type", "application/json"); + + HttpResponse response = client.execute(request); + HttpEntity responseEntity = response.getEntity(); + String responseBody = EntityUtils.toString(responseEntity); + + if (response.getStatusLine().getStatusCode() == 200 || response.getStatusLine().getStatusCode() == 201) { + + + System.out.println("服务成功的启动: " + username); + + + client.close(); + } + } + + + + + + @ApiOperation("超管端或者教师端上传ipynb文件") + @PostMapping("/uploadFileByIpynb") + @AnonymousAccess + public ResponseEntity uploadFileByIpynb(@RequestPart @ApiParam("文件") MultipartFile file, @ApiParam("案例名") String caseName) { + String url = "https://jrdsj.sztzjy.com:598/api/jupyterhub/uploadFileByIpynb"; + + try { + uploadFile(url, file, caseName); + return new ResponseEntity<>("上传成功", HttpStatus.OK); + } catch (IOException e) { + e.printStackTrace(); + return new ResponseEntity<>("上传失败", HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + public static void uploadFile(String url, MultipartFile file, String caseName) throws IOException { + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + HttpPost uploadFile = new HttpPost(url); + + // Build the multipart entity + MultipartEntityBuilder builder = MultipartEntityBuilder.create(); + builder.addPart("file", new ByteArrayBody(file.getBytes(), file.getOriginalFilename())); // Use ByteArrayBody for MultipartFile + builder.addTextBody("caseName", caseName); + + HttpEntity entity = builder.build(); + uploadFile.setEntity(entity); + + // Execute the request + try (CloseableHttpResponse response = httpClient.execute(uploadFile)) { + HttpEntity responseEntity = response.getEntity(); + String responseString = EntityUtils.toString(responseEntity); + System.out.println("Response: " + responseString); + } + } + } + + + @ApiOperation("保存时候判断ipynb文件是否存在") + @GetMapping("/filesIfExist") + @AnonymousAccess + public ResultEntity filesIfExist(@ApiParam("参数为:案例名") String caseName) throws InterruptedException, IOException { + String url = "https://jrdsj.sztzjy.com:598/api/jupyterhub/uploadFileByIpynbExist?caseName=" + caseName; + + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + HttpGet httpGet = new HttpGet(url); + + // 执行 GET 请求 + try (CloseableHttpResponse response = httpClient.execute(httpGet)) { + HttpEntity responseEntity = response.getEntity(); + String responseString = EntityUtils.toString(responseEntity); + + // 解析 JSON 响应 + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonResponse = objectMapper.readTree(responseString); + + // 假设返回的 JSON 对象包含 "data" 字段 + JsonNode dataNode = jsonResponse.get("data"); + return new ResultEntity<>(HttpStatus.OK,dataNode != null && dataNode.asBoolean()); + } + } + + } + + + + @ApiOperation("删除ipynb文件") + @GetMapping("/delUploadFileByIpynb") + @AnonymousAccess + public ResultEntity delUploadFileByIpynb(@ApiParam("参数为:案例名") String caseName) throws InterruptedException, IOException { + String url = "https://jrdsj.sztzjy.com:598/api/jupyterhub/delUploadFileByIpynb?caseName=" + caseName; + + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + HttpGet httpGet = new HttpGet(url); + + // 执行 GET 请求 + try (CloseableHttpResponse response = httpClient.execute(httpGet)) { + HttpEntity responseEntity = response.getEntity(); + String responseString = EntityUtils.toString(responseEntity); + + // 解析 JSON 响应 + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonResponse = objectMapper.readTree(responseString); + + // 假设返回的 JSON 对象包含 "data" 字段 + JsonNode dataNode = jsonResponse.get("data"); + return new ResultEntity<>(HttpStatus.OK,dataNode != null && dataNode.asBoolean()); + } + } + + } + + + + + +}