Artemis: Interactive Learning with Individual Feedback¶
Main features¶
Artemis supports the following exercises:
Programming exercises with version control and automatic assessment with test cases and continuous integration
Quiz exercises with multiple choice, drag and drop and short answer quiz questions
Modeling exercises with semi-automatic assessment using machine learning concepts
Textual exercises with manual (and experimental semi-automatic) assessment
File upload exercises with manual assessment
All these exercises are supposed to be run either live in the lecture with instant feedback or as homework. Students can submit their solutions multiple times within the due date and use the (semi-)automatically provided feedback to improve their solution.
Introduction¶
Exercises¶
Artemis supports the following exercises:
Programming Exercise¶
Conducting a programming exercise consists of 7 steps distributed among instructor, Artemis and students:
Instructor prepares exercise: Set up a repository containing the exercise code and test cases, build instructions on the CI server, and configures the exercise in Artemis.
Student starts exercise: Click on start exercise on Artemis which automatically generates a copy of the repository with the exercise code and configures a build plan accordingly.
Optional: Student clones repository: Clone the personalized repository from the remote VCS to the local machine.
Student solves exercise: Solve the exercise with an IDE of choice on the local computer or in the online editor.
Student uploads solution: Upload changes of the source code to the VCS by committing and pushing them to the remote server (or by clicking submit in the online editor).
CI server verifies solution: verify the student’s submission by executing the test cases (see step 1) and provide feedback which parts are correct or wrong.
Student reviews personal result: Reviews build result and feedback using Artemis. In case of a failed build, reattempt to solve the exercise (step 4).
Instructor reviews course results: Review overall results of all students, and react to common errors and problems.
The following activity diagram shows this exercise workflow.

Exercise Workflow¶
Tutorial: Create Programming Exercises
Online Editor¶
The following screenshot shows the online code editor with interactive and dynamic exercise instructions on the right side. Tasks and UML diagram elements are referenced by test cases and update their color from red to green after students submit a new version and all test cases associated with a task or diagram element pass. This allows the students to immediately recognize which tasks are already fulfilled and is particularly helpful for programming beginners.

Online Editor¶
Testing with Artemis Java Test Sandbox¶
Artemis Java Test Sandbox (abbr. AJTS) is a JUnit 5 extension for easy and secure Java testing on Artemis.
Its main features are
a security manager to prevent students crashing the tests or cheating
more robust tests and builds due to limits on time, threads and io
support for public and hidden Artemis tests, where hidden ones obey a custom deadline
utilities for improved feedback in Artemis like processing multiline error messages or pointing to a possible location that caused an Exception
utilities to test exercises using System.out and System.in comfortably
For more information see https://github.com/ls1intum/artemis-java-test-sandbox
Using adapters to support multiple VCS¶
The following UML component diagram shows the details of the Version Control Adapter that allows to connect to multiple Version Control Systems. The other adapters for Continuous Integration and User Management have a similar structure

Version Control Adapter¶
The Version Control Adapter includes abstract interface definitions. Among others, concrete connectors have to implement the following methods:
+ copyRepository(baseRepository, user)
+ configureRepository(repository, user)
+ deleteRepository(repository)
+ getRepositoryWebUrl(repository)
+ ...
The Continuous Integration Adapter includes abstract interface definitions. Among others, concrete connectors have to implement the following methods:
+ copyBuildPlan(baseBuildPlan, user)
+ configureBuildPlan(buildPlan, repository, user)
+ deleteBuildPlan(buildPlan)
+ onBuildCompleted(buildPlan)
+ getBuildStatus(buildPlan)
+ getBuildDetails(buildPlan)
+ ...
Quiz exercise¶
Modeling exercise¶
Textual exercise¶
File upload exercise¶
Exam Mode¶
Artemis now includes an online exam mode:
Instructors’ Guide¶
Content of this document
Timeline of an Artemis Online Exam¶
1. Creation and Configuration¶
During the exam creation and configuration, you can create your exam and configure it to fit your needs. Add exercises with different variants, register students, generate student exams and conduct test runs. For more information see 1.2 Create and Configure Exam.
Log in to Artemis with your account credentials.
Click on
.
Click on
for your course. It will open the Exam Management Screen.
Here you have access to all the exams of your course. All aspects of the exam are managed from the management screen.
You can create an exam by clicking on
.
When you click on
you are presented with the Create Exam view. Here you can set the basic information such as
title
,examiner
etc. The timeline of the exam is defined by the dates:visible from
,start of working time
,end of working time
,release date of results
,begin of student review
,end of student review
.The first three dates are mandatory when you create an exam. The rest can be set when required.
The
grace period
defines the amount of time the students have at their disposal to hand in their exam after theworking time
is over. This is set to 3 minutes by default.You can also define the
number of exercises
in the exam. You can leave this out initally, however it must be set before you can generate the student exams. For more information, see 1.3 Exercise Groups.Artemis will randomize the order of the exercises for each student if you activate
randomize order of exercise groups
.Finally, you can fill out the exam
start text
andend text
. Artemis will present these texts to the students during the exam conduction, at the Start- and End page respectively.
Artemis exam mode allows you to define multiple exercise variants so that each student can receive a unique exam. Artemis achieves this through exercise groups. Exercise groups represent an individual exercise slot for each student exam. Within one exercise group you can define different exercises.
Artemis selects one exercise per exercise group randomly, to generate the individual student exams.
You can distinguish between mandatory exercise groups and non-mandatory exercise groups.
Artemis always includes mandatory exercise groups in the individual exam of a student.
non-mandatory exercise groups can be left out, if there are more exercise groups than the
number of exercises
defined in the exam configuration.By default, every exercise group is mandatory. You can set the
mandetory
flag when you add an exercise group initially, or later by clickingon the exercise group.

Exercise Groups with different Exercise Variants¶
Exercise groups can contain multiple exercises. For every student exam, Artemis will randomly select one exercise per exercise group.
Note
If you want all student to have the same exam, define only one exercise per exercise group.
To add exercises navigate to the Exercise Groups of the exam. On the header of each exercise group you will find the available exercise types. You can choose between
creating a new exercise
orimporting an existing one
from your courses.

Add different Exercises¶
For exercise types
text
,programming
, andmodeling
you can also define example submissions and example assessments to guide your assessor team.Assessors will review the example submissions and assessments in order to familiarise themselves with the exercise and assessment instructions, before they can assess the real submissions.
1.4.1 Programming Exercises
Programming exercises have multiple special options to adjust their behaviour:
You can check the option to
allow manual assessment
.Note
If you do not set this flag, your assessors will not be able to manually assess the student’s submissions during the assessment process.
You can activate
Run Tests once after Due Date
. This will compile and run the test suite on all the student submissions once after the set date.After you add a programming exercise you can configure the grading via
.
In the Configure Grading screen, you can tweak the
weight
of the tests, thebonus multiplier
and add,bonus points
.You can hide tests so that they are not executed during the exam conduction. Students can not receive feedback from hidden tests during the exam conduction.
Note
If you hide all tests, the students will only be able to see if their submission compiles during the conduction. Set the due date after the exam end date to achieve this effect.
![]()
Configure the Grading of a Programming Exercise¶
To register students to the exam, navigate from the exam management to the Students page. Artemis offers two options to register students. You can:
Add students manually my searching via the search bar.
Bulk import students using a
CSV
file. You can do this by pressing theImport students
button.
Note
Just registering the students to the exam will not allow them to participate in the exam. First, individual student exams must be generated.
You can also remove students from the exam. When you do so, you have the option to also delete their participations and submissions linked to the user’s student exam.

Register Students Page¶
Student exams represent the exam of a student. It consists of an individual set of exercises based on the configured exercise groups.
Student exams are managed via the Student Exams page.
Here you can have an overview of all student exams. When you press
View
on a student exam, you can view thedetails of the student
, the allocatedworking time
, his/herparticipation status
, theirsummary
, as well as theirscores
. Additionally, you will also be able to view which assessor is responsible for each exercise.Note
You can change the individual working time of students from here.
To generate student exams you must click on
. This will trigger Artemis to create a student exam for every registered user.
Artemis determines the number of exercises from the exam configuration and randomly selects one exercise per exercise group.
Note
button will be locked once the exam becomes visible to the students. You cannot perform changes to student exams once the exam conduction has started.
If you have added more students recently, you can choose to
.
creates a participation for each exercise for every registered user, based on their assigned exercises. It also creates the individual repositories and build plans for programming exercises. This action can take a while if there are many registered students due to the communication between the version control (VC) and continuous integration (CI) server.
Warning
You must trigger
before the exam conduction begins.
On the Student Exams page, you can also maintain the repositories of student exams. This functionality only affects programming exercises. You can choose to
and
all student repositories.
Note
Artemis locks and unlocks the student repositories automatically based on the individual exam start and end date. These buttons are typically not necessary unless something went wrong.
Additionally, once the exam conduction ends, you can click on
. This action will evaluate all student exam submissions for all quiz exercises and assign an automatic result.
Note
If you do not press this button, the students quiz exercises will not be graded.

Student Exam Page¶

Test Run Management¶
Test runs are designed to offer the instructors confidence that the exam conduction will run smoothly. They allow you to experience the exam from the student’s perspective. A test run is distinct from a student exam and is not taken into consideration during the calculation of the exam scores.
You can manage your test runs from the Test Run page.
To create a new test run you can press
. This will open a popup where you can select an exercise for each exercise group. You can also set the
working time
. A test run will have as many exercises as there are exercise groups. It does consider thenumber of exercises
set in the exam configuration.Note
Exercise groups with no exercises are ignored.

Create test run popup with one exercise variant selected for each exercise group.¶
When you start the test run, you conduct the exam similar to how a student would. You can create submissions for the different exercises and end the test run.
An instructor can also assess his test run submissions. To do this, you must have completed at least one test run. To navigate to the assessment screen of the test runs click
.

