Verified Commit ec98dda0 authored by Jan-Eric Ortgies's avatar Jan-Eric Ortgies
Browse files

add Projektbericht tex

parent ad74190b
tmp/
.idea/
doc/
\ No newline at end of file
doc/
## Core latex/pdflatex auxiliary files:
*.aux
*.lof
*.log
*.lot
*.fls
*.out
*.toc
*.fmt
*.fot
*.cb
*.cb2
## Intermediate documents:
*.dvi
*-converted-to.*
# these rules might exclude image files for figures etc.
# *.ps
# *.eps
# *.pdf
## Generated if empty string is given at "Please type another file name for output:"
tfa.pdf
## Bibliography auxiliary files (bibtex/biblatex/biber):
*.bbl
*.bcf
*.blg
*-blx.aux
*-blx.bib
*.brf
*.run.xml
## Build tool auxiliary files:
*.fdb_latexmk
*.synctex
*.synctex(busy)
*.synctex.gz
*.synctex.gz(busy)
*.pdfsync
## Auxiliary and intermediate files from other packages:
# algorithms
*.alg
*.loa
# achemso
acs-*.bib
# amsthm
*.thm
# beamer
*.nav
*.pre
*.snm
*.vrb
# cprotect
*.cpt
# endnotes
*.ent
# fixme
*.lox
# feynmf/feynmp
*.mf
*.mp
*.t[1-9]
*.t[1-9][0-9]
*.tfm
*.[1-9]
*.[1-9][0-9]
#(r)(e)ledmac/(r)(e)ledpar
*.end
*.?end
*.[1-9]
*.[1-9][0-9]
*.[1-9][0-9][0-9]
*.[1-9]R
*.[1-9][0-9]R
*.[1-9][0-9][0-9]R
*.eledsec[1-9]
*.eledsec[1-9]R
*.eledsec[1-9][0-9]
*.eledsec[1-9][0-9]R
*.eledsec[1-9][0-9][0-9]
*.eledsec[1-9][0-9][0-9]R
# glossaries
*.acn
*.acr
*.glg
*.glo
*.gls
*.glsdefs
# gnuplottex
*-gnuplottex-*
# gregoriotex
*.gaux
*.gtex
# hyperref
*.brf
# knitr
*-concordance.tex
# TODO Comment the next line if you want to keep your tikz graphics files
*.tikz
*-tikzDictionary
# listings
*.lol
# makeidx
*.idx
*.ilg
*.ind
*.ist
# minitoc
*.maf
*.mlf
*.mlt
*.mtc[0-9]*
# minted
_minted*
*.pyg
# morewrites
*.mw
# mylatexformat
*.fmt
# nomencl
*.nlo
# sagetex
*.sagetex.sage
*.sagetex.py
*.sagetex.scmd
# scrwfile
*.wrt
# sympy
*.sout
*.sympy
sympy-plots-for-*.tex/
# pdfcomment
*.upa
*.upb
# pythontex
*.pytxcode
pythontex-files-*/
# thmtools
*.loe
# TikZ & PGF
*.dpth
*.md5
*.auxlock
# todonotes
*.tdo
# easy-todo
*.lod
# xindy
*.xdy
# xypic precompiled matrices
*.xyc
# endfloat
*.ttt
*.fff
# Latexian
TSWLatexianTemp*
## Editors:
# WinEdt
*.bak
*.sav
# Texpad
.texpadtmp
# Kile
*.backup
# KBibTeX
*~[0-9]*
# auto folder when using emacs and auctex
/auto/*
# expex forward references with \gathertags
*-tags.tex
.DS_Store
\documentclass[
a4paper,
12pt,
plainfootsepline,
headinclude,
headsepline,
numbers=noenddot,
%openany,
% TODO: Find not deprecated alternatives
BCOR=12mm,
DIV=17,
oneside,
% NOTE: Works only if tocloft is not in use
bibliography=totoc,
listof=totoc
]{scrartcl}
%
% DEFAULT CONFIG
%
\input{lib/packages}
\input{lib/person-configuration}
\input{lib/colors}
\input{lib/page-configuration}
%
% ADDITIONAL PACKAGES
%
\usepackage{amsmath}
\usepackage{blindtext}
%
% REAL DOCUMENT
%
\begin{document}
\input{abschnitte/deckblatt}
\newpage
\begin{spacing}{1.0}
\pagenumbering{Roman}
\setcounter{page}{1}
\tableofcontents
\newpage
\addcontentsline{toc}{section}{Abbildungsverzeichnis}
\listoffigures
\newpage
%\addcontentsline{toc}{section}{Tabellenverzeichnis}
%\listoftables
%\newpage
%\addcontentsline{toc}{section}{Listings}
\lstlistoflistings
\newpage
\end{spacing}
\pagenumbering{arabic}
\setcounter{page}{1}
\input{abschnitte/kapitel/01_einleitung.tex}
\newpage
\input{abschnitte/kapitel/02_anforderungen.tex}
\newpage
\input{abschnitte/kapitel/03_design.tex}
\newpage
%\begin{spacing}{1.0}
% \renewcommand\refname{Literaturverzeichnis}
% \bibliographystyle{apacite}
% \bibliography{bib/lib}
%\end{spacing}
%\newpage
\appendix
\newpage
\input{abschnitte/erklaerung}
\newpage
\end{document}
\ No newline at end of file
\begin{titlepage}
\begin{figure}[h]
\hspace{2mm}\textcolor{white}{\sYear}
\flushright
\vspace{-2cm}\includegraphics[scale=0.4]{bilder/hs-logo.png}\hspace{-1.5cm}
%\cite{hsbrhv}
\includepdf{bilder/deckblatt.pdf}
\end{figure}
\vspace*{1.0in}
\hspace*{-1.3in}
\parbox[t]{1.0\paperwidth}{
\centering
\vspace*{1.5in}
\centering
\huge{\textsc{\sTitle}} \\
\vspace*{0.2cm}
\large{\sSubtitle}
}
\doublespacing{
\vfill{
\begin{tabular}{ll}
Vorgelegt von: & \slongName \\
Professor: & \sProf \\
Modul: & \sModul \\
%Wortanzahl: & \#\#\#WORTANZAHL\#\#\# \\
Abgabe am: & \sDeadline
\end{tabular}
}
}
\end{titlepage}
\section*{Erklärung}
%\addcontentsline{toc}{section}{Erklärung}
\thispagestyle{scrheadings}
\clearscrheadfoot
\setheadsepline{0pt}
\setfootsepline{0pt}
\cfoot{}
Hiermit versichere ich, dass die vorliegende Arbeit selbstständig verfasst und keine anderen als die angegebenen Quellen und
Hilfsmittel benutzt wurden. Alle Passagen, die wörtlich oder sinngemäß aus anderen Quellen stammen, wurden als solche
kenntlich gemacht.\\\\
\sName
\bigskip
Bremerhaven, \today \qquad
\ No newline at end of file
\section{Einleitung}
Dieses Dokument beschreibt die im Rahmen des Moduls \qq{Grundlagen der Systemintegration} erstellte Anwendung. \\
Diese Anwendung ensteht zusammen mit einer Java-Anwendung für \qq{Software Engineering 3}, und bildet das Backend der beiden Systeme. Im weiteren werden die Schnittstellen zwischen den beiden Anwendung beschrieben, sowie die generelle Funktionsweise der Software dokumentiert.
\subsection{Übersicht}
In diesem Projekt soll eine Anwendung erstellt werden, welche das Ausführen von Code für die Frontend Anwendung von SWE3 ermöglicht. Hierbei soll beliebiger Java-Code an die von der Anwendung bereitgestellte Schnittstelle geliefert werden, welche dann mit dem Ergebnis beantwortet werden soll.
\begin{figure}[H]
\begin{center}
\includegraphics[width=0.8\textwidth]{bilder/uebersicht.png}
\end{center}
\caption{Übersicht der beiden Projektteile}
\label{img:uebersicht}
\end{figure}
Geplant sind diese Bestandteile (siehe \autoref{img:uebersicht}):
\begin{itemize}
\item Frontend: Java-Anwendung welche im Rahmen von \qq{Software Engineering 3} erstellt wird
\item Backend: go-Anwendung welche im Rahmen von \qq{Grundlagen der Systemintegration} erstellt wird
\end{itemize}
\subsubsection*{Abgrenzung zu SWE3}
Wie in \autoref{img:uebersicht} zu sehen, besteht die komplette Anwendung aus zwei Teilen. Diese Dokumentation beschreibt hauptsächlich den Bereich der go-Anwendung für das Modul \qq{Grundlagen der Systemintegration}, wie er in der rechten Seite von \autoref{img:uebersicht} zu sehen ist.
\ No newline at end of file
\section{Anforderungen}
\subsection{Externe Schnittstellen}
Die Software soll eine REST-Schnittstelle bereitstellen, welche dann von der Java-Anwendung angesprochen werden kann. Hierbei soll die Kommunikation per JSON erfolgen. \\
Die folgenden Informationen werden vom Java-Frontend übergeben:
\begin{itemize}
\item Programmiersprache
\item Quellcode des Benutzers
\item Quellcode der vorgegebenen Lösung
\item eventuelle Testeingaben (wenn vorhanden)
\end{itemize}
Diese Informationen sollen verarbeiten und dann in einem angemessenen Format wieder zurückgegeben werden. Da wir nicht erwarten dass die Ausführungszeit der übergebenen Quellcodes mehrere Minuten betragen wird, kann die Anfrage sowie das Beantworten in der gleichen Abfrage geschehen. Es wird hierbei eine geringere Komplexität erwartet, da das Frontend direkt eine Antwort bekommt und keine Daten im Backend vorgehalten werden müssen, was eine Datenbank somit nicht erforderlich macht.
\subsection{Features}
Es werden folgende Anforderungen an die Features der Software gestellt:
\begin{itemize}
\item Kompilieren/Ausführen des übermittelten Quellcodes\\
Der übermittelte Quellcode soll kompiliert und ausgeführt werden, im Falle einer Fehlermeldung soll diese zurückgegeben werden. Dies soll mit Hilfe von Docker geschehen. Hierbei muss nicht zwischen Fehler beim Kompilieren und Laufzeitfehler unterschieden werden.
\item Ausführen von Lösungen zum Vergleich\\
Um den Quellcode des Nutzers auf Richtigkeit prüfen zu können, soll der bereitgestellte Lösungsquellcode ausgeführt werden, welcher dann mit dem Quellcode des Nutzers verglichen wird.
\item Eingabe von Testwerten\\
Es soll möglich sein, bestimmte Testwerte festzulegen welche dann dem Programm übergeben werden. Hierbei sind Testwerte gemeint, welche in das stdin des Programms eingegeben werden sollen.
\item Ausgabe von Statistiken\\
Es sollen Statistiken zum ausgeführten Quellcode erfasst werden. Hierbei wird sich vorerst auf das Erfassen der Laufzeit des Programms beschränkt.
\end{itemize}
\subsection{Attribute}
Es werden folgende Anforderungen an die Attribute der Software gestellt:
\begin{itemize}
\item Zuverlässigkeit\\
Eventuelle Fehler beim kompilieren oder Ausführen des Nutzerquellcodes sollen abgefangen werden und nicht zum Absturz der Anwendung führen.
\item Verfügbarkeit\\
Es soll möglich sein die Anwendung auf mehreren Servern bereitstellen zu können, um die Verfügbarkeit zu steigern. Hierbei soll auf den Einsatz von Datenbanken geachtet werden, welche eine zustandslose Ausführung der Anwendung schwieriger machen.
\item Sicherheit\\
Da hier Nutzerquellcode ausgeführt wird, soll auf die Sicherheit der Anwendung besonders geachtet werden. Der Quellcode soll nur in nicht privilegierten Containern ausgeführt werden, um mögliche Angriffsvektoren zu verringern.
\item Wartbarkeit\\
Der geschrieben Quellcode soll gut dokumentiert und erweiterbar sein.
\item Portabilität\\
Der Quellcode sollte möglichst Plattformunabhängig programmiert sein, um einfache Portabilität zu gewährleisten.
\item Effizienz\\
Die Anwendung sollte die ausgeführten Funktionen parallelisieren, sofern dies möglich ist.
\end{itemize}
\ No newline at end of file
\section{Design der Systemarchitektur}
\subsection{Ausgewählte Architektur}
\subsubsection{Ausführung per Docker}
\label{sec:docker}
\begin{figure}[H]
\begin{center}
\includegraphics[width=0.8\textwidth]{bilder/docker.png}
\end{center}
\caption{Ausführung per Docker}
\label{img:docker}
\end{figure}
Wie in \autoref{img:docker} beschrieben, werden mehrere Stufen durchlaufen. Im folgenden werden diese beschrieben. Mit Hilfe sogenannter go-Routinen wird es möglich die folgenden Anweisungen jeweils für Nutzerquellcode und Lösungsquellcode nebenläufig auszuführen.
\begin{itemize}
\item docker create\\
Anfangs wird ein Container mit einer eindeutigen ID erstellt, jeweils für den Quellcode des Nutzers sowie der Lösung.
\item docker cp\\
Vor dem Aufruf dieser Funktion wird eine temporäre Datei mit dem Quellcode angelegt, welche dann durch \textit{docker cp} in den jeweiligen Container kopiert wird.
\item docker start\\
Um den Code mit \textit{docker exec} ausführen zu können, wird der Container gestartet.
\item docker exec (compile)\\
Im ersten Schritt wird der jeweilige Quellcode kompiliert, falls ein Fehler auftritt wird abgebrochen und die Fehlermeldung zurückgegeben.
\item docker exec (run code)\\
Im nächsten Schritt wird pro Testfall der Quellcode ausgeführt. Sollte es keine Testfälle geben, wird der Quellcode ohne Eingabe von Testfällen ausgeführt. Bei Laufzeitfehlern wird die Fehlermeldung zurückgegeben, ansonsten die Ausgabe des Programms.
\item docker rm\\
Im letzten Schritt wird der Container entfernt, da dieser nicht mehr benötigt wird.
\end{itemize}
Sobald diese Schritte durchlaufen wurden, wird der entsprechende Response-Struct wie in \autoref{lst:response} zu sehen zusammengebaut und dann als JSON-Antwort zum Java-Frontend zurückgeschickt.
\subsubsection{Konfigurationsdatei}
\label{sec:config}
Um die einfache Erweiterbarkeit der Anwendung zu gewährleisten, wurde sich dazu entschieden, eine Konfigurationsdatei anzulegen. Hierbei wurde das yaml-Format gewählt, da dieses leicht auch für Menschen lesbar ist. Im folgenden ist eine beispielhafte Konfigurationsdatei zu sehen.
\begin{lstlisting}[caption={Beispielhafte config.yml}, language=yaml, captionpos=t, label=lst:configyml]
---
languages:
- name: java
container_name: hsbcc-java
dockerfile: Dockerfile.java
filename: Main.java
exec_command: java Main
requires_compilation: true
compile_command: javac Main.java
- name: clang
container_name: hsbcc-clang
dockerfile: Dockerfile.clang
filename: main.c
exec_command: ./main
requires_compilation: true
compile_command: gcc -o main main.c
\end{lstlisting}
Hier wird zuerst ein Name für den Docker-Container festgelegt. Dann wird angegeben wo die Dockerfiles abgelegt sind, sowie ob die Sprache kompiliert werden muss und wie der Kompiliervorgang ausgeführt werden soll. Außerdem wird der Dateiname sowie ein Kommando angegeben, mit dem der kompilierte Quellcode ausgeführt werden kann.\\
Dadurch dass diese Einstellungen in eine Konfigurationsdatei ausgelagert werden, ist es sehr einfach möglich die Anwendung auf andere Sprachen zu erweitern. So konnte testweise das Ausführen von Javascript Code mit Hilfe eines nodejs Containers möglich gemacht werden, indem nur die Konfigurationsdatei bearbeitet wurde, ohne weitere Modifikationen an der Anwendung vorzunehmen.
\subsubsection{Strukturen}
\textbf{Konfigurationsdatei}
\begin{lstlisting}[caption={Config struct}, language=yaml, captionpos=t, label=lst:config]
type Config struct {
Languages []Language `yaml:"languages"`
}
\end{lstlisting}
\begin{lstlisting}[caption={Language struct}, language=yaml, captionpos=t, label=lst:language]
type Language struct {
Name string `yaml:"name"`
ContainerName string `yaml:"container_name"`
Dockerfile string `yaml:"dockerfile"`
Filename string `yaml:"filename"`
ExecCommand string `yaml:"exec_command"`
RequiresCompilation bool `yaml:"requires_compilation"`
CompileCommand string `yaml:"compile_command"`
}
\end{lstlisting}
Wie in \autoref{sec:config} beschrieben, wurden Einstellungen in einer Konfigurationsdatei festgelegt. Diese kann dann mit Hilfe eines yaml-Decoders als go-Struct eingelesen werden. Im folgenden die beiden Structs die verwendet wurden.\\
Wie bereits in \autoref{sec:config} zu sehen, ist es möglich mehrere Sprachen zu definieren. Dies wird mit dem Config struct in \autoref{lst:config} erreicht, welches ein Array von Language-Structs beinhaltet. Dieses Struct enthält dann wieder Einstellungen für eine Sprache wie in \autoref{lst:language} definiert.\\
\textbf{Status}
\begin{lstlisting}[caption={Status struct}, language=yaml, captionpos=t, label=lst:status]
type Status struct {
Running bool `json:"running"`
SetupDone bool `json:"setup_done"`
}
\end{lstlisting}
Der Status-Struct enthält zwei Variablen, welche Informationen über den Status der Anwendung enthalten. Dieser wird, wie später in \autoref{sec:api} beschrieben, für das bereitstellen dieser Statusinformation für die Schnittstelle benötigt.\\
\textbf{Message}
\begin{lstlisting}[caption={Message struct}, language=yaml, captionpos=t, label=lst:message]
type Message struct {
Language string `json:"language"`
SolutionCode string `json:"solutionCode"`
UserCode string `json:"userCode"`
TestInputs []string `json:"testInputs"`
}
\end{lstlisting}
Dieser Struct beinhaltet die per JSON empfangenen Daten vom Frontend. Hierbei wird zusätzlich zu der Sprache, wie sie in der Konfigurationsdatei definiert wurde, Quellcode vom Benutzer und von der Lösung übergeben. Falls Testeingaben vorhanden sind, werden diese ebenfalls übergeben.\\
\textbf{Response}
\begin{lstlisting}[caption={Response struct}, language=yaml, captionpos=t, label=lst:response]
type Response struct {
UUID string `json:"uuid"`
IsCorrect bool `json:"is_correct"`
AverageExecutionTime int64 `json:"average_execution_time"`
ErrorMessage string `json:"error_message"`
SolutionTests []Test `json:"solution_tests"`
SolutionResult string `json:"solution_result"`
UserTests []Test `json:"user_tests"`
UserResult string `json:"user_result"`
}
\end{lstlisting}
Der Response-Struct enthält die Antwort für das Frontend und wird erstellt nachdem der Quellcode vom Benutzer sowie der Lösung durchlaufen ist. Hierbei wird dem Ergebnis eine feste ID zugewiesen, welche sich im UUIDv4 Format befindet. Neben Angabe der Korrektheit des Quellcodes des Nutzers, wird auch eine Ausführungszeit angegeben. Für den Fall das mehrere Testfälle definiert wurden, wird die durchschnittliche Ausführungszeit aller Testfälle berechnet.\\
Die Fehlermeldung enthält entweder eine Meldung des Compilers, oder wenn vorhanden die Ausgabe bei einem Laufzeitfehler. Für jeden Testfall gibt es einen weiteren Struct, der weiter unten erklärt wird. Hier werden für Lösungsquellcode sowie Nutzerquellcode jeweils ein Array an Tests angegeben, welche als kombinierte Ausgabe im Result-String vorliegen.\\
\textbf{Test}
\begin{lstlisting}[caption={Test struct}, language=yaml, captionpos=t, label=lst:test]
type Test struct {
Id int `json:"id"`
Success bool `json:"success"`
Output string `json:"output"`
ExecutionTime time.Duration `json:"execution_time"`
}
\end{lstlisting}
In diesem Struct wird das Ergebnis ausgeführter Tests festgehalten. Hierbei gibt es eine Test-ID, einen boolean welcher den Erfolg festlegt, sowie die Ausgabe des Tests und die Ausführungszeit. Die Testausgabe enthält bei einem Fehler die Fehlermeldung des Compilers bzw. eventuelle Laufzeitfehler.
\subsubsection{API-Schnittstelle}
\label{sec:api}
Die externe API besteht aus drei Endpunkten, welche im folgenden beschrieben werden.\\
\textbf{\qq{status}-Endpunkt}\\
Dieser Endpunkt nutzt den in \autoref{lst:status} beschrieben Struct, um den Status der Anwendung anzuzeigen.\\
\textbf{\qq{run}-Endpunkt}\\
Der \qq{run}-Endpunkt bekommt per POST-Request die Daten, welche in \autoref{lst:message} definiert sind. Daraufhin werden die in \autoref{sec:docker} beschriebenen Funktionen ausgeführt und in das Response-Struct, wie in \autoref{lst:response} beschrieben, verwandelt und im JSON-Format zurückgeschickt.\\
\textbf{\qq{results}-Endpunkt}\\
Dieser Endpunkt gibt das Ergebnis der Ausführung wie in \autoref{lst:response} beschrieben zurück.
\subsection{Alternative Designs}
Als Alternative zum gewählten Design wie in \autoref{img:docker} zu sehen, gab es noch andere Einfälle. In den ersten Iterationen der Anwendung wurde noch auf den Einsatz von \textit{docker cp} verzichtet. Dabei wurde der Quellcode mit Hilfe des \qq{v}-Flags von \textit{docker exec} in den Container gemountet. Hierbei ergab sich allerdings das Problem, dass das erstellen sowie mounten der temporären Dateien nicht problemlos und Plattformübergreifend möglich war.\\\\
Ein weiteres Problem ergab sich mit dem Kompilieren des Quellcodes. Anfangs wurde dieser schon bei Ausführen des Containers kompiliert, wofür der \textit{compile\_command} wie in \autoref{lst:language} zu sehen in dem entsprechenden Dockerfile stehen musste. Dabei kam es bei fehlerhaftem Quellcode, welcher einen Compilerfehler erzeugt hat, teilweise zu Problemen mit dem Auffangen der Fehlermeldung des Compilers. Der Fehler wurde zwar korrekt erkannt, allerdings war es nicht möglich auf die im \textit{stderr}-Kanal ausgegebene Fehlermeldung des Compilers zuzugreifen.
\ No newline at end of file
\tableofcontents
\ No newline at end of file
% Encoding: UTF-8
% combine multiple authors using "and", if the author is an organisation use {{Some Author}}
@WWW{bargeld,
title = {Das Bargeld},
author = {{Deutsche Bundesbank}},
publisher = {Deutsche Bundesbank},
note = {Abgerufen am 22.02.2019},
url = {https://www.bundesbank.de/de/service/schule-und-bildung/schuelerbuch-geld-und-geldpolitik-digital/das-bargeld-613762},
}
@WWW{ueberweisung,
title = {Überweisung},
author = {{Deutsche Bundesbank}},
publisher = {Deutsche Bundesbank},
note = {Abgerufen am 27.02.2019, aus dem Glossar der Deutschen Bundesbank},
url = {https://www.bundesbank.de/de/startseite/glossar},
}
@WWW{bargeldlos,
author = {Jochen Metzger},
title = {Bargeldloser Zahlungsverkehr},
note = {Abgerufen am 22.02.2019},
year = {2018},
month = {02},
day = {19},
publisher = {Gabler Wirtschaftslexikon},
url = {https://wirtschaftslexikon.gabler.de/definition/bargeldloser-zahlungsverkehr-28136/version-251773},
}
@WWW{digitaleWaerung,
author = {Jochen Metzger},
title = {Virtuelle Währung},
note = {Abgerufen am 22.02.2019},
year = {2018},
month = {02},
day = {19},
publisher = {Gabler Wirtschaftslexikon},
url = {https://wirtschaftslexikon.gabler.de/definition/virtuelle-waehrung-54174/version-277228},
}
@WWW{barzahlung,
author = {Jochen Metzger and Dr. Dr. Jörg Berwanger},
title = {Barzahlung},
note = {Abgerufen am 27.02.2019},
year = {2018},
month = {02},
day = {19},
publisher = {Gabler Wirtschaftslexikon},
url = {https://wirtschaftslexikon.gabler.de/definition/barzahlung-27655/version-251300},
}