-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from gooormmoon/feature/compile2/GRTEAM-7
feat: compile & execute ( GRTEAM-132 )
- Loading branch information
Showing
5 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# 빌드 이미지로 OpenJDK 17 & Gradle을 지정 | ||
FROM gradle:7.6.1-jdk17 AS build | ||
|
||
# 소스코드를 복사할 작업 디렉토리를 생성 | ||
WORKDIR /app | ||
|
||
# 라이브러리 설치에 필요한 파일만 복사 | ||
COPY build.gradle settings.gradle ./ | ||
|
||
# gradle dependencies를 실행하여 의존성 설치 | ||
RUN gradle dependencies --no-daemon | ||
|
||
# 호스트 머신의 소스코드를 작업 디렉토리로 복사 | ||
COPY . /app | ||
|
||
# Gradle 빌드를 실행하여 JAR 파일 생성 | ||
RUN gradle clean build --no-daemon --stacktrace --info | ||
|
||
# 런타임 이미지로 Amazon Corretto JDK 17 지정 | ||
FROM amazoncorretto:17 | ||
|
||
# 애플리케이션을 실행할 작업 디렉토리를 생성 | ||
WORKDIR /app | ||
|
||
# 추가 패키지 설치 (컴파일 도구 포함) | ||
RUN yum update -y && \ | ||
yum install -y gcc gcc-c++ make \ | ||
python3 python3-pip \ | ||
nodejs npm && \ | ||
yum clean all | ||
|
||
# 빌드 이미지에서 생성된 JAR 파일을 런타임 이미지로 복사 | ||
COPY --from=build /app/build/libs/*.jar /app/algofi.jar | ||
|
||
# 9999 포트를 외부에 노출 | ||
EXPOSE 9999 | ||
|
||
# 컨테이너 실행 시 자바 애플리케이션 실행 | ||
ENTRYPOINT ["java", "-jar", "algofi.jar"] |
4 changes: 4 additions & 0 deletions
4
algofi-compile/src/main/java/gooroommoon/algofi_compile/api/CheckoutApiController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package gooroommoon.algofi_compile.api; | ||
|
||
public class CheckoutApiController { | ||
} |
96 changes: 96 additions & 0 deletions
96
algofi-compile/src/main/java/gooroommoon/algofi_compile/api/CompileApiController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package gooroommoon.algofi_compile.api; | ||
|
||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import gooroommoon.algofi_compile.dto.CodeExecutionRequest; | ||
import org.springframework.http.HttpStatus; | ||
import java.io.BufferedReader; | ||
import java.io.IOException; | ||
import java.io.InputStreamReader; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
|
||
@RestController | ||
@RequestMapping("/api/compile") | ||
public class CompileApiController { | ||
@PostMapping | ||
public ResponseEntity<String> compile(@RequestBody CodeExecutionRequest request) { | ||
try { | ||
String result = runCode(request.getCode(), request.getLanguage()); | ||
return ResponseEntity.ok(result); | ||
} catch (Exception e) { | ||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error in code execution: " + e.getMessage()); | ||
} | ||
} | ||
|
||
private String runCode(String code, String language) throws IOException, InterruptedException { | ||
String fileName = "temp"; | ||
ProcessBuilder builder = new ProcessBuilder(); | ||
|
||
switch (language.toLowerCase()) { | ||
case "c": | ||
Path cFilePath = Paths.get("temp." + language.toLowerCase()); | ||
Files.write(cFilePath, code.getBytes()); | ||
|
||
builder.command("sh", "-c", "gcc " + cFilePath.toString() + " -o temp && ./temp"); //linux 버전 | ||
//builder.command("cmd.exe", "/c", "gcc " + cFilePath.toString() + " -o temp && temp"); //windows 버전 | ||
break; | ||
|
||
case "java": | ||
int classIndex = code.indexOf("public class "); | ||
if (classIndex != -1) { | ||
int startIndex = classIndex + "public class ".length(); | ||
int endIndex = code.indexOf(" ", startIndex); | ||
if (endIndex != -1) { | ||
fileName = code.substring(startIndex, endIndex); | ||
} | ||
} | ||
|
||
Path javaFilePath = Paths.get(fileName + "." + language.toLowerCase()); | ||
Files.write(javaFilePath, code.getBytes()); | ||
|
||
String className = javaFilePath.toString().replace(".java", ""); | ||
//builder.command("cmd.exe", "/c", "javac " + javaFilePath.toString() + " && java " + className); //windows 버전 | ||
builder.command("sh", "-c", "javac " + javaFilePath.toString() + " && java " + className); //linux 버전 | ||
break; | ||
|
||
case "javascript": | ||
Path jsFilePath = Paths.get("temp." + language.toLowerCase()); | ||
Files.write(jsFilePath, code.getBytes()); | ||
|
||
//builder.command("cmd.exe", "/c", "node " + jsFilePath.toString()); //windows 버전 | ||
builder.command("sh", "-c", "node " + jsFilePath.toString()); //linux 버전 | ||
|
||
break; | ||
case "python": | ||
Path pyFilePath = Paths.get("temp." + language.toLowerCase()); | ||
Files.write(pyFilePath, code.getBytes()); | ||
|
||
//builder.command("cmd.exe", "/c", "python " + pyFilePath.toString()); //windows 버전 | ||
builder.command("sh", "-c", "python " + pyFilePath.toString()); //linux 버전 | ||
|
||
break; | ||
default: | ||
throw new IllegalArgumentException("Unsupported language: " + language); | ||
} | ||
|
||
builder.redirectErrorStream(true); | ||
Process process = builder.start(); | ||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); | ||
String line; | ||
StringBuilder output = new StringBuilder(); | ||
while ((line = reader.readLine()) != null) { | ||
output.append(line + "\n"); | ||
} | ||
|
||
int exitCode = process.waitFor(); | ||
if (exitCode != 0) { | ||
throw new RuntimeException("Execution failed with exit code " + exitCode); | ||
} | ||
return output.toString(); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
algofi-compile/src/main/java/gooroommoon/algofi_compile/dto/CodeExecutionRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package gooroommoon.algofi_compile.dto; | ||
|
||
public class CodeExecutionRequest { | ||
private String code; // 실행할 코드 | ||
private String language; // 코드의 프로그래밍 언어 | ||
|
||
// 기본 생성자 | ||
public CodeExecutionRequest() { | ||
} | ||
|
||
// 매개변수가 있는 생성자 | ||
public CodeExecutionRequest(String code, String language) { | ||
this.code = code; | ||
this.language = language; | ||
} | ||
|
||
// code 필드의 getter | ||
public String getCode() { | ||
return code; | ||
} | ||
|
||
// code 필드의 setter | ||
public void setCode(String code) { | ||
this.code = code; | ||
} | ||
|
||
// language 필드의 getter | ||
public String getLanguage() { | ||
return language; | ||
} | ||
|
||
// language 필드의 setter | ||
public void setLanguage(String language) { | ||
this.language = language; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "CodeExecutionRequest{" + | ||
"code='" + code + '\'' + | ||
", language='" + language + '\'' + | ||
'}'; | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
algofi-compile/src/test/java/gooroommoon/algofi_compile/api/CompileApiControllerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package gooroommoon.algofi_compile.api; | ||
|
||
import gooroommoon.algofi_compile.dto.CodeExecutionRequest; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.http.ResponseEntity; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
@SpringBootTest | ||
class CompileApiControllerTest { | ||
|
||
@Autowired | ||
private CompileApiController compileApiController; | ||
|
||
@Test | ||
public void testPythonExecution() throws Exception { | ||
String pythonCode = "print('Hello, Python')"; | ||
ResponseEntity<String> response = compileApiController.compile(new CodeExecutionRequest(pythonCode, "python")); | ||
assertEquals("Hello, Python\n", response.getBody()); | ||
} | ||
|
||
@Test | ||
public void testJavaExecution() throws Exception { | ||
String javaCode = "public class Main { public static void main(String[] args) { System.out.println(\"Hello, Java\"); } }"; | ||
ResponseEntity<String> response = compileApiController.compile(new CodeExecutionRequest(javaCode, "java")); | ||
assertEquals("Hello, Java\n", response.getBody()); | ||
} | ||
|
||
@Test | ||
public void testCExecution() throws Exception { | ||
String cCode = "#include <stdio.h>\nint main() {\nprintf(\"Hello, C\\n\");\nreturn 0;\n}"; | ||
ResponseEntity<String> response = compileApiController.compile(new CodeExecutionRequest(cCode, "c")); | ||
assertEquals("Hello, C\n", response.getBody()); | ||
} | ||
|
||
@Test | ||
public void testJavascriptExecution() throws Exception { | ||
String javascriptCode = "console.log('Hello, JavaScript')"; | ||
ResponseEntity<String> response = compileApiController.compile(new CodeExecutionRequest(javascriptCode, "javascript")); | ||
assertEquals("Hello, JavaScript\n", response.getBody()); | ||
} | ||
} |