Test run conduction marked with the banner on the top left.¶
Note
Only the creator of the test run is able to assess his submissions.
You can view the results of the assessment of the test run by clicking on
. This page simulates the Student Exam Summary where the students can view their submissions and the results once they are published.
Here instructors can also use the
complaint
feature and respond to it to conclude the full exam timeline.
Note
You should delete test runs before the actual exam conduction takes place.
2. Conduction¶
The exam conduction starts when the exam becomes visible to the students and ends when the latest working time is over. When the exam conduction begins, you cannot make any changes anymore to the exam configuration or individual student exams. When the conduction starts, the students can access and start their exam. They can submit their solutions to the exercises within the given individual working time. When a student submits the exam, he cannot make any changes anymore to his exercise submissions. For more information, see participating in the online exam.
3. Assessment¶
The assessment begins as soon as the latest student exam working time is over. During this period, your team can assess the submissions of the students and provide results. Artemis executes the test suites for programming exercises automatically and grades these. You can enhance the automatic grading with a manual review. You can also trigger the automatic grading of the quiz exercises via the Manage Student Exams Screen.
Once the exam conduction is over and the latest individual working time has passed, your team can begin the assessment process.
This is done through the Assessment Dashboard.
Note
If the exam conduction is not over, you will not be able to access this page.
The assessment process is anonymised. Artemis omits personal student data from the assessors.
The Assessment Dashboard provides an overview over the current assessment progress per exercise. For each exercise, you can view how many submissions have already been assessed and how many are still left. The status of the student complaints is also displayed here.

Assessment Dashboard¶
To assess a submission for an exercise, you can click on
.
Your assessors must first complete the example submissions and assessments, if you have attached those to the exercise, see 1.4 Add Exercises.
If there is a submission which has not been assessed yet, you can click
. This will fetch a random student submission of this exercise which you can then assess.
Artemis grades programming exercises automatically. However, if the exercise allows a manual assessment, you can review and enhance the automatic results.
You can trigger Artemis to automatically grade quiz exercises via the Manage Student Exams Screen. Therefore, quiz exercises do not appear in the Assessment Dashboard.

Manually Assessing a Programming Submission¶
Artemis also allows you to detect plagiarism attempts.
Artemis conducts this by analyzing the similarities between all student submissions and flagging those which exceed a given threshold. You can compare all flagged submissions side by side and confirm plagiarism attempts.
Instructors can download a
CSV
report of accepted and rejected plagiarism attempts for further processing on external systems.To apply the plagiarism check, you must navigate to the individual exercise. This can be done by navigating to:
->
->
on the specific exercise.

Detecting Plagiarism attempts on Modeling Exercises¶
At the bottom of the page you will find the option
.
4. Publication of Results¶
You can specify the moment when Artemis publishes the results of the exam, see 1.2 Create and Configure Exam. This is usually when the exam assessment ends, but you can specify this at any point in time. During the publication of the results, the student can view their results from their summary page. You can also view the exam statistics from the exam Scores page and export the data into external platforms such as TUM Online as a CSV
file, see 4.1 Exam Scores.
You can access the exam scores by clicking on
. This view aggregates the results of the students and combines them to provide an overview over the students’ performance.
You can view the spread between different achieved scores, the average results per exercise, as well as the individual students’ results.
Additionally, you can choose to modify the dataset by selecting
only include submitted exams
oronly include exercises with at least one non-empty submission
.
Note
Unsubmitted exams are not eligable for the assessment process.
Review student performance using various metrics such as average, median and standard deviation.
Unsubmitted exams are not eligable for assessment and thereby appear as having no score. It can happen that an exercise is not part of any student exam. This is the case when Artemis selects a different exercise of the same exercise group for every student exam. Similarly to the unsubmitted exams, they can warp the results and statistics of the exam. By eliminating unsubmitted exams and exercises which were not part of the exam conduction, you can gain a more realistic overview of the performance of the students.
Review the students perceived difficulty of every exercise to improve exams in the future.
The exam scores can also be exported via
. This is useful to upload the results into university systems like TUM Online as a
CSV
file.The exported
CSV
file includes thestudents name
,username
,email
,registration number
, their assignedexercises
, and theirscore
for every exercise.The exported
CSV
file also contains the aggregated statistics of the exam conduction such as thenumber of participations
and theaverage score
per exercise.
5. Student Review¶
During the review period, students have the opportunity to review the assessment of their exam. If they find inconsistencies, they can submit complaints about perceived mistakes made in the assessment. Students can provide their reasoning through a text message to clarify their objections. You can set the student review period in the exam configuration, see 1.2 Create and Configure Exam.
Students can submit complaints about their assessment in the Summary page.
During the student review, a complaint button will appear for every manually assessed exercise.
Students cannot submit complaints for automatically assessed exercises like quiz and programming exercises.
Students will be able to submit a complaint for programming exercises, if the automatic result has been reviewed manually by an assessor. This is only possible if manual assessment is enabled for the programming exercise.
Note
If you have found a mistake in the automatic assessment of quiz and programming exercises, you can edit those and re-trigger the evaluation for all participants.
For more information on how students can participate in the student review and submit complaints, see student summary guide.
6. Complaint Assessment¶
Artemis collects the complaints submitted by the students during the student review. You can access and review the complaints similar to the submissions from the Assessment Dashboard. Every assessor can evaluate a complaint about the assessment of his/her peers and either accept or reject the complaint. Artemis will automatically update the results of accepted complaints. You can view the updated scores immediately in the Scores page. There you can also export the updated data in CSV
format, see 4.1 Exam Scores.
The complaints appear below the exercise submissions.
The original assessor of an assessment cannot respond to the complaint. A second assessor must review the complaint and respond to it.
Artemis tracks the progress of the complaint assessment and displays a progress bar in the Assessment Dashboard. This allows you to keep track of the complaint assessment and see how many open complaints are left.

Assessor responding to a Complaint¶
Students’ Guide¶
Content of this document
General Information¶
Prerequisites¶
Stable internet connection
Recommendation: Use a LAN connection if possible.
Browser
Recommendation: Chromium (based), e.g. Google Chrome, newest version.
The following prerequisites are only required if your exam contains programming exercises:
Java IDE with JDK 15
Recommendation: Eclipse IDE 2020‑09.
Git Client
Recommendation: SourceTree
Offline Mode¶
The exam mode in Artemis tolerates issues with the Internet connection.
If you loose your connection, you can continue working on text-, quiz- and modeling exercises, but you might get warnings that your solutions cannot be saved.
If your Internet connection recovers, Artemis will save your solution.
Artemis tries to save your solution every 30 seconds, when you navigate between exercises, and when you click
or
.
Programming exercises have 2 modes.
Online code editor: can only be used when you are online.
Note
You have to click on
! Otherwise your solution will not be pushed to the VC server and no build will be triggered.
Local IDE: you only need to be online when you clone the repository and when you push your commits (i.e. submit your solution).
At the end of the online exercise, you must be online within a given
grace period
and submit your exam, otherwise it will not be graded.
Suggestions¶
Do NOT reload the browser
If you reload the browser, the Welcome Screen screen opens and you must enter your name and confirm the checkbox again.
You should only reload if an error occurs that cannot be recovered otherwise!
Participate in ONE browser window!
Working in multiple browser windows at the same time is not allowed!
It will lead to synchronization issues and is seen as suspicious behaviour that can be flagged as cheating.
Do not reload, you will receive a warning¶
Participating in the Artemis Online Exam¶
Accessing the Exam¶
Log in to Artemis with your account credentials.
The current exam should be displayed at the top of the Course Overview screen.
You can also access the exam by navigating to the course and then to the exams.
Note
The exam will become visible shortly before the working time starts.

Access Exam¶
Welcome Screen¶
The welcome screen gives you an overview of all the important information you need about the exam.
Carefully read through the instructions.
Once you have read them, confirm that you will follow the rule, sign with your full name and click
.
Note
Your full name represents your signature. You can find your full name as registered on Artemis below the input field.
After you confirm, if the exam working time has started, the Exam Conduction screen will automatically appear.
Otherwise, you must wait until the exam begins. A popup will appear which will notify you how much time is left before the planned start.

Welcome Screen, waiting for exam start¶
Exam Conduction¶
Once the exam working time starts and you have confirmed your participation, the Conduction screen will appear.
On the header, you will find the Exam Navigation Bar. You can use this bar to navigate between different exercises. For each exercise an icon will display your current status.
When there are unsaved or unsubmitted changes, the exercise representation on the navigation bar becomes
.
When your changes are saved and submitted, the exercise representation on the navigation bar becomes
.
indicates that you have not started this exercise.
You can also navigate through the exercises when you are done with one by clicking
. This action will save and submit your changes and move to the next exercise.
Warning
For programming exercises, you must manually press
otherwise your solution will not be counted!
On the header, you will also find the
button. If you press this, you will be sent to the exam End Screen.
The time left until the end of the exam is also shown next to the action buttons, or below, depending on your screen size.
Note
When the time is about to run out, the background of the timer will turn yellow to warn you.

Exam Navigation Bar¶
Participating in Quiz Exercises¶
Various question types can be included in quiz exam exercises. These are:
Multiple choice questions
Short Answer questions
Drag and Drop questions
All questions are listed in the main screen below one another.
To navigate between them you can either scroll or use the
question overview
on the left. When you click on one of the question representations, your view will automatically scroll to the respective question.To submit your solution, simply press
.
Note
Your submission will automatically be saved every 30 seconds.

Participating in Quiz Exercises¶
Participating in Text Exercises¶
The text exercise view is divided into two sections, the text editor, and the problem statement. The problem statement is docked to the right.
Note
On small screens, the problem statement is shown above the text editor.
If you want to focus only on the text editor, you can collapse the problem statement by pressing on
. This can be reverted by pressing the arrow again.
Note
You can also choose to resize the problem statement by dragging the outline box
.
Within the editor you can type out your solution. The editor will automatically track your number of words and number of characters.

Participating in Text Exercises¶
Participating in Modeling Exercises¶
The modeling exercise view is divided into two sections, the modeling editor, and the problem statement. The problem statement is docked to the right.
Note
On small screens, the problem statement is shown above the modeling editor.
If you want to focus only on the modeling editor, you can collapse the problem statement by pressing on
. This can be reverted by pressing the arrow again.
Note
You can also choose to resize the problem statement by dragging the outline box
.
Within the editor you can model your solution. Depending on the diagram type, you will find the available elements on the right side of the editor. Simply drag and drop them into the editing field.
When you click on a dropped element, you can configure it by setting it’s
name
, it’sattributes
,methods
etc.To connect elements you can simply drag an element’s edges to another element. The editor will then automatically connect those two.
If you are unclear about how to use the modeling editor, you can click on
. It will provide further information about how to use the modeling editor.
Note
If you need more space, you can work in fullscreen by clicking on
. This mode will use your whole screen for the modeling exercise thereby giving you more space to model your solution. To exit the fullscreen mode simply click
.

