package de.hftstuttgart.rest.v1.unittest; import de.hftstuttgart.utils.JGitUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.core.env.Environment; import org.springframework.util.FileSystemUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.servlet.annotation.MultipartConfig; import java.io.*; import java.nio.file.Path; import java.nio.file.Paths; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Rest controller for anything related to the TEST files. */ @RestController @RequestMapping("/v1/unittest") @MultipartConfig public class UnitTestUpload { private static final Logger LOG = LogManager.getLogger(UnitTestUpload.class); public final static String modocotTestConfigRegex = "^modocot::(.*)::(.*|none)::(.*|none)::(.*)$"; public final static String modocotDueConfigRegex = "^modocot::(.*)::(.*|none)::(.*|none)$"; private final JGitUtil jGitUtil; private final String assignmentBasePath; public UnitTestUpload(Environment env, JGitUtil jGitUtil) { this.jGitUtil = jGitUtil; Path p = Paths.get(env.getProperty("modocot.dir"), env.getProperty("modocot.dir.test.folder.name")); this.assignmentBasePath = p.toAbsolutePath().toString(); } /** * Create a subfolder for the specific assignment. * This is called when the teacher creates an assignment and uploads the JUnit test files * * @param unitTestFileRef The text file which contains the JUnit tests meta data * @param assignmentId ID of the created assignment. Generated by Moodle */ @RequestMapping(method = RequestMethod.POST) public void uploadUnitTestFile( @RequestParam("unitTestFile") MultipartFile unitTestFileRef, @RequestParam("assignmentId") String assignmentId ) throws IOException { LOG.info("received new assignment"); File file = Paths.get( this.assignmentBasePath, assignmentId + ".txt") .toFile(); file.mkdirs(); // save assignment config unitTestFileRef.transferTo(file); LOG.debug(String.format("saved config file to: %s", file.getAbsolutePath())); Pattern pattern = Pattern.compile(this.modocotTestConfigRegex); Matcher config = null; LOG.debug("reading test configuration file"); // open saved config in a try-with try (BufferedReader br = new BufferedReader( new InputStreamReader( new FileInputStream(file)))) { String line; // search for a modocot URI while none is found and there are lines left while (config == null && (line = br.readLine()) != null) { Matcher matcher = pattern.matcher(line); if (matcher.matches()) { LOG.debug(String.format("found modocot test line: %s", line)); config = matcher; } } } catch (IOException e) { LOG.error("Error while reading repo config", e); } finally { if (config == null) { throw new RuntimeException("couldn't find repo config for unittest clone"); } } LOG.debug("calling test repo clone"); // cloning assignment repo to persistent space jGitUtil.cloneRepository( config, Paths.get(this.assignmentBasePath, assignmentId).toAbsolutePath().toString()); LOG.info(String.format("stored new assignment: %s", file.getAbsolutePath())); } /** * Delete the folder for the assignment. * Called when the teacher deletes the JUnitTest assignment *

* {{url}}:8080/v1/unittest?assignmentId=111 * * @param assignmentId ID of the assignment to delete. Generated by Moodle */ @RequestMapping(method = RequestMethod.DELETE) public void deleteUnitTestFiles(@RequestParam("assignmentId") String assignmentId) { LOG.info(String.format("received deletion order for assignment %s", assignmentId)); // deleting config file File file = Paths.get( this.assignmentBasePath, assignmentId + ".txt") .toFile(); file.delete(); // deleting local copy of repository file = Paths.get( this.assignmentBasePath, assignmentId).toFile(); FileSystemUtils.deleteRecursively(file); LOG.info(String.format("assignment %s deletion complete", assignmentId)); } }