diff --git a/.gitignore b/.gitignore
index 231eace6bba04501e2dbe859ad3cac3ce1bcdbf6..ac5cec03f49d231c3858414751c3aafc01cef7b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,10 @@
target/
!.mvn/wrapper/maven-wrapper.jar
+# ignore local development files
+docker-compose.yml
+/*.properties
+
### STS ###
.classpath
.factorypath
diff --git a/.versionrc b/.versionrc
new file mode 100644
index 0000000000000000000000000000000000000000..9a4ab851845efd5d5410a969950a79133dc63195
--- /dev/null
+++ b/.versionrc
@@ -0,0 +1,7 @@
+{
+ "tagPrefix": "",
+ "commitUrlFormat": "https://transfer.hft-stuttgart.de/gitlab/HFTSoftwareProject/MoDoCoT-Backend/-/commit/{{hash}}",
+ "compareUrlFormat": "https://transfer.hft-stuttgart.de/gitlab/HFTSoftwareProject/MoDoCoT-Backend/-/compare/{{previousTag}}...{{currentTag}}",
+ "issueUrlFormat": "https://transfer.hft-stuttgart.de/gitlab/HFTSoftwareProject/MoDoCoT-Backend/-/issues/{{id}}"
+}
+
diff --git a/Dockerfile b/Dockerfile
index 4d9f575be5a2759ea13783dbc080b9b9e244b572..91f97b8d4d2308e17779c802b8b5739a18de5c15 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,27 +1,18 @@
#Dockerfile
#base image
-FROM alpine
+FROM openjdk:11-jre-slim
-#Proxy
-ENV http_proxy 'http://proxy.hft-stuttgart.de:80'
-ENV https_proxy 'http://proxy.hft-stuttgart.de:80'
-
-
-#jdk11
-RUN apk add openjdk11 git
-
-VOLUME /tmp
-ADD target/modocot-backend-1.0.2-SNAPSHOT.jar app.jar
-RUN sh -c 'touch /app.jar'
+ADD target/modocot-backend.jar app.jar
# Prepare environment.
# Create needed folders
-RUN mkdir /home/modocot && \
- mkdir /home/modocot/libs
+RUN mkdir /modocot && \
+ mkdir /modocot/data && \
+ mkdir /modocot/config
+
+VOLUME /modocot/data
-# Download needed libs for compilation
-ADD https://repo1.maven.org/maven2/junit/junit/4.13/junit-4.13.jar /home/modocot/libs/junit.jar
-ADD https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/2.2/hamcrest-core-2.2.jar /home/modocot/libs/hamcrest.jar
+env SPRING_CONFIG_ADDITIONAL_LOCATION "file:/home/modocot/config/"
-ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=server","-jar","/app.jar"]
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
diff --git a/Jenkinsfile b/Jenkinsfile
index 76219504679a0e83c7cede3af3965f5d442c4630..43d4e95746d198e268f0fd8a1cf572465c440d89 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,49 +1,73 @@
+
+def version = ""
+
pipeline {
+
environment {
registry = "hftstuttgart/modocot-backend"
registryCredential = 'Dockerhub'
dockerImage = ''
}
+
agent any
+
tools {
jdk 'Java11'
maven 'Maven_Home'
}
+
stages {
- stage('Checkout') {
+ stage('prepare') {
steps {
- echo 'Checkout Repository..'
- git branch: 'master',
- url: 'https://transfer.hft-stuttgart.de/gitlab/HFTSoftwareProject/MoDoCoT-Backend.git'
+ checkout ([
+ $class: 'GitSCM',
+ branches: scm.branches,
+ extensions: scm.extensions + [[$class: 'CloneOption', noTags: false, reference: '', shallow: false]],
+ userRemoteConfigs: scm.userRemoteConfigs
+ ])
+ script {
+ version = sh(script: 'git describe --tags --always', returnStdout: true).trim()
+ echo sh(script: 'env|sort', returnStdout: true)
+ }
+
}
}
- stage('Build') {
+
+ stage('compile') {
steps {
- echo 'Maven Build..'
- sh 'mvn clean package -DskipTests=false'
+ sh 'mvn clean package'
}
}
- stage('Docker Build..') {
- steps{
+
+ stage('build Docker image') {
+ steps {
script {
- dockerImage = docker.build registry + ":latest"
+ dockerImage = docker.build registry
}
}
}
- stage('Push to Dockerhub..') {
- steps{
- script {
- docker.withRegistry( '', registryCredential ) {
- dockerImage.push()
- }
- }
+
+ stage('push development image') {
+ steps {
+ script {
+ docker.withRegistry( '', registryCredential ) {
+ dockerImage.push("${env.GIT_BRANCH}")
}
}
+ }
+ }
- stage('ShellScript') {
+ stage('release') {
+ when {
+ expression { version ==~ /[0-9]+.[0-9]+.[0-9]+/ }
+ }
steps {
- echo 'Exectue Shellscript..'
- sh 'chmod 744 restart_modocot_backend.sh && ./restart_modocot_backend.sh'
+ script {
+ docker.withRegistry( '', registryCredential ) {
+ dockerImage.push("latest")
+ dockerImage.push("${version}")
+ }
+ }
}
}
}
diff --git a/development-templates/custom.yml b/development-templates/custom.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6da28d90f0ea07fbef4400ac005f5d3eda505ead
--- /dev/null
+++ b/development-templates/custom.yml
@@ -0,0 +1,14 @@
+version: '3'
+
+services:
+ backend:
+ build:
+ context: .
+ environment:
+ - DOCKER_HOST=unix:///var/run/docker.sock
+ container_name: modocot-devel-backend
+ ports:
+ - 127.0.0.1:8080:8080
+ volumes:
+ - '/var/run/docker.sock:/var/run/docker.sock'
+ - '/tmp/modocot-tests:/tmp/modocot-tests'
diff --git a/mvnw b/mvnw
deleted file mode 100644
index a1ba1bf554bb63c401f90c6a472c21470ed4e164..0000000000000000000000000000000000000000
--- a/mvnw
+++ /dev/null
@@ -1,233 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Maven2 Start Up Batch script
-#
-# Required ENV vars:
-# ------------------
-# JAVA_HOME - location of a JDK home dir
-#
-# Optional ENV vars
-# -----------------
-# M2_HOME - location of maven2's installed home dir
-# MAVEN_OPTS - parameters passed to the Java VM when running Maven
-# e.g. to debug Maven itself, use
-# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-# ----------------------------------------------------------------------------
-
-if [ -z "$MAVEN_SKIP_RC" ] ; then
-
- if [ -f /etc/mavenrc ] ; then
- . /etc/mavenrc
- fi
-
- if [ -f "$HOME/.mavenrc" ] ; then
- . "$HOME/.mavenrc"
- fi
-
-fi
-
-# OS specific support. $var _must_ be set to either true or false.
-cygwin=false;
-darwin=false;
-mingw=false
-case "`uname`" in
- CYGWIN*) cygwin=true ;;
- MINGW*) mingw=true;;
- Darwin*) darwin=true
- #
- # Look for the Apple JDKs first to preserve the existing behaviour, and then look
- # for the new JDKs provided by Oracle.
- #
- if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
- #
- # Apple JDKs
- #
- export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
- fi
-
- if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
- #
- # Apple JDKs
- #
- export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
- fi
-
- if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
- #
- # Oracle JDKs
- #
- export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
- fi
-
- if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
- #
- # Apple JDKs
- #
- export JAVA_HOME=`/usr/libexec/java_home`
- fi
- ;;
-esac
-
-if [ -z "$JAVA_HOME" ] ; then
- if [ -r /etc/gentoo-release ] ; then
- JAVA_HOME=`java-config --jre-home`
- fi
-fi
-
-if [ -z "$M2_HOME" ] ; then
- ## resolve links - $0 may be a link to maven's home
- PRG="$0"
-
- # need this for relative symlinks
- while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG="`dirname "$PRG"`/$link"
- fi
- done
-
- saveddir=`pwd`
-
- M2_HOME=`dirname "$PRG"`/..
-
- # make it fully qualified
- M2_HOME=`cd "$M2_HOME" && pwd`
-
- cd "$saveddir"
- # echo Using m2 at $M2_HOME
-fi
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched
-if $cygwin ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --unix "$M2_HOME"`
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
-fi
-
-# For Migwn, ensure paths are in UNIX format before anything is touched
-if $mingw ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME="`(cd "$M2_HOME"; pwd)`"
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
- # TODO classpath?
-fi
-
-if [ -z "$JAVA_HOME" ]; then
- javaExecutable="`which javac`"
- if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
- # readlink(1) is not available as standard on Solaris 10.
- readLink=`which readlink`
- if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
- if $darwin ; then
- javaHome="`dirname \"$javaExecutable\"`"
- javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
- else
- javaExecutable="`readlink -f \"$javaExecutable\"`"
- fi
- javaHome="`dirname \"$javaExecutable\"`"
- javaHome=`expr "$javaHome" : '\(.*\)/bin'`
- JAVA_HOME="$javaHome"
- export JAVA_HOME
- fi
- fi
-fi
-
-if [ -z "$JAVACMD" ] ; then
- if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- else
- JAVACMD="`which java`"
- fi
-fi
-
-if [ ! -x "$JAVACMD" ] ; then
- echo "Error: JAVA_HOME is not defined correctly." >&2
- echo " We cannot execute $JAVACMD" >&2
- exit 1
-fi
-
-if [ -z "$JAVA_HOME" ] ; then
- echo "Warning: JAVA_HOME environment variable is not set."
-fi
-
-CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --path --windows "$M2_HOME"`
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
-fi
-
-# traverses directory structure from process work directory to filesystem root
-# first directory with .mvn subdirectory is considered project base directory
-find_maven_basedir() {
- local basedir=$(pwd)
- local wdir=$(pwd)
- while [ "$wdir" != '/' ] ; do
- if [ -d "$wdir"/.mvn ] ; then
- basedir=$wdir
- break
- fi
- wdir=$(cd "$wdir/.."; pwd)
- done
- echo "${basedir}"
-}
-
-# concatenates all lines of a file
-concat_lines() {
- if [ -f "$1" ]; then
- echo "$(tr -s '\n' ' ' < "$1")"
- fi
-}
-
-export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
-MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
-
-# Provide a "standardized" way to retrieve the CLI args that will
-# work with both Windows and non-Windows executions.
-MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
-export MAVEN_CMD_LINE_ARGS
-
-WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-exec "$JAVACMD" \
- $MAVEN_OPTS \
- -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
- ${WRAPPER_LAUNCHER} "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
deleted file mode 100644
index 2b934e89dd1d9872b747047fa696477264a86ad8..0000000000000000000000000000000000000000
--- a/mvnw.cmd
+++ /dev/null
@@ -1,145 +0,0 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM http://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Maven2 Start Up Batch script
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@REM
-@REM Optional ENV vars
-@REM M2_HOME - location of maven2's installed home dir
-@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
-@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
-@REM e.g. to debug Maven itself, use
-@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-@REM ----------------------------------------------------------------------------
-
-@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
-@echo off
-@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
-@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
-
-@REM set %HOME% to equivalent of $HOME
-if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
-
-@REM Execute a user defined script before this one
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
-@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
-if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
-:skipRcPre
-
-@setlocal
-
-set ERROR_CODE=0
-
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
-@REM ==== START VALIDATION ====
-if not "%JAVA_HOME%" == "" goto OkJHome
-
-echo.
-echo Error: JAVA_HOME not found in your environment. >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-:OkJHome
-if exist "%JAVA_HOME%\bin\java.exe" goto init
-
-echo.
-echo Error: JAVA_HOME is set to an invalid directory. >&2
-echo JAVA_HOME = "%JAVA_HOME%" >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-@REM ==== END VALIDATION ====
-
-:init
-
-set MAVEN_CMD_LINE_ARGS=%*
-
-@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
-@REM Fallback to current working directory if not found.
-
-set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
-IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
-
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
-:findBaseDir
-IF EXIST "%WDIR%"\.mvn goto baseDirFound
-cd ..
-IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
-goto findBaseDir
-
-:baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
-cd "%EXEC_DIR%"
-goto endDetectBaseDir
-
-:baseDirNotFound
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
-cd "%EXEC_DIR%"
-
-:endDetectBaseDir
-
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
-
-@setlocal EnableExtensions EnableDelayedExpansion
-for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
-@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
-
-:endReadAdditionalConfig
-
-SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
-
-set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
-if ERRORLEVEL 1 goto error
-goto end
-
-:error
-set ERROR_CODE=1
-
-:end
-@endlocal & set ERROR_CODE=%ERROR_CODE%
-
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
-@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
-if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
-:skipRcPost
-
-@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%" == "on" pause
-
-if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
-
-exit /B %ERROR_CODE%
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 61c952f736f1ecc364477da363aea1dcdb42ed3c..347604f69e91df65f64f45fe00664973a297cfec 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
de.hftstuttgart
modocot-backend
- 1.0.2-SNAPSHOT
+ 2.0.0
jar
Modocot-Backend
@@ -20,34 +20,18 @@
UTF-8
UTF-8
11
-
-
- hftstuttgart
-
- true
- com.github.zeripath
- java-gitea-api
- 1.7.4
-
-
- com.fasterxml.jackson.dataformat
- jackson-dataformat-xml
- 2.9.8
-
-
-
- org.json
- json
- 20180130
+ com.github.docker-java
+ docker-java-core
+ 3.2.6
- org.freemarker
- freemarker
- 2.3.30
+ com.github.docker-java
+ docker-java-transport-httpclient5
+ 3.2.6
org.springframework.boot
@@ -58,33 +42,17 @@
spring-boot-starter-test
test
+
- junit
- junit
- 4.13
+ org.eclipse.jgit
+ org.eclipse.jgit
+ 5.7.0.202003110725-r
log4j
log4j
1.2.17
-
- com.google.code.gson
- gson
- 2.8.6
-
-
-
- com.google.guava
- guava
- 29.0-jre
-
-
-
- org.eclipse.jgit
- org.eclipse.jgit
- 5.7.0.202003110725-r
-
org.apache.logging.log4j
log4j-api
@@ -98,19 +66,12 @@
+ ${project.artifactId}
org.springframework.boot
spring-boot-maven-plugin
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 3.0.0-M3
-
- ${skipTests}
-
-
-
\ No newline at end of file
+
diff --git a/restart_modocot_backend.sh b/restart_modocot_backend.sh
deleted file mode 100644
index 162d6a72a5bbd5e109381a1f54cd8164996bafb9..0000000000000000000000000000000000000000
--- a/restart_modocot_backend.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-# Stop the running backend
-docker stop modocot-backend
-
-# Delete the existing container
-docker rm modocot-backend
-
-# Pull the new version from DockerHub
-docker pull hftstuttgart/modocot-backend
-
-# Build the container and start it
-docker run --name modocot-backend -p 8888:8081 hftstuttgart/modocot-backend:latest &
diff --git a/src/log4j2.xml b/src/log4j2.xml
deleted file mode 100644
index 1b0e59d095a41159edc4b57a9f21c034b306a1a5..0000000000000000000000000000000000000000
--- a/src/log4j2.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/java/de/hftstuttgart/ModocotBackendApplication.java b/src/main/java/de/hftstuttgart/ModocotBackendApplication.java
index b20a5c0de6aa7f45e0029d211d5a008f19bd38c8..fcbbfd966ae9010dec60818575161c7ecaa29585 100644
--- a/src/main/java/de/hftstuttgart/ModocotBackendApplication.java
+++ b/src/main/java/de/hftstuttgart/ModocotBackendApplication.java
@@ -1,86 +1,13 @@
package de.hftstuttgart;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import org.junit.ComparisonFailure;
-import org.junit.runner.notification.Failure;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Primary;
-import org.springframework.context.annotation.PropertySource;
-import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
-
-import javax.tools.Diagnostic;
-import javax.tools.JavaFileObject;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.util.Locale;
@SpringBootApplication
-@PropertySource("classpath:git-credentials.properties")
public class ModocotBackendApplication {
public static void main(String[] args) {
SpringApplication.run(ModocotBackendApplication.class, args);
}
- /**
- * Configuration for the Jackson JSON serializer
- */
- @Bean
- @Primary
- public Jackson2ObjectMapperBuilder jacksonConfiguration() {
- Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
- builder.indentOutput(true)
- .serializationInclusion(JsonInclude.Include.NON_NULL) // Don’t include null values in the JSON
- .serializerByType(Diagnostic.class, new DiagnosticSerializer())
- .serializerByType(Failure.class, new FailureSerializer());
- return builder;
- }
-
- /**
- * Custom serializer for the {@link Diagnostic} class used by Jackson
- */
- private class DiagnosticSerializer extends JsonSerializer {
- @Override
- public void serialize(Diagnostic diagnostic, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
- gen.writeStartObject();
- gen.writeStringField("code", diagnostic.getCode());
- gen.writeNumberField("columnNumber", diagnostic.getColumnNumber());
- gen.writeStringField("kind", diagnostic.getKind().toString());
- gen.writeNumberField("lineNumber", diagnostic.getLineNumber());
- gen.writeStringField("message", diagnostic.getMessage(Locale.ENGLISH));
- gen.writeNumberField("position", diagnostic.getPosition());
-
- URI uri = ((JavaFileObject) diagnostic.getSource()).toUri();
- gen.writeStringField("javaFileName", new File(uri).getName());
- gen.writeNumberField("startPosition", diagnostic.getStartPosition());
- gen.writeNumberField("endPosition", diagnostic.getEndPosition());
- gen.writeEndObject();
- }
- }
-
- /**
- * Custom serializer for the {@link Failure} class used by Jackson
- */
- private class FailureSerializer extends JsonSerializer {
- @Override
- public void serialize(Failure failure, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
- gen.writeStartObject();
- gen.writeStringField("testHeader", failure.getTestHeader());
- gen.writeStringField("message", failure.getMessage());
- gen.writeStringField("trace", failure.getTrace());
-
- Throwable exception = failure.getException();
- if (exception instanceof ComparisonFailure) {
- gen.writeStringField("expected", ((ComparisonFailure) exception).getExpected());
- gen.writeStringField("actual", ((ComparisonFailure) exception).getActual());
- }
- gen.writeEndObject();
- }
- }
}
diff --git a/src/main/java/de/hftstuttgart/config/ModocotProperties.java b/src/main/java/de/hftstuttgart/config/ModocotProperties.java
deleted file mode 100644
index 5ab5f6dd7f60da2586fceb7ab5eb77c8b0613787..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/config/ModocotProperties.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package de.hftstuttgart.config;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class ModocotProperties {
-
- private final String dockerHostIp;
- private final String jenkinsApiToken;
- private final String jenkinsBaseUrl;
- private final String modocotParentDirectory;
- private final String modocotAssignmentFolderPrefix;
- private final String modocotTestFolderName;
- private final String gitTeaBasePath;
- private final String gitTeaUsername;
- private final String gitTeaPassword;
- private final String gitTeaDefaultCommitMessage;
- private final String gitTeaOrigin;
-
- public ModocotProperties(@Value("${docker.hostIp}") String dockerHostIp,
- @Value("${jenkins.api.token}") String jenkinsApiToken,
- @Value("${jenkins.url}") String jenkinsBaseUrl,
- @Value("${modocot.dir.parent}") String modocotParentDirectory,
- @Value("${modocot.dir.assignment.prefix}") String modocotAssignmentFolderPrefix,
- @Value("${modocot.dir.test.folder.name}") String modocotTestFolderName,
- @Value("${gitTea.basePath}") String gitTeaBasePath,
- @Value("${gitTea.username}") String gitTeaUsername,
- @Value("${gitTea.password}") String gitTeaPassword,
- @Value("${gitTea.defaultCommitMessage}") String gitTeaDefaultCommitMessage,
- @Value("${gitTea.defaultOrigin}") String gitTeaOrigin) {
- this.dockerHostIp = dockerHostIp;
- this.jenkinsApiToken = jenkinsApiToken;
- this.jenkinsBaseUrl = jenkinsBaseUrl;
- this.modocotParentDirectory = modocotParentDirectory;
- this.modocotAssignmentFolderPrefix = modocotAssignmentFolderPrefix;
- this.modocotTestFolderName = modocotTestFolderName;
- this.gitTeaBasePath = gitTeaBasePath;
- this.gitTeaUsername = gitTeaUsername;
- this.gitTeaPassword = gitTeaPassword;
- this.gitTeaDefaultCommitMessage = gitTeaDefaultCommitMessage;
- this.gitTeaOrigin = gitTeaOrigin;
- }
-
- public String getDockerHostIp() {
- return dockerHostIp;
- }
-
- public String getJenkinsApiToken() {
- return jenkinsApiToken;
- }
-
- public String getJenkinsBaseUrl() {
- return jenkinsBaseUrl;
- }
-
- public String getModocotParentDirectory() {
- return modocotParentDirectory;
- }
-
- public String getModocotAssignmentFolderPrefix() {
- return modocotAssignmentFolderPrefix;
- }
-
- public String getModocotTestFolderName() {
- return modocotTestFolderName;
- }
-
- public String getGitTeaBasePath() {
- return gitTeaBasePath;
- }
-
- public String getGitTeaUsername() {
- return gitTeaUsername;
- }
-
- public String getGitTeaPassword() {
- return gitTeaPassword;
- }
-
- public String getGitTeaDefaultCommitMessage() {
- return gitTeaDefaultCommitMessage;
- }
-
- public String getGitTeaOrigin() {
- return gitTeaOrigin;
- }
-}
diff --git a/src/main/java/de/hftstuttgart/config/ProxySetup.java b/src/main/java/de/hftstuttgart/config/ProxySetup.java
new file mode 100644
index 0000000000000000000000000000000000000000..3cd0b81fea749c257a1eb3a0fec31aa33e00ce2d
--- /dev/null
+++ b/src/main/java/de/hftstuttgart/config/ProxySetup.java
@@ -0,0 +1,81 @@
+package de.hftstuttgart.config;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+
+import java.io.IOException;
+import java.net.*;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Configuration
+/**
+ * Configures Proxy once on startup
+ */
+public class ProxySetup extends ProxySelector
+{
+ private static final Logger LOG = LogManager.getLogger(ProxySetup.class);
+
+ List noProxy;
+ List setProxy;
+ Set noProxyHosts;
+
+ public ProxySetup(Environment env) {
+
+ String ignoredHostNames = env.getProperty("proxy.ignoredHostNames");
+ if (Objects.isNull(ignoredHostNames)) {
+ ignoredHostNames = "";
+ }
+
+ String proxy = env.getProperty("proxy");
+
+ LOG.info("Configuring Proxy");
+ noProxy = Collections.singletonList(Proxy.NO_PROXY);
+
+ if (Objects.nonNull(proxy)) {
+ String[] proxyValues = proxy.split(":");
+ Proxy p = new Proxy(
+ Proxy.Type.HTTP,
+ new InetSocketAddress(proxyValues[0], Integer.parseInt(proxyValues[1])));
+ setProxy = Collections.singletonList(p);
+
+ LOG.info(String.format("set proxy: %s", p.address().toString()));
+ }
+
+ noProxyHosts = Arrays.stream(ignoredHostNames.split(","))
+ .map(String::toLowerCase)
+ .collect(Collectors.toCollection(HashSet::new));
+
+ LOG.info(String.format("Hosts to be ignored: %s", noProxyHosts));
+
+ ProxySelector.setDefault(this);
+ }
+
+ @Override
+ public List select(URI uri) {
+
+ LOG.debug(String.format("Proxy selection for URI: %s", uri.getHost()));
+
+ // No proxy for given hosts
+ if (noProxyHosts.contains(uri.getHost().toLowerCase())) {
+ LOG.debug(String.format("Proxy disabled for host %s", uri.getHost()));
+ return noProxy;
+ }
+
+ // no proxy if no proxy was set
+ if (Objects.nonNull(setProxy)) {
+ LOG.debug(String.format("Proxy used for host %s", uri.getHost()));
+ return setProxy;
+ }
+
+ LOG.debug("No proxy configured to choose from");
+ return noProxy;
+ }
+
+ @Override
+ public void connectFailed(URI uri, SocketAddress socketAddress, IOException e) {
+ LOG.error(String.format("connection to %s failed with %s", uri.getHost(), e.getMessage()));
+ }
+}
diff --git a/src/main/java/de/hftstuttgart/dockertests/app.war b/src/main/java/de/hftstuttgart/dockertests/app.war
deleted file mode 100644
index 8142e006e4d4c144223c7a058ec9c5202cdb6a6f..0000000000000000000000000000000000000000
Binary files a/src/main/java/de/hftstuttgart/dockertests/app.war and /dev/null differ
diff --git a/src/main/java/de/hftstuttgart/dockertests/app/Hello_World.class b/src/main/java/de/hftstuttgart/dockertests/app/Hello_World.class
deleted file mode 100644
index d2de4f5b61a5efb0ffa9bcd9f39c4b0b28816d52..0000000000000000000000000000000000000000
Binary files a/src/main/java/de/hftstuttgart/dockertests/app/Hello_World.class and /dev/null differ
diff --git a/src/main/java/de/hftstuttgart/dockertests/app/Hello_World.class.zip b/src/main/java/de/hftstuttgart/dockertests/app/Hello_World.class.zip
deleted file mode 100644
index bd81b4fdb651acff5185a34fed6b0adba6ec7a2c..0000000000000000000000000000000000000000
Binary files a/src/main/java/de/hftstuttgart/dockertests/app/Hello_World.class.zip and /dev/null differ
diff --git a/src/main/java/de/hftstuttgart/dockertests/app/Hello_World_Test.class b/src/main/java/de/hftstuttgart/dockertests/app/Hello_World_Test.class
deleted file mode 100644
index 5d7134d4fa092dcad011060c66b160f14ba62e7b..0000000000000000000000000000000000000000
Binary files a/src/main/java/de/hftstuttgart/dockertests/app/Hello_World_Test.class and /dev/null differ
diff --git a/src/main/java/de/hftstuttgart/dockertests/app/Hello_World_Test.class.zip b/src/main/java/de/hftstuttgart/dockertests/app/Hello_World_Test.class.zip
deleted file mode 100644
index af6da35507cbaec57aa20dab6efda575a1011829..0000000000000000000000000000000000000000
Binary files a/src/main/java/de/hftstuttgart/dockertests/app/Hello_World_Test.class.zip and /dev/null differ
diff --git a/src/main/java/de/hftstuttgart/dockertests/app/META-INF/MANIFEST.MF b/src/main/java/de/hftstuttgart/dockertests/app/META-INF/MANIFEST.MF
deleted file mode 100644
index 87e05e14230f56aad4347cc2e5cb21ece04dc9de..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/dockertests/app/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-Created-By: 11.0.7 (Oracle Corporation)
-
diff --git a/src/main/java/de/hftstuttgart/dockertests/app/META-INF/war-tracker b/src/main/java/de/hftstuttgart/dockertests/app/META-INF/war-tracker
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/main/java/de/hftstuttgart/dockertests/app/index.html b/src/main/java/de/hftstuttgart/dockertests/app/index.html
deleted file mode 100644
index 3c34854be75e7d8761030664528335cf2b1d895c..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/dockertests/app/index.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- Example
-
-
- Hello World
-
-
\ No newline at end of file
diff --git a/src/main/java/de/hftstuttgart/dockertests/app/junit-platform-console-standalone-1.6.2.jar b/src/main/java/de/hftstuttgart/dockertests/app/junit-platform-console-standalone-1.6.2.jar
deleted file mode 100644
index b47f57abad34340d62dff9340533e4702adb1ddc..0000000000000000000000000000000000000000
Binary files a/src/main/java/de/hftstuttgart/dockertests/app/junit-platform-console-standalone-1.6.2.jar and /dev/null differ
diff --git a/src/main/java/de/hftstuttgart/dockertests/filetest.txt b/src/main/java/de/hftstuttgart/dockertests/filetest.txt
deleted file mode 100644
index 4d8bb0e66e3065c8f5832cbba614cc329eebe078..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/dockertests/filetest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Bind mount persistance data through bind Mount
diff --git a/src/main/java/de/hftstuttgart/exceptions/CorruptedZipFileException.java b/src/main/java/de/hftstuttgart/exceptions/CorruptedZipFileException.java
deleted file mode 100644
index 991a66e7ab81bffad3b60dd7df68a8ebb7c30422..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/exceptions/CorruptedZipFileException.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package de.hftstuttgart.exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-/**
- * Created by Marcel Bochtler on 28.11.16.
- */
-@ResponseStatus(HttpStatus.BAD_REQUEST)
-public class CorruptedZipFileException extends RuntimeException {
- public CorruptedZipFileException(String s) {
- super(s);
- }
-}
diff --git a/src/main/java/de/hftstuttgart/exceptions/NoZipFileException.java b/src/main/java/de/hftstuttgart/exceptions/NoZipFileException.java
deleted file mode 100644
index b3e5aa29e43f5ae3ab1e839ed96a9b64328f686d..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/exceptions/NoZipFileException.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package de.hftstuttgart.exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-/**
- * Created by Marcel Bochtler on 29.11.16.
- */
-@ResponseStatus(HttpStatus.BAD_REQUEST)
-public class NoZipFileException extends RuntimeException {
- public NoZipFileException(String message) {
- super(message);
- }
-}
diff --git a/src/main/java/de/hftstuttgart/models/JenkinsJobData.java b/src/main/java/de/hftstuttgart/models/JenkinsJobData.java
deleted file mode 100644
index 9a641737ae0f20677d4bd7851c9121c25840a37c..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/models/JenkinsJobData.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package de.hftstuttgart.models;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import de.hftstuttgart.utils.BuildState;
-
-import java.util.List;
-
-@JsonInclude
-public class JenkinsJobData {
-
- public JenkinsJobData() {
- }
-
- public String getClassData() {
- return classData;
- }
-
- public List getJobs() {
- return jobs;
- }
-
- @JsonProperty("_class")
- private String classData;
-
- private List jobs;
-
- @JsonProperty("jobs")
- public void unpackingJobs(List jobs) {
- this.jobs = jobs;
- }
-
- public static class Job {
-
- @JsonProperty("_class")
- private String jobClassData;
- @JsonProperty("name")
- private String name;
- @JsonProperty("color")
- private BuildState color;
-
- public String getJobClassData() {
- return jobClassData;
- }
-
- public void setJobClassData(String jobClassData) {
- this.jobClassData = jobClassData;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public BuildState getColor() {
- return color;
- }
-
- public void setColor(BuildState color) {
- this.color = color;
- }
- }
-}
diff --git a/src/main/java/de/hftstuttgart/models/LegacyMoodleResult.java b/src/main/java/de/hftstuttgart/models/LegacyMoodleResult.java
new file mode 100644
index 0000000000000000000000000000000000000000..dbe0bb5353ae8595decd302bf07c182a3e49f9d2
--- /dev/null
+++ b/src/main/java/de/hftstuttgart/models/LegacyMoodleResult.java
@@ -0,0 +1,72 @@
+package de.hftstuttgart.models;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class LegacyMoodleResult {
+
+ public List testResults;
+ public List compilationErrors;
+
+ public static LegacyMoodleResult convertToModdleResult(ModocotResultSummary summary) {
+ LegacyMoodleTestResult tests = new LegacyMoodleTestResult();
+ tests.failureCount = summary.failureCount;
+ tests.testCount = summary.testCount;
+ tests.successfulTests = summary.successes.stream()
+ .map(s -> s.name)
+ .collect(Collectors.toList());
+ tests.testFailures = summary.failures.stream()
+ .map(f -> {
+ LegacyMoodleTestFailure failure = new LegacyMoodleTestFailure();
+ failure.testHeader = f.name;
+ failure.message = f.failureReason;
+ failure.trace = f.stacktrace;
+
+ return failure;
+ })
+ .collect(Collectors.toList());
+
+ List compilationErrors;
+ compilationErrors = summary.compilationErrors.stream()
+ .map(f -> {
+ LegacyMoodleCompilationError cError = new LegacyMoodleCompilationError();
+ cError.javaFileName = f.name;
+ cError.message = f.failureReason;
+ cError.lineNumber = f.lineNumber;
+ cError.columnNumber = f.columnNumber;
+ cError.position = f.position;
+
+ return cError;
+ })
+ .collect(Collectors.toList());
+
+ LegacyMoodleResult result = new LegacyMoodleResult();
+ result.testResults = Collections.singletonList(tests);
+ result.compilationErrors = compilationErrors;
+
+ return result;
+ }
+
+ private static class LegacyMoodleTestResult {
+ public String testName = "UnitTests";
+ public int testCount;
+ public int failureCount;
+ public List successfulTests;
+ public List testFailures;
+ }
+
+ private static class LegacyMoodleTestFailure {
+ public String testHeader;
+ public String message;
+ public String trace;
+ }
+
+ private static class LegacyMoodleCompilationError {
+ public String message;
+ public String javaFileName;
+ public int lineNumber;
+ public int columnNumber;
+ public int position;
+ }
+}
diff --git a/src/main/java/de/hftstuttgart/models/ModocotResult.java b/src/main/java/de/hftstuttgart/models/ModocotResult.java
new file mode 100644
index 0000000000000000000000000000000000000000..a211b7e45a2e3941e0de2df4962c9798af90bed3
--- /dev/null
+++ b/src/main/java/de/hftstuttgart/models/ModocotResult.java
@@ -0,0 +1,22 @@
+package de.hftstuttgart.models;
+
+public class ModocotResult
+{
+ public String name;
+ public int state;
+
+ public String failureType;
+ public String failureReason;
+ public String stacktrace;
+
+ public int columnNumber;
+ public int lineNumber;
+ public int position;
+
+ public static enum State
+ {
+ SUCCESS,
+ FAILURE,
+ UNKNOWN
+ }
+}
diff --git a/src/main/java/de/hftstuttgart/models/ModocotResultSummary.java b/src/main/java/de/hftstuttgart/models/ModocotResultSummary.java
new file mode 100644
index 0000000000000000000000000000000000000000..96f15f6e0364229a0de763f9fd041303a56f7246
--- /dev/null
+++ b/src/main/java/de/hftstuttgart/models/ModocotResultSummary.java
@@ -0,0 +1,16 @@
+package de.hftstuttgart.models;
+
+import java.util.Set;
+
+public class ModocotResultSummary
+{
+ public long timestamp;
+ public int testCount;
+ public int failureCount;
+ public int successCount;
+ public String globalStacktrace;
+
+ public Set successes;
+ public Set failures;
+ public Set compilationErrors;
+}
diff --git a/src/main/java/de/hftstuttgart/models/TestResult.java b/src/main/java/de/hftstuttgart/models/TestResult.java
deleted file mode 100644
index 27c8cfbaeac1629f97506486d309436937ac2941..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/models/TestResult.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package de.hftstuttgart.models;
-
-import org.junit.runner.notification.Failure;
-
-import java.util.List;
-
-public class TestResult {
-
- private String testName;
- private int testCount;
- private int failureCount;
- private List successfulTests;
- private List testFailures;
-
- public String getTestName() {
- return testName;
- }
-
- public void setTestName(String testName) {
- this.testName = testName;
- }
-
- public int getTestCount() {
- return testCount;
- }
-
- public void setTestCount(int testCount) {
- this.testCount = testCount;
- }
-
- public int getFailureCount() {
- return failureCount;
- }
-
- public void setFailureCount(int failureCount) {
- this.failureCount = failureCount;
- }
-
- public List getSuccessfulTests() {
- return successfulTests;
- }
-
- public void setSuccessfulTests(List successfulTests) {
- this.successfulTests = successfulTests;
- }
-
- public List getTestFailures() {
- return testFailures;
- }
-
- public void setTestFailures(List testFailures) {
- this.testFailures = testFailures;
- }
-
- @Override
- public String toString() {
- return "TestResult{" +
- "testName='" + testName + '\'' +
- ", testCount=" + testCount +
- ", failureCount=" + failureCount +
- ", testFailures=" + testFailures +
- '}';
- }
-}
diff --git a/src/main/java/de/hftstuttgart/models/UserResult.java b/src/main/java/de/hftstuttgart/models/UserResult.java
deleted file mode 100644
index 3c0d696b1b35c5689660ab9fb23e0c4f7ba07fa8..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/models/UserResult.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package de.hftstuttgart.models;
-
-import javax.tools.Diagnostic;
-import java.util.List;
-
-public class UserResult {
-
- private List testResults;
- private List compilationErrors;
-
- public UserResult(List testResults) {
-
- this.testResults = testResults;
- }
-
-
- public List getTestResults() {
- return testResults;
- }
-
- public void setTestResults(List testResults) {
- this.testResults = testResults;
- }
-
- public List getCompilationErrors() {
- return compilationErrors;
- }
-
- public void setCompilationErrors(List compilationErrors) {
- this.compilationErrors = compilationErrors;
- }
-
-
-}
diff --git a/src/main/java/de/hftstuttgart/rest/v1/jenkins/RestAPIController.java b/src/main/java/de/hftstuttgart/rest/v1/jenkins/RestAPIController.java
deleted file mode 100644
index 3bfa00331f8c7b4d66057a2302200099fc5fb97c..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/rest/v1/jenkins/RestAPIController.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package de.hftstuttgart.rest.v1.jenkins;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.HashMap;
-import java.util.Map;
-
-@RestController
-public class RestAPIController {
-
- private static final Logger LOG = LogManager.getLogger(RestAPIController.class);
-
- public static final Map JOB_MAP = new HashMap<>();
-
- @PostMapping("/v1/uploaduserresults")
- public void uploadsResults(@RequestParam("jobID") String jobId, @RequestBody String userResult) {
- LOG.info("result: " + userResult);
- if (!JOB_MAP.containsKey(jobId)) {
- String keys = String.join(", ", JOB_MAP.keySet());
- throw new IllegalArgumentException(
- String.format("Key %s does not exist in JOB_MAP, available Keys: [%s]", jobId, keys));
- }
- JOB_MAP.put(jobId, userResult);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/de/hftstuttgart/rest/v1/task/TaskUpload.java b/src/main/java/de/hftstuttgart/rest/v1/task/TaskUpload.java
index 6d402e65c3351d41a017299b5528add5a0109672..83d70b326fab2814bd4ba9e8c78152f89856956d 100644
--- a/src/main/java/de/hftstuttgart/rest/v1/task/TaskUpload.java
+++ b/src/main/java/de/hftstuttgart/rest/v1/task/TaskUpload.java
@@ -1,15 +1,17 @@
package de.hftstuttgart.rest.v1.task;
-import de.hftstuttgart.config.ModocotProperties;
-import de.hftstuttgart.rest.v1.jenkins.RestAPIController;
-import de.hftstuttgart.utils.BackendUtil;
-import de.hftstuttgart.utils.BuildState;
-import de.hftstuttgart.utils.GitTeaUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.dockerjava.api.model.Bind;
+import com.github.dockerjava.api.model.Volume;
+import de.hftstuttgart.models.LegacyMoodleResult;
+import de.hftstuttgart.models.ModocotResultSummary;
+import de.hftstuttgart.rest.v1.unittest.UnitTestUpload;
+import de.hftstuttgart.utils.DockerUtil;
+import de.hftstuttgart.utils.FileUtil;
import de.hftstuttgart.utils.JGitUtil;
-import de.hftstuttgart.utils.TaskUploadUtils;
-import de.hftstuttgart.utils.UnzipUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@@ -17,10 +19,12 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.annotation.MultipartConfig;
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.util.UUID;
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Rest controller for everything related to the TASK files
@@ -31,98 +35,173 @@ import java.util.UUID;
public class TaskUpload {
private static final Logger LOG = LogManager.getLogger(TaskUpload.class);
- private final ModocotProperties modocotProperties;
- private final TaskUploadUtils taskUploadUtils;
private final JGitUtil jGitUtil;
+ private final DockerUtil dockerUtil;
private final String assignmentBasePath;
- private final GitTeaUtil gitTeaUtil;
+ private final Path testTmpPathHost;
+ private final Path testTmpPathModocot;
- public TaskUpload(ModocotProperties modocotProperties,
- TaskUploadUtils taskUploadUtils,
- JGitUtil jGitUtil,
- GitTeaUtil gitTeaUtil) {
- this.modocotProperties = modocotProperties;
- this.taskUploadUtils = taskUploadUtils;
+ public TaskUpload(
+ Environment env,
+ JGitUtil jGitUtil,
+ DockerUtil dockerUtil
+ ) {
this.jGitUtil = jGitUtil;
- this.gitTeaUtil = gitTeaUtil;
- this.assignmentBasePath =
- this.modocotProperties.getModocotParentDirectory()
- + File.separator
- + this.modocotProperties.getModocotAssignmentFolderPrefix();
- }
-
- @RequestMapping(method = RequestMethod.POST)
- public String uploadAndTestFile(@RequestParam("taskFile") MultipartFile taskFileRef,
- @RequestParam("assignmentId") String assignmentId) throws IOException, InterruptedException {
- String jobId = assignmentId + "_" + UUID.randomUUID();
- String subFolderPath = this.assignmentBasePath + assignmentId;
-
- LOG.info("subFolderPath: " + subFolderPath);
- File workDirectory = new File(subFolderPath);
- workDirectory.mkdirs();
-
- LOG.info("created new File");
- File file = new File(subFolderPath, String.valueOf(UUID.randomUUID()));
+ this.dockerUtil = dockerUtil;
- taskFileRef.transferTo(file);
- List unzippedFiles = UnzipUtil.unzip(file);
+ // set base path for assignments to be stored
+ Path p = Paths.get(
+ env.getProperty("modocot.dir"),
+ env.getProperty("modocot.dir.test.folder.name"));
+ this.assignmentBasePath = p.toAbsolutePath().toString();
- if (file.exists()) file.delete();
-
- startFileRead(assignmentId, subFolderPath, unzippedFiles);
-
- BuildState buildState = this.taskUploadUtils.startTask(jobId, subFolderPath);
+ // set path of temporary directory on host and inside our container
+ this.testTmpPathHost = Paths.get(env.getProperty("host.tests.tmp.dir"));
+ this.testTmpPathModocot = Paths.get(env.getProperty("modocot.tests.tmp.dir"));
+ }
- if (buildState != BuildState.BLUE) {
- String jenkinsError = this.taskUploadUtils.getJenkinsConsoleOutput(jobId);
- LOG.error(jenkinsError);
- RestAPIController.JOB_MAP.remove(jobId);
- this.gitTeaUtil.deleteRepository(jobId);
- this.taskUploadUtils.deleteJenkinsJob(jobId);
- return jenkinsError;
+ @RequestMapping(method = RequestMethod.POST)
+ public LegacyMoodleResult uploadAndTestFile(@RequestParam("taskFile") MultipartFile taskFileRef,
+ @RequestParam("assignmentId") String assignmentId
+ ) throws IOException, InterruptedException {
+ LOG.info("submission for testing received");
+
+ LOG.debug("creating new temporary directory");
+ Path workDirectory = Files.createTempDirectory(testTmpPathModocot, "modocot");
+ LOG.debug(String.format("working dir for test is: %s", workDirectory.toAbsolutePath().toString()));
+
+ // define paths for the test, the submission and where the result is to be expected afterwards
+ Path testPath = Paths.get(workDirectory.toAbsolutePath().toString(), "test");
+ Path srcPath = Paths.get(workDirectory.toAbsolutePath().toString(), "src");
+ Path resultPath = Paths.get(workDirectory.toAbsolutePath().toString(), "result");
+
+ // clone stored test to tmpdir
+ LOG.debug("copying pre-downloaded unitttest repo");
+ FileUtil.copyFolder(
+ Paths.get(
+ assignmentBasePath,
+ assignmentId
+ ),
+ testPath
+ );
+
+ LOG.debug("copy test config");
+ Files.copy(
+ Paths.get(
+ assignmentBasePath,
+ assignmentId + ".txt"
+ ),
+ Paths.get(
+ workDirectory.toAbsolutePath().toString(),
+ "config.txt"
+ )
+ );
+
+ // clone student code to tmpdir
+ Pattern pattern = Pattern.compile(UnitTestUpload.modocotDueConfigRegex);
+ Matcher config = null;
+
+ LOG.debug("reading task file");
+ // open received file in a try-with
+ try (BufferedReader br = new BufferedReader(
+ new InputStreamReader(
+ taskFileRef.getInputStream()))) {
+ String line;
+
+ // as long as we haven't found a configuration and have lines left, search
+ while (config == null && (line = br.readLine()) != null) {
+ Matcher matcher = pattern.matcher(line);
+ if (matcher.matches()) {
+ LOG.debug(String.format("found modocot 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");
+ }
}
- Thread.sleep(3000);
-
- String userResult = RestAPIController.JOB_MAP.remove(jobId);
-
- this.gitTeaUtil.deleteRepository(jobId);
-
- this.taskUploadUtils.deleteJenkinsJob(jobId);
+ LOG.debug("calling repo clone");
+ jGitUtil.cloneRepository(config, srcPath.toAbsolutePath().toString());
+
+ Files.createDirectory(resultPath);
+
+ LOG.info("starting unittest");
+ pattern = Pattern.compile(UnitTestUpload.modocotTestConfigRegex);
+ config = null;
+
+ LOG.debug("reading test config");
+ // open test config and read it in again, important to know with which docker image the test should be run
+ try (BufferedReader br = new BufferedReader(
+ new InputStreamReader(
+ new FileInputStream(Paths.get(workDirectory.toAbsolutePath().toString(), "config.txt").toFile())))) {
+ String line;
+ while (config == null && (line = br.readLine()) != null) {
+ Matcher matcher = pattern.matcher(line);
+ if (matcher.matches()) {
+ LOG.debug(String.format("found modocot line: %s", line));
+ config = matcher;
+ }
+ }
+ } catch (IOException e) {
+ LOG.error("Error while reading test config", e);
+ }
+ finally {
+ if (config == null) {
+ throw new RuntimeException("couldn't find test config for unittest");
+ }
+ }
- if (!this.taskUploadUtils.isValidJSON(userResult)) {
- throw new IllegalArgumentException("userResult from JUnitTestLauncher is invalid: " + userResult);
+ // define the paths to mount as Binds from Host to the test-container
+ Path testPathHost = Paths.get(
+ testTmpPathHost.toAbsolutePath().toString(),
+ workDirectory.getName(workDirectory.getNameCount()-1).toString(),
+ testPath.getName(testPath.getNameCount()-1).toString()
+ );
+ Path srcPathHost = Paths.get(
+ testTmpPathHost.toAbsolutePath().toString(),
+ workDirectory.getName(workDirectory.getNameCount()-1).toString(),
+ srcPath.getName(srcPath.getNameCount()-1).toString()
+ );
+ Path resultPathHost = Paths.get(
+ testTmpPathHost.toAbsolutePath().toString(),
+ workDirectory.getName(workDirectory.getNameCount()-1).toString(),
+ resultPath.getName(resultPath.getNameCount()-1).toString()
+ );
+
+ // start test-container with professor given image and bind mounts for test, submission and result
+ dockerUtil.runContainer(
+ config.group(4),
+ new Bind(testPathHost.toAbsolutePath().toString(), new Volume("/modocot/test")),
+ new Bind(srcPathHost.toAbsolutePath().toString(), new Volume("/modocot/src")),
+ new Bind(resultPathHost.toAbsolutePath().toString(), new Volume("/modocot/result"))
+ );
+
+ // define expected result file
+ File resultFile = Paths.get(resultPath.toAbsolutePath().toString(), "result.json").toFile();
+
+ // check if result file is there
+ if (!resultFile.exists() || !resultFile.isFile()) {
+ LOG.error(String.format("couln't find result file in %s", resultFile.getAbsolutePath()));
+ throw new RuntimeException("no resultfile found");
}
- return userResult;
- }
+ LOG.debug("parse results json");
+ ObjectMapper objectMapper = new ObjectMapper();
+ ModocotResultSummary resultSummary = objectMapper.readValue(
+ resultFile.toURI().toURL(),
+ ModocotResultSummary.class);
- /**
- * Extracting all lines from repo.txt and cloning extracted repository
- *
- * @param assignmentId String assignmentId
- * @param subFolderPath working-directory
- * @param unzippedFiles List of all Files from {@link MultipartFile}
- */
- private void startFileRead(String assignmentId, String subFolderPath, List unzippedFiles) {
- boolean gotRepoFile = unzippedFiles.stream().anyMatch(zipFile -> zipFile.getName().equalsIgnoreCase("repo.txt"));
- if (gotRepoFile) {
- List lines = BackendUtil.extractLinesFromRepoFile(unzippedFiles, "repo.txt");
- String repoUrl = (lines.size() > 0 && !lines.get(0).equals("")) ?
- lines.get(0) : "";
- String credentials = (lines.size() > 1 && !lines.get(1).equals("")) ?
- lines.get(1) : null;
- File unit = new File(subFolderPath + "/src/UnitTests");
- unit.mkdirs();
- File task = new File(subFolderPath + "/src/Test");
- task.mkdirs();
-
- this.jGitUtil.cloneRepository("http://" + this.modocotProperties.getDockerHostIp()
- + ":3000/" + this.modocotProperties.getGitTeaUsername() + "/"
- + assignmentId + ".git",
- unit, null, true, false);
- this.jGitUtil.cloneRepository(repoUrl, task, credentials, credentials != null, true);
- }
+ // convert to moddle plugin readable format and return to moodle
+ LOG.debug("convert to moodle understandable format");
+ LegacyMoodleResult moodleResult = LegacyMoodleResult.convertToModdleResult(resultSummary);
+
+ LOG.info("submission tested successfully");
+ return moodleResult;
}
}
diff --git a/src/main/java/de/hftstuttgart/rest/v1/unittest/UnitTestUpload.java b/src/main/java/de/hftstuttgart/rest/v1/unittest/UnitTestUpload.java
index 92a9357f86dc54f127fffa7b60d2fa3bc3349b89..6a6fcdd36376bd636c7ee3c7a0e9bd47fa8027e2 100644
--- a/src/main/java/de/hftstuttgart/rest/v1/unittest/UnitTestUpload.java
+++ b/src/main/java/de/hftstuttgart/rest/v1/unittest/UnitTestUpload.java
@@ -1,15 +1,10 @@
package de.hftstuttgart.rest.v1.unittest;
-import de.hftstuttgart.config.ModocotProperties;
-import de.hftstuttgart.utils.BackendUtil;
-import de.hftstuttgart.utils.FileUtil;
-import de.hftstuttgart.utils.GitTeaUtil;
import de.hftstuttgart.utils.JGitUtil;
-import de.hftstuttgart.utils.UnzipUtil;
-import io.gitea.model.Repository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import org.eclipse.jgit.transport.PushResult;
+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;
@@ -17,13 +12,11 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.annotation.MultipartConfig;
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.util.Objects;
-import java.util.UUID;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
+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.
@@ -34,93 +27,77 @@ import java.util.stream.Stream;
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 ModocotProperties modocotProperties;
- private final GitTeaUtil gitTeaUtil;
private final JGitUtil jGitUtil;
private final String assignmentBasePath;
- public UnitTestUpload(ModocotProperties modocotProperties,
- GitTeaUtil gitTeaUtil,
- JGitUtil jGitUtil) {
- this.modocotProperties = modocotProperties;
- this.gitTeaUtil = gitTeaUtil;
+ public UnitTestUpload(Environment env, JGitUtil jGitUtil) {
this.jGitUtil = jGitUtil;
- this.assignmentBasePath =
- modocotProperties.getModocotParentDirectory()
- + File.separator
- + modocotProperties.getModocotAssignmentFolderPrefix();
+
+ 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 zip file which contains the JUnit tests
+ * @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 {
-
- // path to the directory in which we will be working
- String subFolderPath = this.assignmentBasePath + assignmentId;
-
- LOG.info("work-directory: " + subFolderPath);
- // creating the work-directory
- File workDirectory = new File(subFolderPath);
- workDirectory.mkdirs();
-
- // creating the file which the unitTestFileRef will be transferred into
- File file = new File(subFolderPath, String.valueOf(UUID.randomUUID()));
-
- // transferring MultipartFile into temporary file
+ 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);
-
- // unzipping temporary file to work-directory
- List zipFiles = UnzipUtil.unzip(file);
-
- // unzipping temporary file (not needed anymore)
- if (file.exists()) file.delete();
-
- // check if any extracted files are named repo.txt
- if (zipFiles.stream().anyMatch(zipFile -> zipFile.getName().equalsIgnoreCase("repo.txt"))) {
- // reading all from the repo.txt
- List lines = BackendUtil.extractLinesFromRepoFile(zipFiles, "repo.txt");
- // either set the first line of repo.txt or ""
- String repoUrl = (lines.size() > 0 && !lines.get(0).equals("")) ?
- lines.get(0) : "";
- LOG.info("repoUrl: " + repoUrl);
- // either set the second line of repo.txt or null
- String credentials = ((lines.size() > 1) && !lines.get(1).equals("")) ?
- lines.get(1) : null;
- LOG.info("credentials: " + credentials);
- // cloning repository repoUrl into work-directory, using credentials from second line in repo.txt
- this.jGitUtil.cloneRepository(repoUrl, workDirectory, credentials, credentials != null,true);
- }
-
- Stream.of(Objects.requireNonNull(workDirectory.listFiles()))
- .forEach(fi -> System.out.println(fi.getAbsolutePath()));
-
- if(this.gitTeaUtil.repositoryExists(assignmentId)) {
- this.gitTeaUtil.deleteRepository(assignmentId);
+ 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);
}
- // creating repository on internal giTea, name = assignmentId
- Repository repo = this.gitTeaUtil.createRepository(assignmentId);
- System.out.println(repo);
- // giTea runs in docker and returns CloneUrl as localhost, replacing localhost with docker-host ip
- repo.setCloneUrl(repo.getCloneUrl().replace("localhost", modocotProperties.getDockerHostIp()));
-
- // committing everything in work-directory and push to created repository
- Iterable pushResults = this.jGitUtil.commitAllAndPush(workDirectory, repo, false);
- if (pushResults != null) {
- for (PushResult pushResult : pushResults) {
- LOG.info("Push-Result: " + pushResult.getMessages());
+ finally {
+ if (config == null) {
+ throw new RuntimeException("couldn't find repo config for unittest clone");
}
}
- // deleting created work-directory
- FileUtil.deleteFolderRecursively(workDirectory);
- LOG.info("Uploaded unit test file: " + workDirectory);
+ 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()));
}
/**
@@ -133,10 +110,21 @@ public class UnitTestUpload {
*/
@RequestMapping(method = RequestMethod.DELETE)
public void deleteUnitTestFiles(@RequestParam("assignmentId") String assignmentId) {
- String path = this.assignmentBasePath + assignmentId;
- File dir = new File(path);
- if (dir.exists()) {
- FileUtil.deleteFolderRecursively(dir);
- }
+ 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));
}
}
diff --git a/src/main/java/de/hftstuttgart/utils/BackendUtil.java b/src/main/java/de/hftstuttgart/utils/BackendUtil.java
deleted file mode 100644
index 428c7dcb26d7d005228859130c3a3577b61ba1a1..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/utils/BackendUtil.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package de.hftstuttgart.utils;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.List;
-import java.util.stream.Collectors;
-
-public class BackendUtil {
-
- /**
- * Loop through all {@link File}s in {@code filesFromZipFile} and find {@link File} {@code fileNameToSearchFor}.
- * And return a {@link List} of Strings for each line in file {@code fileNameToSearchFor}
- *
- * @param filesFromZipFile all files which get extracted from previous zipFile
- * @param fileNameToSearchFor search for specific name
- * @return {@link List} of Strings for each line in file {@code fileNameToSearchFor}
- */
- public static List extractLinesFromRepoFile(List filesFromZipFile, String fileNameToSearchFor) {
- if(filesFromZipFile.size() < 1 && fileNameToSearchFor != null) {
- throw new IllegalArgumentException();
- }
- List lines = null;
- for (File file : filesFromZipFile) {
- if (file.getName().equalsIgnoreCase(fileNameToSearchFor)) {
- try {
- FileInputStream fis = new FileInputStream(file);
- BufferedReader br = new BufferedReader(new InputStreamReader(fis));
- lines = br.lines().collect(Collectors.toList());
- br.close();
- if (file.exists())
- file.delete();
- } catch (IOException ignored) { }
- }
- }
- return lines;
- }
-}
diff --git a/src/main/java/de/hftstuttgart/utils/BuildState.java b/src/main/java/de/hftstuttgart/utils/BuildState.java
deleted file mode 100644
index 718b165f98531bc1e9e1bc5bb5dab2210e27cba4..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/utils/BuildState.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package de.hftstuttgart.utils;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public enum BuildState {
- @JsonProperty("blue") BLUE,
- @JsonProperty("notbuilt") NOTBUILT,
- @JsonProperty("notbuilt_anime") NOTBUILT_ANMIE,
- @JsonProperty("red") RED,
- @JsonProperty("yellow") YELLOW,
- @JsonProperty("grey") GREY,
- @JsonProperty("disabled") DISABLED,
- @JsonProperty("aborted") ABORTED,
- @JsonProperty("aborted_anime") ABORTED_ANIME,
- @JsonProperty("grey_anime") GREY_ANIME
-
-}
diff --git a/src/main/java/de/hftstuttgart/utils/DockerUtil.java b/src/main/java/de/hftstuttgart/utils/DockerUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..7c9183c68a08edbbc9af15190cca2f8c461270f0
--- /dev/null
+++ b/src/main/java/de/hftstuttgart/utils/DockerUtil.java
@@ -0,0 +1,75 @@
+package de.hftstuttgart.utils;
+
+import com.github.dockerjava.api.DockerClient;
+import com.github.dockerjava.api.command.CreateContainerResponse;
+import com.github.dockerjava.api.model.Bind;
+import com.github.dockerjava.api.model.HostConfig;
+import com.github.dockerjava.core.DefaultDockerClientConfig;
+import com.github.dockerjava.core.DockerClientConfig;
+import com.github.dockerjava.core.DockerClientImpl;
+import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
+import com.github.dockerjava.transport.DockerHttpClient;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+
+@Component
+public class DockerUtil {
+ private static final Logger LOG = LogManager.getLogger(DockerUtil.class);
+
+ private DockerClient dockerClient;
+
+ public DockerUtil(Environment env) {
+ LOG.info("initializing Docker tools");
+ LOG.debug("create docker client config");
+ DockerClientConfig dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder().build();
+
+ LOG.debug("create docker http client");
+ DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
+ .dockerHost(dockerClientConfig.getDockerHost())
+ .sslConfig(dockerClientConfig.getSSLConfig())
+ .build();
+
+ LOG.debug("create docker client");
+ dockerClient = DockerClientImpl.getInstance(dockerClientConfig, httpClient);
+ }
+
+ public int runContainer(String image, Bind... binds) throws InterruptedException, IOException
+ {
+ LOG.debug(String.format("pull image: %s", image));
+ dockerClient.pullImageCmd(image)
+ .start()
+ .awaitCompletion()
+ .close();
+
+ LOG.debug("creating container");
+ CreateContainerResponse containerResponse = dockerClient.createContainerCmd("testcontainer")
+ .withImage(image)
+ .withHostConfig(
+ HostConfig.newHostConfig()
+ .withBinds(binds))
+ .exec();
+ LOG.debug(String.format("container created: %s", containerResponse.getId()));
+
+ LOG.debug(String.format("starting container %s", containerResponse.getId()));
+ dockerClient.startContainerCmd(containerResponse.getId()).exec();
+
+ LOG.debug(String.format("waiting for completion of container %s", containerResponse.getId()));
+ int ret = dockerClient
+ .waitContainerCmd(containerResponse.getId())
+ .start()
+ .awaitCompletion()
+ .awaitStatusCode();
+ LOG.debug(String.format("container completed with status %d", ret));
+
+ LOG.debug(String.format("deleting container %s", containerResponse.getId()));
+ dockerClient.removeContainerCmd(containerResponse.getId())
+ .withRemoveVolumes(true)
+ .exec();
+
+ return ret;
+ }
+}
diff --git a/src/main/java/de/hftstuttgart/utils/FileUtil.java b/src/main/java/de/hftstuttgart/utils/FileUtil.java
index 98d088c7a6566074245b9aa3ecf144b042f2ca08..0e4f01dea1ef75b4d3ef9fba56d1229d4aab47af 100644
--- a/src/main/java/de/hftstuttgart/utils/FileUtil.java
+++ b/src/main/java/de/hftstuttgart/utils/FileUtil.java
@@ -1,6 +1,9 @@
package de.hftstuttgart.utils;
import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
/**
* Helper Class for all file related tasks.
@@ -27,4 +30,14 @@ public class FileUtil {
folder.delete();
}
+ public static void copyFolder(Path src, Path dst) throws IOException {
+ Files.walk(src)
+ .forEach(source -> {
+ try {
+ Files.copy(source, dst.resolve(src.relativize(source)));
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ });
+ }
}
diff --git a/src/main/java/de/hftstuttgart/utils/GitTeaUtil.java b/src/main/java/de/hftstuttgart/utils/GitTeaUtil.java
deleted file mode 100644
index 3fe9d47e140edeb5c46bd42d6e13e9d0519c9512..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/utils/GitTeaUtil.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package de.hftstuttgart.utils;
-
-import de.hftstuttgart.config.ModocotProperties;
-import io.gitea.ApiClient;
-import io.gitea.ApiException;
-import io.gitea.Configuration;
-import io.gitea.api.RepositoryApi;
-import io.gitea.api.UserApi;
-import io.gitea.auth.HttpBasicAuth;
-import io.gitea.model.CreateRepoOption;
-import io.gitea.model.Repository;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-@Component
-public class GitTeaUtil {
-
- private static final Logger LOG = LogManager.getLogger(GitTeaUtil.class);
-
- private final ModocotProperties modocotProperties;
-
- public GitTeaUtil(ModocotProperties modocotProperties) {
- this.modocotProperties = modocotProperties;
- }
-
- /**
- * Create Git-Repository with name {@code repositoryName} on internal Git-Server
- *
- * @param repositoryName name of new Repository
- * @return newly created Repository
- */
- public Repository createRepository(String repositoryName) {
- setupAuth();
- Repository repo = null;
- try {
- repo = new UserApi()
- .createCurrentUserRepo(new CreateRepoOption().name(repositoryName));
- } catch (ApiException e) {
- LOG.error(String.format("Error while creating repository: %s", repositoryName), e);
- }
- if (repo != null) {
- LOG.info("Created repository {} on {}", repositoryName, repo.getCloneUrl());
- } else {
- throw new IllegalStateException("Repository is null");
- }
- return repo;
- }
-
- /**
- * Delete Git-Repository with name {@code repositoryName} on internal Git-Server
- *
- * @param repositoryName name of new Repository
- */
- public void deleteRepository(String repositoryName) {
- setupAuth();
- try {
- new RepositoryApi().repoDelete(this.modocotProperties.getGitTeaUsername(), repositoryName);
- } catch (ApiException e) {
- LOG.error("Error while deleting repository:" + e.getMessage());
- }
- }
-
- /**
- * Check if a Git-Repository with the given name exists.
- *
- * @param repositoryName name of the Repository
- */
- public boolean repositoryExists(String repositoryName) {
- setupAuth();
- Repository repository = null;
- try {
- repository = new RepositoryApi().repoGet(this.modocotProperties.getGitTeaUsername(), repositoryName);
- } catch (ApiException e) {
- LOG.error("Error while deleting repository:" + e.getMessage());
- }
- return repository != null;
- }
-
- private void setupAuth() {
- ApiClient defaultClient = Configuration.getDefaultApiClient();
-
- defaultClient.setBasePath(this.modocotProperties.getGitTeaBasePath());
- HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("BasicAuth");
- basicAuth.setUsername(this.modocotProperties.getGitTeaUsername());
- basicAuth.setPassword(this.modocotProperties.getGitTeaPassword());
- }
-}
diff --git a/src/main/java/de/hftstuttgart/utils/JGitUtil.java b/src/main/java/de/hftstuttgart/utils/JGitUtil.java
index c4722c1ccc877ad1eaa27194b119469dcb3dc73b..b3cd18d30262cb84d8404d531e3235a6840b00c5 100644
--- a/src/main/java/de/hftstuttgart/utils/JGitUtil.java
+++ b/src/main/java/de/hftstuttgart/utils/JGitUtil.java
@@ -1,189 +1,53 @@
package de.hftstuttgart.utils;
-import de.hftstuttgart.config.ModocotProperties;
-import io.gitea.model.Repository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.transport.PushResult;
-import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.springframework.stereotype.Component;
+import org.springframework.util.FileSystemUtils;
import java.io.File;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.net.ProxySelector;
-import java.net.SocketAddress;
-import java.net.URI;
-import java.util.Arrays;
-import java.util.List;
+import java.util.regex.Matcher;
@Component
public class JGitUtil {
private static final Logger LOG = LogManager.getLogger(JGitUtil.class);
- private final ModocotProperties modocotProperties;
+ public JGitUtil() {}
- public JGitUtil(ModocotProperties modocotProperties) {
- this.modocotProperties = modocotProperties;
- }
+ public void cloneRepository(Matcher config, String targetPath) {
+ LOG.debug(String.format("cloning repository: %s", config.group(1)));
- /**
- * Clone Repository from {@code uriToClone} into Directory {@code cloneDirectory}, and using token {@code token}.
- * {@code boolean proxy} determines, if a proxy should be used
- *
- * @param uriToClone Repository cloneUrl
- * @param cloneDirectory {@link File} directory in which Repository should be cloned into
- * @param token AuthToken, when cloning Repository. If {@code null} use {@code ModocotProperties}
- * @param proxy boolean if a proxy should be used
- */
- public void cloneRepository(String uriToClone, File cloneDirectory, String token, boolean useToken, boolean proxy) {
- if (!cloneDirectory.isDirectory()) {
- String error = String.format("%s is not a directory, cannot clone", cloneDirectory.getAbsolutePath());
- LOG.error(error);
- throw new IllegalArgumentException(error);
- }
- LOG.info(String.format("Cloning all files from %s into %s", uriToClone, cloneDirectory.getAbsolutePath()));
- try {
- deleteDotGitFolder(cloneDirectory);
- UsernamePasswordCredentialsProvider credProvider = null;
- LOG.info("using token: " + useToken);
- if (useToken) {
- LOG.info("token: " + token);
- if (token != null) {
- LOG.info("Using token: " + token);
- String[] credentials = token.split(":");
- credProvider = new UsernamePasswordCredentialsProvider(credentials[0], credentials[1]);
- } else {
- LOG.info("Using credentials: " + this.modocotProperties.getGitTeaUsername() + ", " + this.modocotProperties.getGitTeaPassword());
- credProvider = new UsernamePasswordCredentialsProvider(
- this.modocotProperties.getGitTeaUsername(),
- this.modocotProperties.getGitTeaPassword());
- }
- }
- LOG.info("Starting cloning, url: " + uriToClone);
- setProxy(proxy);
- if (useToken) {
- Git.cloneRepository()
- .setCredentialsProvider(credProvider)
- .setURI(uriToClone)
- .setDirectory(cloneDirectory)
- .call()
- .close();
- } else {
- Git.cloneRepository()
- .setURI(uriToClone)
- .setDirectory(cloneDirectory)
- .call()
- .close();
- }
- } catch (GitAPIException e) {
- LOG.error(String.format("Error while cloning from %s", uriToClone), e);
+ File targetDirectory = new File(targetPath);
+ if (targetDirectory.exists()) {
+ LOG.debug("clone target directory existing yet, deleting now");
+ FileSystemUtils.deleteRecursively(targetDirectory);
}
- }
- /**
- * Commit {@code directory} and push all files to the given {@code repository}.
- *
- * @param directory {@link File} directory to commit
- * @param repository {@link Repository} Repository to push to
- * @param proxy boolean if a proxy should be used
- * @return {@code Iterable}
- */
- public Iterable commitAllAndPush(File directory, Repository repository, boolean proxy) {
- if (!directory.isDirectory()) {
- String error = String.format("%s is not a directory, cannot commit or push", directory.getAbsolutePath());
- LOG.error(error);
- throw new IllegalArgumentException(error);
- }
- LOG.info(String.format("Committing all files in: %s and pushing them to: %s", directory.getAbsolutePath(), repository.getCloneUrl()));
try {
- deleteDotGitFolder(directory);
- // "git init" new repository
- Git.init()
- .setDirectory(directory)
- .call();
-
- // open new repository
- Git git = Git.open(directory);
-
- // "git add ." on repository
- git.add()
- .addFilepattern(".")
- .call();
-
- // "git commit -m %gitTeaCommitMessage%" on repository
- git.commit()
- .setMessage(this.modocotProperties.getGitTeaDefaultCommitMessage())
- .call();
-
- // add new remote from repository
- git.remoteAdd()
- .setName(this.modocotProperties.getGitTeaOrigin())
- .setUri(new URIish(repository.getCloneUrl()))
- .call();
- // "git push" to new origin
- setProxy(proxy);
- return git.push()
- .setCredentialsProvider(new UsernamePasswordCredentialsProvider(
- this.modocotProperties.getGitTeaUsername(),
- this.modocotProperties.getGitTeaPassword()))
- .call();
-
- } catch (Exception e) {
- LOG.error(String.format("Error while committing to repo: %s from file: %s", repository, directory.getAbsolutePath()), e);
- }
- return null;
- }
+ LOG.debug("preparing clone");
+ CloneCommand cloneCommand = Git.cloneRepository()
+ .setDirectory(targetDirectory)
+ .setURI(config.group(1));
+
+ if (!config.group(2).equals("none") && !config.group(3).equals("none")) {
+ LOG.debug("setting credentials");
+ cloneCommand.setCredentialsProvider(
+ new UsernamePasswordCredentialsProvider(config.group(2), config.group(3)));
+ }
- private void deleteDotGitFolder(File directory) {
- File temp = new File(directory.getPath() + "/src/UnitTests/.git");
- if (temp.exists() && temp.isDirectory() && temp.canWrite()) {
- FileUtil.deleteFolderRecursively(temp);
+ LOG.debug("cloning...");
+ cloneCommand.call()
+ .close();
}
- temp = new File(directory.getPath() + "/src/.git");
- if (temp.exists() && temp.isDirectory() && temp.canWrite()) {
- FileUtil.deleteFolderRecursively(temp);
+ catch (GitAPIException e) {
+ LOG.error(String.format("Error while cloning from %s", config.group(1)), e);
}
- temp = new File(directory.getPath() + "/.git");
- if (temp.exists() && temp.isDirectory() && temp.canWrite()) {
- FileUtil.deleteFolderRecursively(temp);
- }
- }
-
- private void setProxy(boolean proxy) {
- if (proxy) {
- ProxySelector.setDefault(new ProxySelector() {
- final ProxySelector delegate = ProxySelector.getDefault();
- @Override
- public List select(URI uri) {
- // Filter the URIs to be proxied
- if (uri.toString().contains("https")) {
- return Arrays.asList(new Proxy(Proxy.Type.HTTP, InetSocketAddress
- .createUnresolved("proxy.hft-stuttgart.de", 80)));
- }
- if (uri.toString().contains("http")) {
- return Arrays.asList(new Proxy(Proxy.Type.HTTP, InetSocketAddress
- .createUnresolved("proxy.hft-stuttgart.de", 80)));
- }
- // revert to the default behaviour
- return delegate == null ? Arrays.asList(Proxy.NO_PROXY)
- : delegate.select(uri);
- }
-
- @Override
- public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
- if (uri == null || sa == null || ioe == null) {
- throw new IllegalArgumentException(
- "Arguments can't be null.");
- }
- }
- });
- }
+ LOG.debug(String.format("cloned from %s to %s", config.group(1), targetDirectory));
}
}
diff --git a/src/main/java/de/hftstuttgart/utils/RestCall.java b/src/main/java/de/hftstuttgart/utils/RestCall.java
deleted file mode 100644
index 6dce14bedf1d7b750b9de5221fdbd7df52390511..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/utils/RestCall.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package de.hftstuttgart.utils;
-
-import de.hftstuttgart.config.ModocotProperties;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.tomcat.util.codec.binary.Base64;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-
-@Component
-public class RestCall {
-
- private static final Logger LOG = LogManager.getLogger(RestCall.class);
-
- private final ModocotProperties modocotProperties;
-
- public RestCall(ModocotProperties modocotProperties) {
- this.modocotProperties = modocotProperties;
- }
-
- public ResponseEntity exchange(String specificUrl, HttpMethod method, T body, Class responseType, Object... uriVariables) {
- RestTemplate restTemplate = new RestTemplate();
- HttpHeaders headers = new HttpHeaders();
- headers.setContentType(MediaType.APPLICATION_XML);
- headers.add("Authorization", "Basic " + new String(Base64.encodeBase64((this.modocotProperties.getJenkinsApiToken()).getBytes())));
- headers.add("user", "admin");
- LOG.info(method.toString() + ", to: " + this.modocotProperties.getJenkinsBaseUrl() + specificUrl);
- return restTemplate.exchange(this.modocotProperties.getJenkinsBaseUrl() + specificUrl, method, new HttpEntity<>(body, headers), responseType, uriVariables);
- }
-}
diff --git a/src/main/java/de/hftstuttgart/utils/TaskUploadUtils.java b/src/main/java/de/hftstuttgart/utils/TaskUploadUtils.java
deleted file mode 100644
index a287a8209d9fb41ecfeedb57639ef6e090fc8a28..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/utils/TaskUploadUtils.java
+++ /dev/null
@@ -1,177 +0,0 @@
-package de.hftstuttgart.utils;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import de.hftstuttgart.config.ModocotProperties;
-import de.hftstuttgart.models.JenkinsJobData;
-import de.hftstuttgart.rest.v1.jenkins.RestAPIController;
-import freemarker.template.Configuration;
-import freemarker.template.Template;
-import freemarker.template.TemplateException;
-import freemarker.template.Version;
-import io.gitea.model.Repository;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.Map;
-
-@Component
-public class TaskUploadUtils {
-
- private static final Logger LOG = LogManager.getLogger(TaskUploadUtils.class);
- private final GitTeaUtil gitTeaUtil;
- private final ModocotProperties modocotProperties;
- private final JGitUtil jGitUtil;
- private final RestCall restCall;
-
- public TaskUploadUtils(GitTeaUtil gitTeaUtil,
- ModocotProperties modocotProperties,
- JGitUtil jGitUtil,
- RestCall restCall) {
- this.gitTeaUtil = gitTeaUtil;
- this.modocotProperties = modocotProperties;
- this.jGitUtil = jGitUtil;
- this.restCall = restCall;
- }
-
- /**
- * Start jenkinsJob and return its BuildStatus after completion
- *
- * @param jobId String jenkinsJobId
- * @param subFolderPath workingDirectory
- * @return Jenkins BuildStatus
- */
- public BuildState startTask(String jobId, String subFolderPath) throws IOException, InterruptedException {
- // we clone the Student submission to /Test subfolder and then copy those files into the working directory
- File f = new File(subFolderPath + "/src/Test");
- for (File fi : f.listFiles()) {
- Files.move(Paths.get(fi.getPath()), Paths.get(subFolderPath + "/src/" + fi.getName()));
- }
- if (f.exists()) f.delete();
-
- File temp = new File(subFolderPath + "/src/UnitTests/.git");
- if (temp.exists() && temp.isDirectory() && temp.canWrite()) {
- FileUtil.deleteFolderRecursively(temp);
- }
- temp = new File(subFolderPath + "/src/.git");
- if (temp.exists() && temp.isDirectory() && temp.canWrite()) {
- FileUtil.deleteFolderRecursively(temp);
- }
-
- // creating the jobId.json containing the jobId
- FileWriter fileWriter = new FileWriter(subFolderPath + "/src/jobId.json");
- fileWriter.write(new ObjectMapper().readTree("{\"jobId\":\"" + jobId + "\"}").toString());
- fileWriter.close();
-
- // creating repository with name jobId
- Repository repository = this.gitTeaUtil.createRepository(jobId);
- repository.setCloneUrl(repository.getCloneUrl().replace("localhost", modocotProperties.getDockerHostIp()));
-
- // committing work-directory and pushing all files to repository
- this.jGitUtil.commitAllAndPush(new File(subFolderPath), repository, false);
-
- FileUtil.deleteFolderRecursively(new File(subFolderPath));
-
- // persisting the jobId
- RestAPIController.JOB_MAP.put(jobId, null);
-
- createJenkinsJob(jobId, repository.getCloneUrl());
- buildJenkinsJob(jobId);
-
- // waiting for jenkinsJob to finish then returning its BuildStatus
- int timeout = 0;
- BuildState buildState = getJenkinsBuildState(jobId);
- while (buildState != BuildState.BLUE && buildState != BuildState.RED) {
- buildState = getJenkinsBuildState(jobId);
- if (timeout >= 100) break;
- Thread.sleep(6000);
- timeout++;
- }
- return buildState;
- }
-
- public void deleteJenkinsJob(String jobId) {
- LOG.info("deleteJenkinsJob jobId: " + jobId);
- ResponseEntity response = this.restCall.exchange("job/" + jobId + "/doDelete", HttpMethod.POST, null, String.class);
- }
-
-
- private BuildState getJenkinsBuildState(String jenkinsJob) {
- LOG.info("getJenkinsBuildState jenkinsJob: " + jenkinsJob);
- ResponseEntity response = this.restCall.exchange("api/json?tree=jobs[name,color]", HttpMethod.GET, null, JenkinsJobData.class);
-
- if (response.getBody() == null) {
- throw new NullPointerException("Jenkins Response was null");
- }
-
- return response.getBody()
- .getJobs()
- .stream()
- .filter(job -> job.getName().equals(jenkinsJob))
- .findFirst()
- .get()
- .getColor();
-
- }
-
- public String getJenkinsConsoleOutput(String jenkinsJob) {
- ResponseEntity response = this.restCall.exchange("job/" + jenkinsJob + "/lastBuild/consoleText", HttpMethod.GET, null, String.class);
- return response.getBody();
- }
-
- private void buildJenkinsJob(String user) {
- LOG.info("buildJenkinsJob user: " + user);
- ResponseEntity response = this.restCall.exchange("job/" + user + "/build", HttpMethod.POST, null, String.class);
- }
-
- private void createJenkinsJob(String gitUser, String gitUrl) {
- LOG.info("createJenkinsJob gitUser: " + gitUser + ", gitUrl: " + gitUrl);
- ResponseEntity response = this.restCall.exchange("createItem?name=" + gitUser, HttpMethod.POST, createXmlFile(gitUser, gitUrl), String.class);
- }
-
- private String createXmlFile(String gitUser, String gitUrl) {
- // fill data map for template
- Map templateData = new HashMap<>();
- templateData.put("gitUser", gitUser);
- templateData.put("gitUrl", gitUrl);
-
- // freemarker create config
- Configuration cfg = new Configuration(new Version("2.3.30"));
- cfg.setClassForTemplateLoading(this.getClass(), "/templates");
- cfg.setDefaultEncoding("UTF-8");
-
- // fuse config and data
- StringWriter out = new StringWriter();
- try {
- Template template = cfg.getTemplate("JenkinsFile.ftl");
- template.process(templateData, out);
- LOG.info(String.format("Template created with gitUrl: %s and gitUser: %s", gitUrl, gitUser));
- } catch (IOException | TemplateException e) {
- e.printStackTrace();
- }
- return out.getBuffer().toString();
- }
-
- public boolean isValidJSON(final String json) {
- boolean valid = false;
- try {
- final JsonParser parser = new ObjectMapper().getFactory().createParser(json);
- while (parser.nextToken() != null) {
- }
- valid = true;
- } catch (IOException e) {
- LOG.error("Json is invalid", e);
- }
- return valid;
- }
-}
diff --git a/src/main/java/de/hftstuttgart/utils/UnzipUtil.java b/src/main/java/de/hftstuttgart/utils/UnzipUtil.java
deleted file mode 100644
index 50a61aae299db1691d391c6f4e155c1d42f334a8..0000000000000000000000000000000000000000
--- a/src/main/java/de/hftstuttgart/utils/UnzipUtil.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package de.hftstuttgart.utils;
-
-import de.hftstuttgart.exceptions.CorruptedZipFileException;
-import de.hftstuttgart.exceptions.NoZipFileException;
-import org.apache.log4j.Logger;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipInputStream;
-
-/**
- * Created by Marcel Bochtler on 13.11.16.
- * Based on: https://www.mkyong.com/java/how-to-decompress-files-from-a-zip-file/
- */
-public class UnzipUtil {
-
- private static final Logger LOG = Logger.getLogger(UnzipUtil.class);
-
- /**
- * Unzips files and saves them to the disk.
- * Checks if the zip file is valid.
- */
- public static List unzip(File zipFile) throws IOException {
-
- String outputFolder = zipFile.getParentFile().getAbsolutePath();
- List unzippedFiles = new ArrayList<>();
-
- byte[] buffer = new byte[1024];
-
- //create output directory is not exists
- File folder = new File(zipFile.getAbsolutePath());
- if (!folder.exists()) {
- folder.mkdir();
- }
-
- try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile))) {
- ZipEntry zipEntry = zipInputStream.getNextEntry();
-
- if (zipEntry == null) {
- String message = "The file " + zipFile.getAbsolutePath() + " does not seem be a zip file";
- LOG.error(message);
- throw new NoZipFileException(message);
- }
-
- while (zipEntry != null) {
- String fileName = zipEntry.getName();
- File unzippedFile = new File(outputFolder + File.separator + fileName);
- LOG.info("Unzipped file: " + unzippedFile.getName());
-
- // create all non exists folders
- // else we will hit FileNotFoundException for compressed folder
- new File(unzippedFile.getParent()).mkdirs();
-
- FileOutputStream fos = new FileOutputStream(unzippedFile);
- int length;
- while ((length = zipInputStream.read(buffer)) > 0) {
- fos.write(buffer, 0, length);
- }
-
- fos.close();
- zipEntry = zipInputStream.getNextEntry();
- unzippedFiles.add(unzippedFile);
- }
-
- if (zipFile.exists()) {
- zipFile.delete();
- }
-
- return unzippedFiles;
-
- } catch (ZipException ze) {
- String msg = "Failed to unzip file " + zipFile;
- LOG.error(msg);
- throw new CorruptedZipFileException(msg);
- }
- }
-}
diff --git a/src/main/resources/application-debug.properties b/src/main/resources/application-debug.properties
new file mode 100644
index 0000000000000000000000000000000000000000..e8812078465dc6cb680d88b0dbd11e2b5f48fa61
--- /dev/null
+++ b/src/main/resources/application-debug.properties
@@ -0,0 +1 @@
+logging.level.de.hftstuttgart=TRACE
diff --git a/src/main/resources/application-server.properties b/src/main/resources/application-server.properties
deleted file mode 100644
index af2743a533622ae0f32d5e7630d37cc3815c9fe5..0000000000000000000000000000000000000000
--- a/src/main/resources/application-server.properties
+++ /dev/null
@@ -1,26 +0,0 @@
-# Multipart settings
-spring.http.multipart.enabled=true
-spring.http.multipart.max-file-size=5Mb
-
-server.port=8081
-
-docker.hostIp=10.40.10.144
-
-jenkins.api.token=dome:1194017120ee74c91ee314e6f796e7b2ae
-jenkins.url=http://${docker.hostIp}:8080/
-
-
-###############################################
-# Modocot properties
-###############################################
-
-# Holds the uploaded Zip-Files
-modocot.dir.parent=/home/modocot
-modocot.dir.assignment.prefix=Assignment_
-modocot.dir.test.folder.name=UnitTests
-
-gitTea.basePath=http://${docker.hostIp}:3000/api/v1
-gitTea.username=giteaUser
-gitTea.password=giteaUser1!
-gitTea.defaultCommitMessage=Commit all changes including additions
-gitTea.defaultOrigin=origin
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index e5b383692fb2a268660505e7a222f6cfccd77594..cdaac83fe6f9f203698163c272547f692dc9473c 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -2,24 +2,12 @@
spring.http.multipart.enabled=true
spring.http.multipart.max-file-size=5Mb
-server.port=8081
-
-docker.hostIp=10.0.2.15
-
-jenkins.api.token=token:114e49fcd53d583f81113697a64d0e7630
-jenkins.url=http://${docker.hostIp}:8080/
-
###############################################
# Modocot properties
###############################################
# Holds the uploaded Zip-Files
-modocot.dir.parent=/home/doom/modocot/
-modocot.dir.assignment.prefix=Assignment_
+modocot.tests.tmp.dir=/tmp/modocot-tests
+host.tests.tmp.dir=${modocot.tests.tmp.dir}
+modocot.dir=/modocot/data
modocot.dir.test.folder.name=UnitTests
-
-gitTea.basePath=http://${docker.hostIp}:3000/api/v1
-gitTea.username=giteaUser
-gitTea.password=giteaUser1!
-gitTea.defaultCommitMessage=Commit all changes including additions
-gitTea.defaultOrigin=origin
diff --git a/src/main/resources/git-credentials.properties b/src/main/resources/git-credentials.properties
deleted file mode 100644
index dc90ad822710b57a06640eabfa12a1da52b55ce4..0000000000000000000000000000000000000000
--- a/src/main/resources/git-credentials.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-modocot.git.username=username
-modocot.git.password=password
\ No newline at end of file
diff --git a/src/main/resources/templates/JenkinsFile.ftl b/src/main/resources/templates/JenkinsFile.ftl
deleted file mode 100644
index 8cb515391afe340e41c287059d21f7149b868764..0000000000000000000000000000000000000000
--- a/src/main/resources/templates/JenkinsFile.ftl
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- Pipeline for User: ${gitUser}
- false
-
-
-
- 2
-
-
- ${gitUrl}
- giteaUser
-
-
-
-
- */master
-
-
- false
-
-
-
- src/Jenkinsfile
- true
-
-
- false
-
\ No newline at end of file
diff --git a/src/main/resources/templates/JenkinsLocalTestFile.ftl b/src/main/resources/templates/JenkinsLocalTestFile.ftl
deleted file mode 100644
index eeda8887750e3aa285259658afe5568994a88176..0000000000000000000000000000000000000000
--- a/src/main/resources/templates/JenkinsLocalTestFile.ftl
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- ${gitUser} ${gitUrl}
- false
-
-
-
-
- true
- false
- false
- false
-
- false
-
-
-
-
\ No newline at end of file
diff --git a/src/test/java/de/hftstuttgart/rest/v1/unittest/IntegrationTest.java b/src/test/java/de/hftstuttgart/rest/v1/unittest/IntegrationTest.java
deleted file mode 100644
index 56da99873df9e25971747c5edaa2a265f099001d..0000000000000000000000000000000000000000
--- a/src/test/java/de/hftstuttgart/rest/v1/unittest/IntegrationTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package de.hftstuttgart.rest.v1.unittest;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.mock.web.MockMultipartFile;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import org.springframework.web.context.WebApplicationContext;
-
-import java.io.File;
-import java.io.FileInputStream;
-
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
-public class IntegrationTest {
-
- @Autowired
- private WebApplicationContext webApplicationContext;
-
- MockMvc mockMvc;
-
- @Before
- public void setup() throws Exception {
- mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
- }
-
- @Test
- @Ignore
- public void validUnitTestFileTest() throws Exception {
-
- // Upload tests
- File unitTestFile = new File(Thread.currentThread().getContextClassLoader().getResource("tests.zip").getFile());
- MockMultipartFile testFileMock = new MockMultipartFile("unitTestFile", new FileInputStream(unitTestFile));
- mockMvc.perform(MockMvcRequestBuilders.fileUpload("/v1/unittest")
- .file(testFileMock)
- .param("assignmentId", "111"))
- .andExpect(status().is(200));
-
- // Upload tasks
- File taskFile = new File(Thread.currentThread().getContextClassLoader().getResource("tasks.zip").getFile());
- MockMultipartFile taskFileMock = new MockMultipartFile("taskFile", new FileInputStream(taskFile));
- mockMvc.perform(MockMvcRequestBuilders.fileUpload("/v1/task")
- .file(taskFileMock)
- .param("assignmentId", "111"))
- .andExpect(status().is(200))
- .andExpect(content().string(("{\n" +
- " \"testResults\" : [ {\n" +
- " \"testName\" : \"CalculatorTest\",\n" +
- " \"testCount\" : 5,\n" +
- " \"failureCount\" : 0,\n" +
- " \"successfulTests\" : [ \"add\", \"div\", \"sub\", \"sum\", \"mult\" ],\n" +
- " \"testFailures\" : [ ]\n" +
- " } ],\n" +
- " \"compilationErrors\" : [ ]\n" +
- "}")
- .replaceAll("\\n|\\r\\n", System.getProperty("line.separator"))));
- }
-
- @Test
- @Ignore
- public void corruptedZipTest() throws Exception {
-
- File file = new File(Thread.currentThread().getContextClassLoader().getResource("corrupted.zip").getFile());
- MockMultipartFile mockFile = new MockMultipartFile("unitTestFile", new FileInputStream(file));
-
- mockMvc.perform(MockMvcRequestBuilders.fileUpload("/v1/unittest")
- .file(mockFile)
- .param("assignmentId", "222"))
- .andExpect(status().is(400));
- }
-
- @Test
- @Ignore
- public void renamedTxtFileTest() throws Exception {
-
- File file = new File(Thread.currentThread().getContextClassLoader().getResource("textfile.zip").getFile());
- MockMultipartFile mockFile = new MockMultipartFile("unitTestFile", new FileInputStream(file));
-
- mockMvc.perform(MockMvcRequestBuilders.fileUpload("/v1/unittest")
- .file(mockFile)
- .param("assignmentId", "333"))
- .andExpect(status().is(400));
-
- }
-
- @Test
- @Ignore
- public void noAssignmentIdTest() throws Exception {
-
- File file = new File(Thread.currentThread().getContextClassLoader().getResource("textfile.zip").getFile());
- MockMultipartFile mockFile = new MockMultipartFile("unitTestFile", new FileInputStream(file));
-
- mockMvc.perform(MockMvcRequestBuilders.fileUpload("/v1/unittest")
- .file(mockFile))
- .andExpect(status().is(400));
-
- }
-
-}
diff --git a/src/test/resources/corrupted.zip b/src/test/resources/corrupted.zip
deleted file mode 100644
index c1a3499985e71dca75b4ff39881101774c0962e9..0000000000000000000000000000000000000000
Binary files a/src/test/resources/corrupted.zip and /dev/null differ
diff --git a/src/test/resources/tasks.zip b/src/test/resources/tasks.zip
deleted file mode 100644
index 8010049bbfecb50ab67c3a5cea8cec4b938b380a..0000000000000000000000000000000000000000
Binary files a/src/test/resources/tasks.zip and /dev/null differ
diff --git a/src/test/resources/tests.zip b/src/test/resources/tests.zip
deleted file mode 100644
index f3690a0624e6aafb6e5dc0bdbf96fe838763ac7d..0000000000000000000000000000000000000000
Binary files a/src/test/resources/tests.zip and /dev/null differ
diff --git a/src/test/resources/textfile.zip b/src/test/resources/textfile.zip
deleted file mode 100644
index bc2a4803bf412abea5ca4d88e63bf94ff0598abe..0000000000000000000000000000000000000000
--- a/src/test/resources/textfile.zip
+++ /dev/null
@@ -1,3 +0,0 @@
-
-asdfsadfasdf
-asdfasdfsadf