Participating in Modeling Exercises¶
Participating in Programming Exercises¶
Depending on your exam, programming exercises can come in three forms:
Online Code Editor + support for local IDE
Online Code Editor
Support for local IDE
If your exercise allows the use of the code editor your screen will be divided into three sections, from left to right:
The file browser
The code Editor
The instructions
The file browser displays the file structure of the assignment. You can access any file within the assignment. Artemis will display the selected file’s content in the code editor where you can edit it.
You can add new files and directories using the
and
buttons.
You also have the ability to rename
and delete
files and folders, therefore caution is advised.
Note
If you accidentally delete or remove a file, you can use
, to load the last saved version from the server.
The code editor allows you to edit the content of specific files. It shows the line numbers and will also annotate the appropriate line, if a compilation error occurs.
The instructions are docked to the right.
If you want to focus only on the code editor, you can collapse the instructions by pressing on the
. This can be reverted by pressing the arrow again. Similarly, if you want to collapse the file browser, you can press the
above the file browser.
Note
You can also choose to resize any of the three sections by dragging the
.
When you press
, your files are saved on the Artemis server. However, you must press
for your solution to be counted!
When you press
, your changes are pushed to the version control (VC) server and a build is started on the continuous integration (CI) server. This is indicated by the results changing from
to
.
Warning
There is no auto-submit!

Participating in Programming Exercises with the online code editor and local IDE enabled¶
If your exercise allows the use of the local IDE you will have access to the button
.
When you click it you can choose to clone the exercise via
HTTPS
orSSH
, if you have configured your private key.Note
You must link a public key to your account in advance if you want to use
SSH
.To work offline follow these steps:
Clone the Exercise
Import the project in your IDE
Work on the code
Commit and push the code. A push is equivalent to pressing the
button.

Clone the Repository¶
Warning
You are responsible for pushing/submitting your code. Your instructors cannot help you if you have saved, but did not submit.
Your instructors can decide to limit the real-time feedback in programming exercises during the online exam.
In that case, you will only see if your code compiles or not:
means that your code does not compile!
means that your code compiles but provides no further information about your final score.
Warning
Edit a programming exercise EITHER in the online editor OR in your local IDE! Otherwise, conflicts can occur that are hard to resolve.
End Screen¶
When you are finished with the exercises, or the time runs out you navigate to the End Screen.
This is done either by clicking on
or automatically when the exam conduction time is over.
Note
If you navigated to this screen via
, you have the option to return to the conduction by clicking on
.
In this screen you should confirm that you followed all the rules and sign with your full name, similar to the Welcome Screen.
You are given an additional
grace period
to submit the exam after the conduction is over. This additional time is added to the timer shown on the top right.Warning
Your exam will not be graded, should you fail to submit!
Once you submit your exam, no further changes can be made to any exercise.

End Screen after Early Hand in¶
Summary¶
After you hand in, you can view the summary of your exam.
You always have access to the summary. You can find it by following the steps displayed in: Accessing the Exam.
The summary contains an aggregated view of all your submissions. For programming exercises, it also contains the latest commit hash and repository URL so you can review your code.

Summary before the results are published¶
Once the results have been published, you can view your score in the summary.
Additionally, if within the student review period, you have the option to complain about manual assessments made. To do this, simply click on
and explain your rationale.
A second assessor, different from the original one will have the opportunity to review your complaint and respond to it.
Note
The results will automatically be updated, if your complaint was successful.

Complaining about the Assessment of a Text Exercise¶
System Design¶
Top-Level Design¶
The following diagram shows the top-level design of Artemis which is decomposed into an application client (running as Angular web app in the browser) and an application server (based on Spring Boot). For programming exercises, the application server connects to a version control system (VCS) and a continuous integration system (CIS). Authentication is handled by an external user management system (UMS).

