From a52e395ccc8097cefafa0ca1d0db8b74d85ebbf2 Mon Sep 17 00:00:00 2001
From: whb <17803890193@163.com>
Date: Thu, 1 Aug 2024 17:37:31 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Eipynb=E6=96=87=E4=BB=B6?=
=?UTF-8?q?=E5=88=A0=E9=99=A4=E7=AD=89=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 6 +
.../resource_center/config/Constant.java | 3 +
.../new_module/stu/JupyterhubController.java | 215 ++++++++++++++++++
3 files changed, 224 insertions(+)
create mode 100644 src/main/java/com/sztzjy/resource_center/controller/new_module/stu/JupyterhubController.java
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());
+ }
+ }
+
+ }
+
+
+
+
+
+}