Top-Level Design¶
While Artemis includes generic adapters to these three external systems with a defined protocol that can be instantiated to connect to any VCS, CIS or UMS, it also provides 3 concrete implementations for these adapters to connect to:
VCS: Atlassian Bitbucket Server
CIS: Atlassian Bamboo Server
UMS: Atlassian JIRA Server (more specifically Atlassian Crowd on the JIRA Server)
Deployment¶
The following UML deployment diagram shows a typical deployment of Artemis application server and application client. Student, Instructor and Teaching Assistant (TA) computers are all equipped equally with the Artemis application client being displayed in the browser.
The Continuous Integration Server typically delegates the build jobs to local build agents within the university infrastructure or to remote build agents, e.g. hosted in the Amazon Cloud (AWS).
Deployment Overview¶
Data Model¶
The Artemis application server used the following data model in the MySQL database. It supports multiple courses with multiple exercises. Each student in the participating student group can participate in the exercise by clicking the Start Exercise button. Then a repository and a build plan for the student (User) will be created and configured. The initialization state variable (Enum) helps to track the progress of this complex operation and allows to recover from errors. A student can submit multiple solutions by committing and pushing the source code changes to a given example code into the version control system or using the user interface. Each submission is automatically tested by the continuous integration server, which notifies the Artemis application server, when a new result exists. In addition, teaching assistants can assess student solutions and “manually” create results. The current data model is more complex and supports different types of exercises such as programming exercises, modeling exercises, quiz, and text exercises.
Data Model¶
Setup Guide¶
In this guide you learn how to setup the development environment of Artemis. Artemis is based on JHipster, i.e. Spring Boot development on the application server using Java 15, and TypeScript development on the application client in the browser using Angular and Webpack. To get an overview of the used technology, have a look at the JHipster Technology stack and other tutorials on the JHipster homepage.
You can find tutorials how to setup JHipster in an IDE (IntelliJ IDEA Ultimate is recommended) on https://jhipster.github.io/configuring-ide. Note that the Community Edition of IntelliJ IDEA does not provide Spring Boot support (see the comparison matrix). Before you can build Artemis, you must install and configure the following dependencies/tools on your machine:
Java JDK: We use Java (JDK 15) to develop and run the Artemis application server which is based on Spring Boot.
MySQL Database Server 8: Artemis uses Hibernate to store entities in a MySQL database. Download and install the MySQL Community Server (8.0.x) and configure the ‘root’ user with an empty password. (In case you want to use a different password, make sure to change the value in application-dev.yml and in liquibase.gradle). The required Artemis scheme will be created / updated automatically at startup time of the server application. Alternatively, you can run the MySQL Database Server inside a Docker container using e.g.
docker-compose -f src/main/docker/mysql.yml up
Node.js: We use Node (>=13.12.0) to compile and run the client Angular application. Depending on your system, you can install Node either from source or as a pre-packaged bundle.
Yarn: We use Yarn 1.x (>=1.22.0) to manage client side Node dependencies. Depending on your system, you can install Yarn either from source or as a pre-packaged bundle. To do so, please follow the instructions on the Yarn installation page.
Server Setup¶
To start the Artemis application server from the development
environment, first import the project into IntelliJ and then make sure
to install the Spring Boot plugins to run the main class
de.tum.in.www1.artemis.ArtemisApp
. Before the application runs, you
have to configure the file application-artemis.yml
in the folder
src/main/resources/config
.
artemis:
repo-clone-path: ./repos/
repo-download-clone-path: ./repos-download/
encryption-password: <encrypt-password> # arbitrary password for encrypting database values
user-management:
use-external: true
external:
url: https://jira.ase.in.tum.de
user: <username> # e.g. ga12abc
password: <password>
admin-group-name: tumuser
ldap:
url: <url>
user-dn: <user-dn>
password: <password>
base: <base>
version-control:
url: https://bitbucket.ase.in.tum.de
user: <username> # e.g. ga12abc
password: <password>
token: <token> # VCS API token giving Artemis full Admin access. Not needed for Bamboo+Bitbucket
ci-token: <token from the CI> # Token generated by the CI (e.g. Jenkins) for webhooks from the VCS to the CI. Not needed for Bamboo+Bitbucket
continuous-integration:
url: https://bamboo.ase.in.tum.de
user: <username> # e.g. ga12abc
token: <token> # Enter a valid token generated by bamboo or leave this empty to use the fallback authentication user + password
password: <password>
vcs-application-link-name: LS1 Bitbucket Server # If the VCS and CI are directly linked (normally only for Bitbucket + Bamboo)
empty-commit-necessary: true # Do we need an empty commit for new exercises/repositories in order for the CI to register the repo
# Hash/key of the ci-token, equivalent e.g. to the ci-token in version-control
# Some CI systems, like Jenkins, offer a specific token that gets checked against any incoming notifications
# from a VCS trying to trigger a build plan. Only if the notification request contains the correct token, the plan
# is triggered. This can be seen as an alternative to sending an authenticated request to a REST API and then
# triggering the plan.
# In the case of Artemis, this is only really needed for the Jenkins + GitLab setup, since the GitLab plugin in
# Jenkins only allows triggering the Jenkins jobs using such a token. Furthermore, in this case, the value of the
# hudson.util.Secret is stored in the build plan, so you also have to specify this encrypted string here and NOT the actual token value itself!
# You can get this by GETting any job.xml for a job with an activated GitLab step and your token value of choice.
secret-push-token: <token hash>
# Key of the saved credentials for the VCS service
# Bamboo: not needed
# Jenkins: You have to specify the key from the credentials page in Jenkins under which the user and
# password for the VCS are stored
vcs-credentials: <credentials key>
# Key of the credentials for the Artemis notification token
# Bamboo: not needed
# Jenkins: You have to specify the key from the credentials page in Jenkins under which the notification token is stored
notification-token: <credentials key>
# The actual value of the notification token to check against in Artemis. This is the token that gets send with
# every request the CI system makes to Artemis containing a new result after a build.
# Bamboo: The token value you use for the Server Notification Plugin
# Jenkins: The token value you use for the Server Notification Plugin and is stored under the notification-token credential above
authentication-token: <token>
lti:
id: artemis_lti
oauth-key: artemis_lti_key
oauth-secret: <secret> # only important for online courses on the edX platform, can typically be ignored
user-prefix-edx: edx_
user-prefix-u4i: u4i_
user-group-name-edx: edx
user-group-name-u4i: u4i
git:
name: Artemis
email: artemis@in.tum.de
automatic-text:
segmentation-url: http://localhost:8000/segment
feedback-consistency-url: http://localhost:8001/feedback_consistency
material-upload-url: http://localhost:8001/upload
embedding-url: http://localhost:8001/embed
embedding-chunk-size: 50
clustering-url: http://localhost:8002/cluster
secret: null
Change all entries with <...>
with proper values, e.g. your TUM
Online account credentials to connect to the given instances of JIRA,
Bitbucket and Bamboo. Alternatively, you can connect to your local JIRA,
Bitbucket and Bamboo instances. It’s not necessary to fill all the
fields, most of them can be left blank. Note that there is additional
information about the setup for programming exercises provided:
Setup for Programming Exercises with Bamboo, Bitbucket and Jira¶
This page describes how to set up a programming exercise environment based on Bamboo, Bitbucket and Jira.
Therefore, a check is included within the BambooBuildPlanService that ensures that builds are not started in Docker agents if the development setup is present.
Prerequisites:
Content of this document
Docker-Compose¶
Before you start the docker-compose, check if the bamboo version in the
build.gradle
(search for com.atlassian.bamboo:bamboo-specs
) is
equal to the bamboo version number in the Dockerfile of bamboo stored in
src/main/docker/bamboo/Dockerfile
. If the version number is not
equal adjust the version number in the Dockerfile.
Execute the docker-compose file atlassian.yml
stored in
src/main/docker
e.g. with
docker-compose -f src/main/docker/atlassian.yml up -d
Error Handling: It can happen that there is an overload with other
docker networks
ERROR: Pool overlaps with other one on this address space
. Use the
command docker network prune
to resolve this issue.
Make also sure that docker has enough memory (~ 6GB). To adapt it, go to Preferecences -> Resources
Configure Bamboo, Bitbucket and Jira¶
By default, the Jira instance is reachable under localhost:8081
, the
Bamboo instance under localhost:8085
and the Bitbucket instance
under localhost:7990
.
Get evaluation licenses for Atlassian products: Atlassian Licenses
Create an admin user with the same credentials in all 3 applications. Create a sample project in Jira. Also, you can select the evaluation/internal/test/dev setups if you are asked. Select a
Bitbucket (Server)
license if asked. Do not connect Bitbucket with Jira yet.- Execute the shell script
atlassian-setup.sh
in thesrc/main/docker
directory (e.g. withsrc/main/docker/./atlassian-setup.sh
). This script creates groups, users ([STRIKEOUT:and adds them to the created groups] NOT YET) and disabled application links between the 3 applications Enable the created application links between all 3 application (OAuth Impersonate). The links should open automatically after the shell script has finished. If not open them manually:
The script has already created users and groups but you need to manually assign the users into their respective group in Jira. In our test setup, users 1-5 are students, 6-10 are tutors and 11-15 are instructors. The usernames are artemis_test_user_{1-15} and the password is again the username. When you create a course in artemis you have to manually choose the created groups(students, tutors, instructors).
Use the user directories in Jira to synchronize the users in bitbucket and bamboo:
Go to Jira → User management → Jira user server → Add application → Create one application for bitbucket and one for bamboo → add the IP-address
0.0.0.0/0
to IP AddressesGo to Bitbucket and Bamboo → User Directories → Add Directories → Atlassian Crowd → use the URL
http://jira:8080
as Server URL → use the application name and password which you used in the previous step. Also, you should decrease the synchronisation period (e.g. to 2 minutes). Press synchronise after adding the directory, the users and groups should now be available.
In Bamboo create a global variable named SERVER_PLUGIN_SECRET_PASSWORD, the value of this variable will be used as the secret. The value of this variable should be then stored in
src/main/resources/config/application-artemis.yml
as the value ofartemis-authentication-token-value
.Download the bamboo-server-notifaction-plugin and add it to bamboo. Go to Bamboo → Manage apps → Upload app → select the downloaded .jar file → Upload
Add Maven and JDK:
Go to Bamboo → Server capabilities → Add capabilities menu → Capability type
Executable
→ select typeMaven 3.x
→ insertMaven 3
as executable label → insert/artemis
as path.Add capabilities menu → Capability type
JDK
→ insertJDK
as JDK label → insert/usr/lib/jvm/java-15-oracle
as Java home.
Generate a personal access token
While username and password can still be used as a fallback, this option is already marked as deprecated and will be removed in the future.
9.1 Personal access token for Bamboo.
Log in as the admin user and go to Bamboo -> Profile (top right corner) -> Personal access tokens -> Create token
Insert the generated token into the file
application-artemis.yml
in the sectioncontinuous-integration
:
artemis: continuous-integration: user: <username> password: <password> token: #insert the token here
9.2 Personal access token for Bitbucket.
Log in as the admin user and go to Bitbucket -> View Profile (top right corner) -> Manage account -> Personal access tokens -> Create token
Insert the generated token into the file
application-artemis.yml
in the section ``version-control ``:
artemis: version-control: user: <username> password: <password> token: #insert the token here
Disable XSRF checking Although XSRF checking is highly recommended, we currently have to disable it as Artemis does not yet support sending the required headers.
Log in as the admin user go to Bamboo -> Overview -> Security Settings
Edit the settings and disable XSRF checking:
Configure Artemis¶
Modify
src/main/resources/config/application-artemis.yml
repo-clone-path: ./repos/ repo-download-clone-path: ./repos-download/ encryption-password: artemis-encrypt # arbitrary password for encrypting database values user-management: use-external: true external: url: http://localhost:8081 user: <jira-admin-user> password: <jira-admin-password> admin-group-name: instructors internal-admin: username: artemis_admin password: artemis_admin version-control: url: http://localhost:7990 user: <bitbucket-admin-user> password: <bitbuckt-admin-password> continuous-integration: url: http://localhost:8085 user: <bamboo-admin-user> password: <bamboo-admin-password> token: <bamboo-admin-token> vcs-application-link-name: LS1 Bitbucket Server empty-commit-necessary: true artemis-authentication-token-value: <artemis-authentication-token-value>
Modify the application-dev.yml
server: port: 8080 # The port of artemis url: http://172.20.0.1:8080 # needs to be an ip // url: http://docker.for.mac.host.internal:8080 # If the above one does not work for mac try this one // url: http://host.docker.internal:8080 # If the above one does not work for windows try this one
In addition, you have to start Artemis with the profiles bamboo
,
bitbucket
and jira
so that the correct adapters will be used,
e.g.:
--spring.profiles.active=dev,bamboo,bitbucket,jira,artemis
Please read Setup Guide for more details.
How to verify the connection works?¶
You can login to Artemis with the admin user you created in Jira
You can create a programming exercise
You can create a programming exercise
The build of the students repository gets started after pushing to it
When using the code editor, after clicking on Submit, the text Building and testing… should appear.
The build result is displayed in the code editor.
Setup for Programming Exercises with Jenkins and GitLab¶
This page describes how to set up a programming exercise environment
based on Jenkins and GitLab. Optional commands are in curly brackets {}
.
The following assumes that all instances run on separate servers. If you have one single server, or your own NGINX instance, just skip all NGINX related steps and use the configurations provided under Separate NGINX Configurations
If you want to setup everything on your local machine, you can also
just ignore all NGINX related steps. Just make sure that you use
unique port mappings for your Docker containers (e.g. 80
for
GitLab, 8080
for Jenkins, 8081
for Artemis)
Prerequisites:
Content of this document
Artemis¶
In order to use Artemis with Jenkins as Continuous Integration
Server and Gitlab as Version Control Server, you have to configure
the file application-prod.yml
(Production Server) or
application-artemis.yml
(Local Development) accordingly. Please note
that all values in <..>
have to be configured properly. These values
will be explained below in the corresponding sections.
artemis:
repo-clone-path: ./repos/
repo-download-clone-path: ./repos-download/
encryption-password: artemis-encrypt # arbitrary password for encrypting database values
user-management:
use-external: false
internal-admin:
username: artemis_admin
password: artemis_admin
version-control:
url: <https://gitlab-url>
user: <gitlab-admin-user>
password: <gitlab-admin-password>
token: <token>
ci-token: <ci-token>
continuous-integration:
user: <jenkins-admin-user>
password: <jenkins-admin-password>
url: <https://jenkins-url>
empty-commit-necessary: false
secret-push-token: <secret push token>
vcs-credentials: <vcs-credentials>
artemis-authentication-token-key: <artemis-authentication-token-key>
artemis-authentication-token-value: <artemis-authentication-token-value>
In addition, you have to start Artemis with the profiles gitlab
and
jenkins
so that the correct adapters will be used, e.g.:
--spring.profiles.active=dev,jenkins,gitlab,artemis
Please read Setup Guide for more details.
For a local setup on Windows you can use http://host.docker.internal appended by the chosen ports as the version-control and continuous-integration url.
Make sure to change the server.url
value in application-dev.yml
or application-prod.yml
accordingly. This value will be used for the
communication hooks from Gitlab to Artemis and from Jenkins to Artemis.
In case you use a different port than 80 (http) or 443 (https) for the
communication, you have to append it to the server.url
value,
e.g. 127.0.0.1:8081
.
When you start Artemis for the first time, it will automatically create
an admin user based on the default encryption password specified in the
yml file above. In case you want to use a different encryption password,
you can insert users manually into the jhi_user
table. You can use
Jasypt Online Encryption
Tool
to generate encryption strings. Use Two Way Encryption (With Secret
Text).
GitLab¶
Pull the latest GitLab Docker image
docker pull gitlab/gitlab-ce:latest
Run the image (and change the values for hostname and ports). Add
-p 2222:22
if cloning/pushing via ssh should be possible. As Gitlab runs in a docker container and the default port for SSH (22) is typically used by the host running Docker, we change the port Gitlab uses for SSH to2222
. This can be adjusted if needed.Make sure to remove the comments from the command before running it and that docker has enough memory (~ 6GB). To adapt it, go to
Preferecences -> Resources
docker run -itd --name gitlab \ --hostname your.gitlab.domain.com \ # Specify the hostname --restart always \ -m 3000m \ # Optional argument to limit the memory usage of Gitlab -p 2222:22 \ # Remove this if cloning via SSH should not be supported -p 80:80 -p 443:443 \ # Alternative 1: If you are NOT running your own NGINX instance -p <some port of your choosing>:80 \ # Alternative 2: If you ARE running your own NGINX instance -v gitlab_data:/var/opt/gitlab \ -v gitlab_logs:/var/log/gitlab \ -v gitlab_config:/etc/gitlab \ gitlab/gitlab-ce:latest
Wait a couple of minutes until the container is deployed and GitLab is set up, then open the instance in you browser and set a first admin password of your choosing. You can then login using the username “root” and you password.
We recommend to rename the “root” admin user to “artemis”. To rename the user, click on the image on the top right and select “Settings”. Now select “Account” on the left and change the username. Use the same password in the Artemis configuration file application-artemis.yml
artemis: version-control: user: artemis password: the.password.you.chose
If you run your own NGINX, then skip the next steps (6-7)
Configure Gitlab to automatically generate certificates using LetsEncrypt. Edit the Gitlab configuration
docker exec -it gitlab /bin/bash nano /etc/gitlab/gitlab.rb
And add the following part
letsencrypt['enable'] = true # GitLab 10.5 and 10.6 require this option external_url "https://your.gitlab.domain.com" # Must use https protocol letsencrypt['contact_emails'] = ['gitlab@your.gitlab.domain.com'] # Optional nginx['redirect_http_to_https'] = true nginx['redirect_http_to_https_port'] = 80
Reconfigure gitlab to generate the certificate.
# Save your changes and finally run gitlab-ctl reconfigure
If this command fails, try using
gitlab-ctl renew-le-certs
Login to GitLab using the Artemis admin account and go to the profile settings (upper right corned → Settings)
Go to Access Tokens
Create a new token named “Artemis” and give it all rights.
Copy the generated token and insert it into the Artemis configuration file application-artemis.yml
artemis: version-control: token: your.generated.api.token
(Optional) Allow outbound requests to local network
There is a known limitation for the local setup: webhook URLs for the communication between Gitlab and Artemis and between Gitlab and Jenkins cannot include local IP addresses. This option can be deactivated in Gitlab on
<https://gitlab-url>/admin/application_settings/network
→ Outbound requests. Another possible solution is to register a local URL, e.g. using ngrok, to be available over a domain the Internet.Adjust the monitoring-endpoint whitelist. Run the following command
docker exec -it gitlab /bin/bash
Then edit the Gitlab configuration
nano /etc/gitlab/gitlab.rb
Add the following lines
gitlab_rails['monitoring_whitelist'] = ['0.0.0.0/0'] gitlab_rails['gitlab_shell_ssh_port'] = 2222
This will disable the firewall for all IP addresses. If you only want to allow the server that runs Artemis to query the information, replace
0.0.0.0/0
withARTEMIS.SERVER.IP.ADRESS/32
If you use SSH and use a different port than
2222
, you have to adjust the port above.Disable prometheus. As we encountered issues with the prometheus log files not being deleted and therefore filling up the disk space, we decided to disable prometheus within Gitlab. If you also want to disable prometheus, edit the configuration again using
nano /etc/gitlab/gitlab.rb
and add the following line
prometheus_monitoring['enable'] = false
The issue with more details can be found here.
Reconfigure Gitlab
gitlab-ctl reconfigure
You can upgrade GitLab by downloading the latest Docker image and starting a new container with the old volumes:
docker stop gitlab docker rename gitlab gitlab_old docker pull gitlab/gitlab-ce:latest
See https://hub.docker.com/r/gitlab/gitlab-ce/ for the latest version. You can also specify an earlier one.
Start a GitLab container just as described in Start-Gitlab and wait for a couple of minutes. GitLab
should configure itself automatically. If there are no issues, you can
delete the old container using docker rm gitlab_old
and the olf
image (see docker images
) using docker rmi <old-image-id>
.
You can also remove all old images using docker image prune -a
Jenkins¶
Pull the latest Jenkins LTS Docker image
sudo docker pull jenkins/jenkins:lts
Create a custom docker image
Run the following command to get the latest jenkins LTS docker image.
In order to install and use Maven with Java in the Jenkins container, you have to first install maven, then download Java and finally configure Maven to use Java instead of the default version.
To perform all these steps automatically, you can prepare a Docker image:
Create a dockerfile with the content found here <src/main/docker/jenkins/Dockerfile>. Copy it in a file named
Dockerfile
, e.g. in the folder/opt/jenkins/
usingvim Dockerfile
.Now run the command
docker build --no-cache -t jenkins-artemis .
This might take a while because Docker will download Java, but this is only required once.
Run steps 4-6 only if you are not using a separate instance, otherwise continue with Start-Jenkins
Create a file increasing the maximum file size for the nginx proxy. The nginx-proxy uses a default file limit that is too small for the plugin that will be uploaded later. Skip this step if you have your own NGINX instance.
echo "client_max_body_size 16m;" > client_max_body_size.conf
Run the NGINX proxy docker container, this will automatically setup all reverse proxies and force https on all connections. (This image would also setup proxies for all other running containers that have the VIRTUAL_HOST and VIRTUAL_PORT environment variables). Skip this step if you have your own NGINX instance.
docker run -itd --name nginx_proxy \ -p 80:80 -p 443:443 \ --restart always \ -v /var/run/docker.sock:/tmp/docker.sock:ro \ -v /etc/nginx/certs \ -v /etc/nginx/vhost.d \ -v /usr/share/nginx/html \ -v $(pwd)/client_max_body_size.conf:/etc/nginx/conf.d/client_max_body_size.conf:ro \ jwilder/nginx-proxy
The nginx proxy needs another docker-container to generate letsencrypt certificates. Run the following command to start it (make sure to change the email-address). Skip this step if you have your own NGINX instance.
docker run --detach \ --name nginx_proxy-letsencrypt \ --volumes-from nginx_proxy \ --volume /var/run/docker.sock:/var/run/docker.sock:ro \ --env "DEFAULT_EMAIL=mail@yourdomain.tld" \ jrcs/letsencrypt-nginx-proxy-companion
Run Jenkins by executing the following command (change the hostname and choose which port alternative you need)
docker run -itd --name jenkins \ --restart always \ -v jenkins_data:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ -e VIRTUAL_HOST=your.jenkins.domain -e VIRTUAL_PORT=8080 \ # Alternative 1: If you are NOT using a separate NGINX instance -e LETSENCRYPT_HOST=your.jenkins.domain \ # Only needed if Alternative 1 is used -p <some port of your choosing>:8080 \ # Alternative 2: If you ARE using a separate NGINX instance jenkins-artemis
For jenkins to be able to read data from the volume you might need to allow the jenkins user to read the jenkins_data folder. One way to do that is transfer the ownership to the user with id 1000 which is normally the user the jenkins process runs with.
sudo chown -R 1000 jenkins_data/
Wait until the docker container has started and Jenkins is running.
Run the following commands to navigate into the docker container and check the Maven and JDK version
sudo docker exec -it jenkins /bin/bash mvn -version
This should print
Maven 3.x
as Maven version,Java 15
as Java version and/usr/lib/jvm/java-15-openjdk-amd64
as Java home.Open Jenkins in your browser (e.g.
localhost:8080
) and setup the admin user account (install all suggested plugins). You can get the initial admin password using the following command.# Jenkins highlights the password in the logs, you can't miss it docker logs -f jenkins or alternatively docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
Set the chosen credentials in the Artemis configuration application-artemis.yml
artemis: continuous-integration: user: your.chosen.username password: your.chosen.password
Setup JDK 15 in Jenkins Settings
Navigate in your browser into Jenkins → Manage Jenkins → Global Tool Configuration → JDK. Change the existing JDK installation or click on Add JDK.
Use
OpenJDK 15
as Name and/usr/lib/jvm/java-15-openjdk-amd64
as JAVA_HOME
You will need to install the following plugins (apart from the recommended ones that got installed during the setup process):
GitLab for enabling webhooks to and from GitLab
Multiple SCMs for combining the exercise test and assignment repositories in one build
Post Build Task for preparing build results to be exported to Artemis
Xvfb for exercises based on GUI libraries, for which tests have to have some virtual display
Timestamper for adding the time to every line of the build output (Timestamper might already be installed)
Choose “Download now and install after restart” and checking the “Restart Jenkins when installation is complete and no jobs are running” box
Go to Manage Jenkins → Configure System. There you will find the Timestamper configuration, use the following value for both formats:
'<b>'yyyy-MM-dd'T'HH:mm:ssX'</b> '

Artemis needs to receive a notification after every build, which contains the test results and additional commit information. For that purpose, we developed a Jenkins plugin, that can aggregate and POST JUnit formatted results to any URL.
You can download the current release of the plugin here (Download the .hpi file). Go to the Jenkins plugin page (Manage Jenkins → Manage Plugins) and install the downloaded file under the Advanced tab under Upload Plugin

Go to Credentials → Jenkins → Global credentials and create the following credentials
Create a new access token in GitLab named “Jenkins” and give it api rights and read_repository rights. For detailed instructions on how to create such a token follow Gitlab Access Token.
Copy the generated token and create new Jenkins credentials:
Kind: GitLab API token
API token: your.copied.token
Leave the ID field blank
The description is up to you
Go to the Jenkins settings Manage Jenkins → Configure System. There you will find the GitLab settings. Fill in the URL of your GitLab instance and select the just created API token in the credentials dropdown. After you click on “Test Connection”, everything should work fine. If you have problems finding the right URL for your local docker setup, you can try http://host.docker.internal:80 for Windows or http://docker.for.mac.host.internal:80 for Mac if GitLab is reachable over port 80.
Create a new Jenkins credential containing the token, which gets send by the server notification plugin to Artemis with every build result:
Kind: Secret text
Secret: your.secret_token_value (choose any value you want, copy it for the nex step)
Leave the ID field blank
The description is up to you
Copy the generated ID of the new credentials and put it into the Artemis configuration application-artemis.yml
artemis: continuous-integration: artemis-authentication-token-key: the.id.of.the.notification.token.credential
Copy the actual value you chose for the token and put it into the Artemis configuration application-artemis.yml
artemis: continuous-integration: artemis-authentication-token-value: the.actual.value.of.the.notification.token
Create a new Jenkins credentials containing the username and password of the GitLab administrator account:
Kind: Username with password
Scope: global
Username: the_username_you_chose_for_the_gitlab_admin_user
Password: the_password_you_chose_for_the_gitlab_admin_user
Leave the ID field blank
The description is up to you
Copy the generated ID (e.g.
ea0e3c08-4110-4g2f-9c83-fb2cdf6345fa
) of the new credentials and put it into the Artemis configuration file application-artemis.ymlartemis: continuous-integration: vcs-credentials: the.id.of.the.username.and.password.credentials.from.jenkins
GitLab has to notify Jenkins build plans if there are any new commits to the repository. The push notification that gets sent here is secured by a token generated by Jenkins. In order to get this token, you have to do the following steps:
Create a new item in Jenkins (use the Freestyle project type) and name it TestProject
In the project configuration, go to Build Triggers → Build when a change is pushed to GitLab and activate this option
Click on Advanced.
You will now have a couple of new options here, one of them being a “Secret token”.
Click on the “Generate” button right below the text box for that token.
Copy the generated value, let’s call it $gitlab-push-token
Apply these change to the plan (i.e. click on Apply)
Perform a GET request to the following URL (e.g. with Postman) using Basic Authentication and the username and password you chose for the Jenkins admin account:
GET https://your.jenkins.domain/job/TestProject/config.xml
You will get the whole configuration XML of the just created build plan, there you will find the following tag:
<secretToken>{$some-long-encrypted-value}</secretToken>
![]()
Job configuration XML¶
Copy the value of :math:`some-long-encrypted-value without the curly brackets!. This is the encrypted value of the `gitlab-push-token you generated in step 5.
Now, you can delete this test project and input the following values into your Artemis configuration application-artemis.yml (replace the placeholders with the actual values you wrote down)
artemis: version-control: ci-token: $gitlab-push-token continuous-integration: secret-push-token: $some-long-encrytped-value
In a local setup, you might want to disable CSRF by going to: “Manage Jenkins” - “Configure Global Security” and uncheck “Prevent Cross Site Request Forgery exploits”. Also disable the option
use-crumb
inapplication-jenkins.yml
.Depending on the version this setting might not be available anymore. Have a look here on how you can disable CSRF protection.
Build the latest version of the jenkins-artemis
Docker image, stop
the running container and mount the Jenkins data volume to the new LTS
container. Make sure to perform this command in the folder where the
Dockerfile
was created (e.g. /opt/jenkins/
):
docker stop jenkins docker rename jenkins jenkins_old docker build --no-cache -t jenkins-artemis .
Now start a new Jenkins container just as described in Start-Jenkins.
Jenkins should be up and running again. If there are no issues, you can
delete the old container using docker rm jenkins_old
and the old
image (see docker images
) using docker rmi <old-image-id>
.
You can also remove all old images using docker image prune -a
You should also update the Jenkins plugins regularly due to security reasons. You can update them directly in the Web User Interface in the Plugin Manager.
Separate NGINX Configurations¶
There are some placeholders in the following configurations. Replace them with your setup specific values ### GitLab
server {
listen 443 ssl http2;
server_name your.gitlab.domain;
ssl_session_cache shared:GitLabSSL:10m;
include /etc/nginx/common/common_ssl.conf;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header Referrer-Policy same-origin;
client_max_body_size 10m;
client_body_buffer_size 1m;
location / {
proxy_pass http://localhost:<your exposed GitLab HTTP port (default 80)>;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_http_version 1.1;
proxy_redirect http:// https://;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
gzip off;
}
}
server {
listen 443 ssl http2;
server_name your.jenkins.domain;
ssl_session_cache shared:JenkinsSSL:10m;
include /etc/nginx/common/common_ssl.conf;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header Referrer-Policy same-origin;
client_max_body_size 10m;
client_body_buffer_size 1m;
location / {
proxy_pass http://localhost:<your exposed Jenkins HTTP port (default 8080)>;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off; # Required for HTTP-based CLI to work over SSL
# workaround for https://issues.jenkins-ci.org/browse/JENKINS-45651
add_header 'X-SSH-Endpoint' 'your.jenkins.domain.com:50022' always;
}
error_page 502 /502.html;
location /502.html {
root /usr/share/nginx/html;
internal;
}
}
If you haven’t done so, generate the DH param file:
sudo openssl dhparam -out /etc/nginx/dhparam.pem 4096
ssl_certificate <path to your fullchain certificate>;
ssl_certificate_key <path to the private key of your certificate>;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+CHACHA20:EECDH+AESGCM:EDH+AESGCM:!AES128;
ssl_ecdh_curve secp384r1;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver <if you have any, specify them here> valid=300s;
resolver_timeout 5s;
#Deployment Artemis / GitLab / Jenkins using Docker on Local machine
Execute the following steps in addition to the ones described above:
Preparation¶
Create a Docker network named “artemis” with
docker network create artemis
Gitlab¶
Add the Gitlab container to the created network with
docker network connect artemis gitlab
Get the URL of the Gitlab container with the first IP returned by
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' gitlab
Use this IP in the
application-artemis.yml
file atartemis.version-control.url
Jenkins¶
Add the Jenkins container to the created network with
docker network connect artemis jenkins
Get the URL of the Gitlab container with the first IP returned by
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' jenkins
Use this IP in the
application-artemis.yml
file atartemis.continuous-integration.url
Artemis¶
In
docker-compose.yml
Change the
8080:8080
port to8081:8081
because Jenkins is using the port 8080Change the SPRING_PROFILES_ACTIVE to dev,jenkins,gitlab,artemis
In
src/main/resources/config/application-dev.yml
At
spring.profiles.active:
add& gitlab & jenkins
At
spring.liquibase:
add the new propertychange-log: classpath:config/liquibase/master.xml
At
server:
change port to 8081 and
Run
docker-compose up
After the container has been deployed run
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' artemis_artemis-server
and copy the first resulting IP.In
src/main/resources/config/application-dev.yml
atserver:
change the port to 8081 and aturl:
paste the copied IPStop the Artemis docker container with Control-C and re-run
docker-compose up
Setup of Artemis with multiple instances¶
Setup with multiple instances¶
There are certain scenarios, where a setup with multiple instances of the application server is required. This can e.g. be due to special requirements regarding fault tolerance or performance.
Artemis also supports this setup (which is also used at the Chair for Applied Software Engineering at TUM).
Multiple instances of the application server are used to distribute the load:
A load balancer (typically a reverse proxy such as nginx) is added, that distributes the requests to the different instances.
Note: This documentation focuses on the practical setup of this distributed setup.
More details regarding the theoretical aspects can be found in the Bachelor’s Thesis Securing and Scaling Artemis WebSocket Architecture, which can be found here: pdf
.
Additional synchronization¶
All instances of the application server use the same database, but other parts of the system also have to be synchronized:
Database cache
WebSocket messages
File system
Each of these three aspects is synchronized using a different solution
Database cache¶
Artemis uses a cache provider that supports distributed caching: Hazelcast.
All instances of Artemis form a so-called cluster that allows them to synchronize their cache.
You can use the configuration argument spring.hazelcast.interface
to configure the interface on which Hazelcast will listen.
One problem that arises with a distributed setup is that all instances have to know each other in order to create this cluster. This is problematic if the instances change dynamically. Artemis uses a discovery service to solve the issue (named JHipster Registry).
Disovery service¶
JHipster registry contains Eureka, the discovery service where all instances can register themselves and fetch the other registered instances.
Eureka can be configured like this within Artemis:
# Eureka configuration
eureka:
client:
enabled: true
service-url:
defaultZone: {{ artemis_eureka_urls }}
instance:
prefer-ip-address: true
ip-address: {{ artemis_ip_address }}
appname: Artemis
instanceId: Artemis:{{ artemis_eureka_instance_id }}
logging:
file:
name: '/opt/artemis/artemis.log'
{{ artemis_eureka_urls }}
must be the URL where Eureka is reachable, {{ artemis_ip_address }}
must be the IP under which this instance is reachable and {{ artemis_eureka_instance_id }}
must be a unique identifier for this instance.
You also have to setup the value jhipster.registry.password
to the password of the registry (which you will set later).
Installing
Create the directory
sudo mkdir /opt/registry/
sudo mkdir /opt/registry/config-server
Download the application
Download the latest version of the jhipster-registry from GitHub, e.g. by using
sudo wget -O /opt/registry/registry.jar https://github.com/jhipster/jhipster-registry/releases/download/v6.2.0/jhipster-registry-6.2.0.jar
Service configuration
sudo vim /etc/systemd/system/registry.service
[Unit]
Description=Registry
After=syslog.target
[Service]
User=artemis
WorkingDirectory=/opt/registry
ExecStart=/usr/bin/java \
-Xmx256m \
-jar registry.jar \
--spring.profiles.active=prod,native
SuccessExitStatus=143
StandardOutput=/opt/registry/registry.log
#StandardError=inherit
[Install]
WantedBy=multi-user.target
Set Permissions in Registry Folder
sudo chown -R artemis:artemis /opt/registry
sudo chmod g+rwx /opt/registry
Enable the service
sudo systemctl daemon-reload
sudo systemctl enable registry.service
Start Service (only after performing steps 1-3 of the configuration)
sudo systemctl start registry
Logging
sudo journalctl -f -n 1000 -u registry
Configuration
sudo vim /opt/registry/application-prod.yml
logging:
file:
name: '/opt/registry/registry.log'
jhipster:
security:
authentication:
jwt:
base64-secret: THE-SAME-TOKEN-THAT-IS-USED-ON-THE-ARTEMIS-INSTANCES
registry:
password: AN-ADMIN-PASSWORD-THAT-MUST-BE-CHANGED
spring:
security:
user:
password: AN-ADMIN-PASSWORD-THAT-MUST-BE-CHANGED
sudo vim /opt/registry/bootstrap-prod.yml
jhipster:
security:
authentication:
jwt:
base64-secret: THE-SAME-TOKEN-THAT-IS-USED-ON-THE-ARTEMIS-INSTANCES
secret: ''
spring:
cloud:
config:
server:
bootstrap: true
composite:
- type: native
search-locations: file:./config-server
sudo vim /opt/registry/config-server/application.yml
# Common configuration shared between all applications configserver: name: Artemis JHipster Registry status: Connected to the Artemis JHipster Registry jhipster: security: authentication: jwt: secret: '' base64-secret: THE-SAME-TOKEN-THAT-IS-USED-ON-THE-ARTEMIS-INSTANCES eureka: client: service-url: defaultZone: http://admin:${jhipster.registry.password}@localhost:8761/eureka/
nginx config
You still have to make the registry available:
sudo vim /etc/nginx/sites-available/registry.conf
server { listen 443 ssl http2; server_name REGISTRY_FQDN; ssl_session_cache shared:RegistrySSL:10m; include /etc/nginx/common/common_ssl.conf; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; add_header X-Frame-Options DENY; add_header Referrer-Policy same-origin; client_max_body_size 10m; client_body_buffer_size 1m; location / { proxy_pass http://localhost:8761; proxy_read_timeout 300; proxy_connect_timeout 300; proxy_http_version 1.1; proxy_redirect http:// https://; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; gzip off; } }
sudo ln -s /etc/nginx/sites-available/registry.conf /etc/nginx/sites-enabled/
This enables the registry in nginx
sudo service nginx restart
This will apply the config changes and the registry will be reachable.
WebSockets¶
WebSockets should also be synchronized (so that a user connected to one instance can perform an action which causes an update to users on different instances, without having to reload the page - such as quiz starts). We use a so-called broker for this (named Apache ActiveMQ Artemis).
It relays message between instances:
Setup
Create a folder to store ActiveMQ
sudo mkdir /opt/activemq-distribution
Download ActiveMQ here: http://activemq.apache.org/components/artemis/download/
sudo wget -O /opt/activemq-distribution/activemq.tar.gz https://downloads.apache.org/activemq/activemq-artemis/2.13.0/apache-artemis-2.13.0-bin.tar.gz
Extract the downloaded contents
cd /opt/activemq-distribution sudo tar -xf activemq.tar.gz
Navigate to the folder with the CLI
cd /opt/activemq-distribution/apache-artemis-2.13.0/bin
Create a broker in the /opt/broker/broker1 directory, replace USERNAME and PASSWORD accordingly
sudo ./artemis create --user USERNAME --password PASSWORD --require-login /opt/broker/broker1
Adjust the permissions
sudo chown -R artemis:artemis /opt/broker sudo chmod g+rwx /opt/broker
Adjust the configuration of the broker:
sudo vim /opt/broker/broker1/etc/broker.xml
<?xml version='1.0'?> <configuration xmlns="urn:activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd"> <core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq:core "> <name>0.0.0.0</name> <journal-pool-files>10</journal-pool-files> <acceptors> <!-- STOMP Acceptor. --> <acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true;heartBeatToConnectionTtlModifier=6</acceptor> </acceptors> <connectors> <connector name="netty-connector">tcp://localhost:61616</connector> </connectors> <security-settings> <security-setting match="#"> <permission type="createNonDurableQueue" roles="amq"/> <permission type="deleteNonDurableQueue" roles="amq"/> <permission type="createDurableQueue" roles="amq"/> <permission type="deleteDurableQueue" roles="amq"/> <permission type="createAddress" roles="amq"/> <permission type="deleteAddress" roles="amq"/> <permission type="consume" roles="amq"/> <permission type="browse" roles="amq"/> <permission type="send" roles="amq"/> <!-- we need this otherwise ./artemis data imp wouldn't work --> <permission type="manage" roles="amq"/> </security-setting> </security-settings> <address-settings> <!--default for catch all--> <address-setting match="#"> <dead-letter-address>DLQ</dead-letter-address> <expiry-address>ExpiryQueue</expiry-address> <redelivery-delay>0</redelivery-delay> <!-- with -1 only the global-max-size is in use for limiting --> <max-size-bytes>-1</max-size-bytes> <message-counter-history-day-limit>10</message-counter-history-day-limit> <address-full-policy>PAGE</address-full-policy> <auto-create-queues>true</auto-create-queues> <auto-create-addresses>true</auto-create-addresses> <auto-create-jms-queues>true</auto-create-jms-queues> <auto-create-jms-topics>true</auto-create-jms-topics> </address-setting> </address-settings> </core> </configuration>
Service configuration:
sudo vim /etc/systemd/system/broker1.service
[Unit] Description=ActiveMQ-Broker After=network.target [Service] User=artemis WorkingDirectory=/opt/broker/broker1 ExecStart=/opt/broker/broker1/bin/artemis run [Install] WantedBy=multi-user.target
Enable the service
sudo systemctl daemon-reload sudo systemctl enable broker1 sudo systemctl start broker1
Configuration of Artemis
Add the following values to your Artemis config:
spring: websocket: broker: username: USERNAME password: PASSWORD addresses: "localhost:61613"
USERNAME
and PASSWORD
are the values used in step 5. Replace localhost if the broker runs on a separate machine.
File system¶
The last (and also easiest) part to configure is the file system: You have to provide a folder that is shared between all instances of the application server (e.g. by using NFS).
You then have to set the following values in the application config:
artemis: repo-clone-path: {{ artemis_repo_basepath }}/repos/ repo-download-clone-path: {{ artemis_repo_basepath }}/repos-download/ file-upload-path: {{ artemis_repo_basepath }}/uploads submission-export-path: {{ artemis_repo_basepath }}/exports
Where {{ artemis_repo_basepath }}
is the path to the shared folder
The file system stores (as its names suggests) files, these are e.g. submissions to file upload exercises, repositories that are checked out for the online editor, course icons, etc.
Scheduling¶
Artemis uses scheduled tasks in various scenarios: e.g. to lock repositories on due date, clean up unused resources, etc. As we now run multiple instances of Artemis, we have to ensure that the scheduled tasks are not executed multiple times. Artemis uses to approaches for this:
Tasks for quizzes (e.g. evaluation once the quiz is due) are automatically distributed (using Hazelcast)
Tasks for other exercises are only scheduled on one instance:
You must add the Scheduling
profile to exactly one instance of your cluster. This instance will then perform scheduled tasks whereas the other instances will not.
nginx configuration¶
You have to change the nginx configuration (of Artemis) to ensure that the load is distributed between all instances. This can be done by defining an upstream (containing all instances) and forwarding all requests to this upstream.
upstream artemis { server instance1:8080; server instance2:8080; }
Overview¶
All instances can now communicate with each other on 3 different layers:
Database cache
WebSockets
File system
You can see the state of all connected instances within the registry:
It relays message between instances:
Note
Be careful that you don’t commit changes to application-artemis.yml
.
To avoid this, follow the best practice when configuring your local development environment:
Create a file named
application-local.yml
undersrc/main/resources/config
.Copy the contents of
application-artemis.yml
into the new file.Update configuration values in
application-local.yml
.
By default, changes to application-local.yml
will be ignored by git so you don’t accidentally
share your credentials or other local configuration options.
If you use a password, you need to adapt it in
gradle/liquibase.gradle
.
Run the server via a run configuration in IntelliJ¶
The project comes with some pre-configured run / debug configurations that are stored in the .idea
directory.
When you import the project into IntelliJ the run configurations will also be imported.
The recommended way is to run the server and the client separated. This provides fast rebuilds of the server and hot module replacement in the client.
Artemis (Server): The server will be started separated from the client. The startup time decreases significantly.
Artemis (Client): Will execute
yarn install
andyarn start
. The client will be available at http://localhost:9000/ with hot module replacement enabled (also see Client Setup).
Other run / debug configurations¶
Artemis (Server & Client): Will start the server and the client. The client will be available at http://localhost:8080/ with hot module replacement disabled.
Artemis (Server, Jenkins & Gitlab): The server will be started separated from the client with the profiles
dev,jenkins,gitlab,artemis
instead ofdev,bamboo,bitbucket,jira,artemis
.Artemis (Server, Text Clustering): The server will be started separated from the client with
automaticText
profile enabled (see Text Assessment Clustering Service).
Typical problems with Liquibase checksums¶
One typical problem in the development setup is that an exception occurs during the database initialization. Artemis uses Liquibase to automatically upgrade the database scheme after changes to the data model. This ensures that the changes can also be applied to the production server. In case you encounter errors with liquibase checksum values, run the following command in your terminal / command line:
./gradlew liquibaseClearChecksums
Run the server with Spring Boot and Spring profiles¶
The Artemis server should startup by running the main class
de.tum.in.www1.artemis.ArtemisApp
using Spring Boot.
Note
Artemis uses Spring profiles to segregate parts of the
application configuration and make it only available in certain
environments. For development purposes, the following program arguments
can be used to enable the dev
profile and the profiles for JIRA,
Bitbucket and Bamboo:
--spring.profiles.active=dev,bamboo,bitbucket,jira,artemis,scheduling
If you use IntelliJ (Community or Ultimate) you can set the active profiles by
Choosing
Run | Edit Configurations...
Going to the
Configuration Tab
Expanding the
Environment
section to revealVM Options
and setting them to-Dspring.profiles.active=dev,bamboo,bitbucket,jira,artemis,scheduling
Set Spring profiles with IntelliJ Ultimate¶
If you use IntelliJ Ultimate, add the following entry to the section
Active Profiles
(within Spring Boot
) in the server run
configuration:
dev,bamboo,bitbucket,jira,artemis,scheduling
Run the server with the command line (Gradle wrapper)¶
If you want to run the application via the command line instead, make
sure to pass the active profiles to the gradlew
command like this:
./gradlew bootRun --args='--spring.profiles.active=dev,bamboo,bitbucket,jira,artemis,scheduling'
As an alternative, you might want to use Jenkins and Gitlab with an internal user management in Artemis, then you would use the profiles:
dev,jenkins,gitlab,artemis,scheduling
Client Setup¶
You need to install Node and Yarn on your local machine.
Using IntelliJ¶
If you are using IntelliJ you can use the pre-configured Artemis (Client)
run configuration that will be delivered with this repository:
Choose
Run | Edit Configurations...
Select the
Artemis (Client)
configuration from thenpm section
Now you can run the configuration in the upper right corner of IntelliJ
Using the command line¶
You should be able to run the following command to install development tools and dependencies. You will only need to run this command when dependencies change in package.json.
yarn install
To start the client application in the browser, use the following command:
yarn start
This compiles TypeScript code to JavaScript code, starts the hot module
replacement feature in Webpack (i.e. whenever you change a TypeScript
file and save, the client is automatically reloaded with the new code)
and will start the client application in your browser on
http://localhost:9000
. If you have activated the JIRA profile (see
above in Server Setup) and if you have configured
application-artemis.yml
correctly, then you should be able to login
with your TUM Online account.
For more information, review Working with Angular. For further instructions on how to develop with JHipster, have a look at Using JHipster in development.
Customize your Artemis instance¶
You can define the following custom assets for Artemis to be used instead of the TUM defaults:
The logo next to the “Artemis” heading on the navbar →
${artemisRunDirectory}/public/images/logo.png
The favicon →
${artemisRunDirectory}/public/images/favicon.ico
The privacy statement HTML →
${artemisRunDirectory}/public/content/privacy_statement.html
The contact email address in the
application-{dev,prod}.yml
configuration file under the keyinfo.contact
The imprint link in the
application-{dev,prod}.yml
configuration file under the keyinfo.imprint
Alternative: Using docker-compose¶
A full functioning development environment can also be set up using docker-compose:
Install docker and docker-compose
Configure the credentials in
application-artemis.yml
in the foldersrc/main/resources/config
as described aboveRun
docker-compose up
Go to http://localhost:9000
The client and the server will run in different containers. As yarn is
used with its live reload mode to build and run the client, any change
in the client’s codebase will trigger a rebuild automatically. In case
of changes in the codebase of the server one has to restart the
artemis-server
container via
docker-compose restart artemis-server
.
(Native) Running and Debugging from IDEs is currently not supported.
Get a shell into the containers:¶
app container:
docker exec -it $(docker-compose ps -q artemis-app) sh
mysql container:
docker exec -it $(docker-compose ps -q artemis-mysql) mysql
Other useful commands:¶
Stop the server:
docker-compose stop artemis-server
(restart viadocker-compose start artemis-server
)Stop the client:
docker-compose stop artemis-client
(restart viadocker-compose start artemis-client
)
Text Assessment Clustering Service¶
The semi-automatic text assessment relies on the Athene service. To enable automatic text assessments, special configuration is required:
Enable the automaticText
Spring profile:¶
--spring.profiles.active=dev,bamboo,bitbucket,jira,artemis,scheduling,automaticText
Configure API Endpoints:¶
The Athene service is running on a dedicated machine and is adressed via
HTTP. We need to extend the configuration in the file
src/main/resources/config/application-artemis.yml
like so:
artemis:
# ...
automatic-text:
segmentation-url: http://localhost:8000/segment
material-upload-url: http://localhost:8001/upload
embedding-url: http://localhost:8001/embed
embedding-chunk-size: 50
clustering-url: http://localhost:8002/cluster
secret: null
Using local user management¶
If you want to test in a local environment using different users, it makes sense to rely on local instead of external user management.
Go to the application-artemis.yml file, and set use-external in the user-management section to false.
Remove the jira profile from your local Run Configuration for the Server.

Remove the jira profile from the list shown in IntelliJ¶
Setup Guide for Guided Tutorials in Artemis¶
This guide gives you instructions on how to setup and create guided tutorials for Artemis:
Create GuidedTour object¶
A guided tutorial can be created by instantiating a GuidedTour
object.
This object has the mandatory attributes settingsKey
, the identifier for the tutorial which will be stored in the database, and steps
, which is an array that stores all tutorial steps.
A tutorial can have different types of tutorial steps:
TextTourStep
: tutorial step with only text contentImageTourStep
: tutorial step with text content and embedded imageVideoTourStep
: tutorial step with text content and embedded videoUserInteractionTourStep
: tutorial step which requires a certain interaction from the user to proceed to the next step.ModelingTaskTourStep
: tutorial step with text content and modeling task for the Apollon editor that is assessed for the stepAssessmentTaskTourStep
: tutorial step with text content and a tutor assessment task for example submissions (currently only implemented for text assessments).
Example implementation of a GuidedTour object¶
In this example, the GuidedTour
object is created and assigned to the constant exampleTutorial
, which one can use to embed the tutorial to a component of choice.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import { Orientation, UserInteractionEvent } from '../../src/main/webapp/app/guided-tour/guided-tour.constants';
import { GuidedTour } from '../../src/main/webapp/app/guided-tour/guided-tour.model';
import { ImageTourStep, ModelingTaskTourStep, TextTourStep, VideoTourStep } from '../../src/main/webapp/app/guided-tour/guided-tour-step.model';
import { GuidedTourModelingTask, personUML } from '../../src/main/webapp/app/guided-tour/guided-tour-task.model';
export const exampleTutorial: GuidedTour = {
settingsKey: 'example_tutorial',
steps: [
new TextTourStep({
highlightSelector: '.guided-tour-overview',
headlineTranslateKey: 'tour.courseOverview.overviewMenu.headline',
contentTranslateKey: 'tour.courseOverview.overviewMenu.content',
highlightPadding: 10,
orientation: Orientation.BOTTOM,
}),
new ImageTourStep({
headlineTranslateKey: 'tour.courseOverview.welcome.headline',
subHeadlineTranslateKey: 'tour.courseOverview.welcome.subHeadline',
contentTranslateKey: 'tour.courseOverview.welcome.content',
imageUrl: 'https://ase.in.tum.de/lehrstuhl_1/images/teaching/interactive/InteractiveLearning.png',
}),
new VideoTourStep({
headlineTranslateKey: 'tour.courseExerciseOverview.installPrerequisites.sourceTreeSetup.headline',
contentTranslateKey: 'tour.courseExerciseOverview.installPrerequisites.sourceTreeSetup.content',
hintTranslateKey: 'tour.courseExerciseOverview.installPrerequisites.sourceTreeSetup.hint',
videoUrl: 'tour.courseExerciseOverview.installPrerequisites.sourceTreeSetup.videoUrl',
}),
new ModelingTaskTourStep({
highlightSelector: 'jhi-modeling-editor .guided-tour.modeling-editor .modeling-editor',
headlineTranslateKey: 'tour.modelingExercise.executeTasks.headline',
contentTranslateKey: 'tour.modelingExercise.executeTasks.content',
highlightPadding: 5,
orientation: Orientation.TOP,
userInteractionEvent: UserInteractionEvent.MODELING,
modelingTask: new GuidedTourModelingTask(personUML.name, 'tour.modelingExercise.executeTasks.personClass'),
}),
// ...
],
};
|
Mandatory attributes¶
TextTourStep
: The mandatory fields areheadlineTranslateKey
andcontentTranslateKey
.ImageTourStep
: The ImageTourStep extends the TextTourStep and hasimageUrl
as an additional mandatory attribute.VideoTourStep
: The VideoTourStep extends the TextTourStep and hasvideoUrl
as an additional mandatory attribute.UserInterActionTourStep
: The UserInterActionTourStep extends the TextTourStep and is used to include interactions tasks for the user during the tour step. It has the additional mandatory attributeuserInteractionEvent
, which defines the interaction type, and the optional attributetriggerNextStep
.ModelingTaskTourStep
: The ModelingTaskTourStep extends the UserInterActionTourStep and hasmodelingTask
as an additional mandatory attribute.AssessmentTaskTourStep
: The AssessmentTaskTourStep extends the UserInterActionTourStep and hasassessmentTask
as an additional mandatory attribute.
Optional attributes¶
There are many optional attributes that can be defined for a tour step. These attributes and their definition can be found in the abstract class TourStep
.
Below, you can find a list of attributes that are used more often:
highlightSelector
: For thehighlightSelector
you have to enter a CSS selector for the HTML element that you want to highlight for this step. For better maintainability of the guided tutorials, it is strongly advised to create new selectors with the prefixguided-tour
within the DOM and use it as the highlight selector.orientation
: We can define an orientation for every tour step individually. The tour step orientation is used to define the position of the tour step next to highlighted element.highlightPadding
: This attribute sets the additional padding around the highlight element.userInteractionEvent
: Some steps require user interactions, e.g. certain click events, before the next tour step can be enabled. The supported user interactions are defined in the enumUserInteractionEvent
.pageUrl
: If you want to create a multi-page tutorial, i.e. a tutorial that guides the user through multiple component pages, then you have to use this attribute. ThepageUrl
should be added to the first tutorial step of every page and if the URL has identifiers in the URL such as course or exercise ids then these numbers should be replaced with the regex(\d+)+
. An example of multi-page tutorials can be found in thetutor-assessment-tour.ts
file.
Add translations¶
In order to allow internationalization, the values for the attributes headlineTranslateKey
, subHeadlineTranslateKey
, contentTranslateKey
and hintTranslateKey
reference the text snippets which are stored in JSON translation document.
Further attributes that need translations are videoUrl
for VideoTourStep
and taskTranslateKey
for the modelingTask
in the ModelingTaskTourStep
.
One JSON document that is used for the translations of guided tutorials is the file guidedTour.json
.
Embed in component file¶
There are multiple service methods to embed a guided tutorial in an application component file. We use the GuidedTutorialService in the component through dependency injection and invoke the fitting method to enable the tutorial for the component:
The enableTourForCourseOverview
method is used when the tutorial should be enabled for a certain course in a component, which displays a list of courses (e.g. overview.component.ts
).
It returns the course for which the tutorial is enabled, if available, otherwise null.
public enableTourForCourseOverview(courses: Course[], guidedTour: GuidedTour, init: boolean): Course | null {
The enableTourForCourseExerciseComponent
method is used when the tutorial should be enabled for a certain course and exercise in a component, which displays a list of exercises for a course (e.g. course-exercises.component.ts
).
It returns the exercise for which the tutorial is enabled, if available, otherwise null.
public enableTourForCourseExerciseComponent(course: Course | null, guidedTour: GuidedTour, init: boolean): Exercise | null {
The enableTourForExercise
method is used when the tutorial should be enabled for a certain exercise (e.g. course-exercise-details.component.ts
).
It returns the exercise for which the tutorial is enabled, if available, otherwise null.
public enableTourForExercise(exercise: Exercise, guidedTour: GuidedTour, init: boolean) {
Example of integrating the GuidedTour exampleTutorial
into a component file¶
constructor( private guidedTourService: GuidedTourService ) {}
...
this.courseForGuidedTour = this.guidedTourService.enableTourForCourseOverview(this.courses, exampleTutorial, true);
Extend configuration file¶
The mapping of guided tutorials to certain courses and exercises is configured in the application-dev.yml
and application-prod.yml
files.
The yaml configuration below shows that the guided tutorials are only enabled for the course with the short name artemistutorial
.
The configuration for tours
shows a list of mappings tutorialSettingsKey
→ exerciseIdentifier
. The exerciseIdentifier
for programming exercises is the exercise short name, otherwise it’s the exercise title.
info:
guided-tour:
courseShortName: 'artemistutorial'
tours:
- cancel_tour: ''
- code_editor_tour: 'tutorial'
- course_overview_tour: ''
- course_exercise_overview_tour: 'tutorial'
- modeling_tour: 'UML Class Diagram'
- programming_exercise_fail_tour: 'tutorial'
- programming_exercise_success_tour: 'tutorial'
- tutor_assessment_tour: 'Patterns in Software Engineering'
Writing test cases for guided tutorials¶
Through Jest client tests it is possible to start the guided tutorials and go through all the tutorial steps while checking for the highlight selectors.
An example test suite for the courseOverviewTour
can be found in the overview.component.spec.ts
file.
User Registration¶
Artemis supports user registration based on the Jhipster template.
User registration has to be enabled in one application-*.yml
file and can be customized.
Example:
artemis:
user-management:
use-external: false
registration:
enabled: true
allowed-email-pattern: '[a-zA-Z0-9_\-\.\+]+@(tum\.de|in\.tum\.de|mytum\.de)'
allowed-email-pattern-readable: '@tum.de, @in.tum.de, @mytum.de'
spring:
mail:
host: <host>
port: 25
username: <username>
password: <password>
protocol: smtp
tls: true
properties.mail.smtp:
auth: true
starttls:
enable: true
ssl:
trust: <host>
jhipster:
mail:
base-url: https://artemis.ase.in.tum.de
from: artemis.in@tum.de
Users can register a new account on the start page based on allowed-email-pattern
.
If no email pattern is defined, any email address can be used.
Upon registration, users receive an email to activate their account.
You can find more information on how to configure the email server on the official Jhipster documentation.