diff --git a/.gitpod.yml b/.gitpod.yml
index 9f6da64..6e0cc81 100644
--- a/.gitpod.yml
+++ b/.gitpod.yml
@@ -1,6 +1,6 @@
# Image of workspace. Learn more: https://www.gitpod.io/docs/configure/workspaces/workspace-image
image: maeddes/gitpod:full
-workspaceLocation: '/workspace/otel-getting-started/labs'
+workspaceLocation: '/workspace/otel-getting-started'
tasks:
- name: Add Python Otel libs
@@ -9,4 +9,4 @@ tasks:
init: echo 127.0.0.1 httpbin | sudo tee -a /etc/hosts
command: docker run -p 80:80 kennethreitz/httpbin
- name: Start tutorial
- command: docker compose up tutorial
\ No newline at end of file
+ command: docker compose up tutorial
diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/Dockerfile b/labs/automatic-instrumentation/solution/todobackend-springboot/Dockerfile
new file mode 100644
index 0000000..b7beec4
--- /dev/null
+++ b/labs/automatic-instrumentation/solution/todobackend-springboot/Dockerfile
@@ -0,0 +1,23 @@
+FROM docker.io/maven:3-eclipse-temurin-21 as build
+WORKDIR /workspace/app
+
+COPY pom.xml .
+COPY src src
+
+RUN --mount=type=cache,target=/root/.m2 mvn install -DskipTests
+RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
+
+FROM docker.io/eclipse-temurin:21-jdk-alpine
+RUN mkdir -p /opt/todobackend
+WORKDIR /opt/todobackend
+#RUN addgroup -S demo && adduser -S demo -G demo
+#USER demo
+VOLUME /tmp
+ARG DEPENDENCY=/workspace/app/target/dependency
+COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /opt/todobackend/app/lib
+COPY --from=build ${DEPENDENCY}/META-INF /opt/todobackend/app/META-INF
+COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /opt/todobackend/app
+
+ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar /opt/todobackend
+
+ENTRYPOINT ["java", "-cp", "/opt/todobackend/app:/opt/todobackend/app/lib/*", "-javaagent:/opt/todobackend/opentelemetry-javaagent.jar","io.novatec.todobackend.TodobackendApplication"]
\ No newline at end of file
diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/pom.xml b/labs/automatic-instrumentation/solution/todobackend-springboot/pom.xml
new file mode 100644
index 0000000..79c0651
--- /dev/null
+++ b/labs/automatic-instrumentation/solution/todobackend-springboot/pom.xml
@@ -0,0 +1,74 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.2
+
+
+
+ io.novatec
+ todobackend
+ 0.0.1-SNAPSHOT
+ todobackend
+ Novatec Demo Application
+
+
+ 21
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.postgresql
+ postgresql
+ runtime
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-ui
+ 2.2.0
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ io.opentelemetry.instrumentation
+ opentelemetry-instrumentation-annotations
+ 1.29.0
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java
new file mode 100644
index 0000000..b058c45
--- /dev/null
+++ b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/java/io/novatec/todobackend/TodobackendApplication.java
@@ -0,0 +1,144 @@
+package io.novatec.todobackend;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.web.bind.annotation.*;
+
+import io.opentelemetry.instrumentation.annotations.SpanAttribute;
+import io.opentelemetry.instrumentation.annotations.WithSpan;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+
+@SpringBootApplication
+@RestController
+@CrossOrigin(origins = "*")
+
+public class TodobackendApplication {
+
+ private Logger logger = LoggerFactory.getLogger(TodobackendApplication.class);
+
+ @Value("${HOSTNAME:not_set}")
+ String hostname;
+
+ @Value("${spring.profiles.active: none}")
+ String profile;
+
+ @Autowired
+ TodoRepository todoRepository;
+
+ private String getInstanceId() {
+
+ if (!hostname.equals("not_set"))
+ return hostname;
+ return "probably localhost";
+
+ }
+
+ @GetMapping("/hello")
+ String hello() {
+
+ return getInstanceId() + " Hallo, Welt ! ";
+
+ }
+
+ @GetMapping("/fail")
+ String fail() {
+
+ System.exit(1);
+ return "fixed!";
+ }
+
+ @GetMapping("/todos/")
+ List getTodos(){
+
+ logger.info(cfInstance);
+
+ List todos = new ArrayList();
+
+ todoRepository.findAll().forEach(todo -> todos.add(todo.getTodo()));
+ logger.info("GET /todos/ "+todos.toString());
+
+
+ return todos;
+ }
+
+ @PostMapping("/todos/{todo}")
+ String addTodo(@PathVariable String todo){
+
+ this.someInternalMethod(todo);
+ //todoRepository.save(new Todo(todo));
+ logger.info("POST /todos/ "+todo.toString());
+
+ return todo;
+
+ }
+
+ @WithSpan
+ String someInternalMethod(@SpanAttribute String todo){
+
+ todoRepository.save(new Todo(todo));
+ if(todo.equals("slow")){
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ if(todo.equals("fail")){
+
+ System.out.println("Failing ...");
+ throw new RuntimeException();
+
+ }
+ return todo;
+
+ }
+
+ @DeleteMapping("/todos/{todo}")
+ String removeTodo(@PathVariable String todo) {
+
+ todoRepository.deleteById(todo);
+ logger.info("DELETE /todos/ "+todo.toString());
+ return "removed "+todo;
+
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(TodobackendApplication.class, args);
+ }
+}
+
+@Entity
+class Todo{
+
+ @Id
+ String todo;
+
+ public Todo(){}
+
+ public Todo(String todo){
+ this.todo = todo;
+ }
+
+ public String getTodo(){
+ return todo;
+ }
+
+ public void setTodo(String todo) {
+ this.todo = todo;
+ }
+
+}
+
+interface TodoRepository extends CrudRepository {
+
+}
\ No newline at end of file
diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application-dev.properties b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application-dev.properties
new file mode 100644
index 0000000..25d7606
--- /dev/null
+++ b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application-dev.properties
@@ -0,0 +1,5 @@
+spring.h2.console.enabled=true
+spring.h2.console.path=/h2
+spring.datasource.url=jdbc:h2:mem:testdb
+spring.datasource.username=sa
+spring.datasource.password=
\ No newline at end of file
diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application-prod.properties b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application-prod.properties
new file mode 100644
index 0000000..6806431
--- /dev/null
+++ b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application-prod.properties
@@ -0,0 +1,3 @@
+spring.datasource.url= jdbc:postgresql://${POSTGRES_HOST:postgresdb}:5432/mydb
+spring.datasource.username=matthias
+spring.datasource.password=password
\ No newline at end of file
diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application.properties b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application.properties
new file mode 100644
index 0000000..eaa2173
--- /dev/null
+++ b/labs/automatic-instrumentation/solution/todobackend-springboot/src/main/resources/application.properties
@@ -0,0 +1,13 @@
+server.port=8080
+
+server.forward-headers-strategy=native
+management.endpoints.web.exposure.include=*
+
+spring.profiles.active=dev
+
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.show-sql=true
+#spring.jpa.properties.hibernate.format_sql=true
+
+spring.application.name=springboot-backend
+otel.exporter.otlp.endpoint=http://${COLLECTOR_HOST:localhost}:4317
diff --git a/labs/automatic-instrumentation/solution/todobackend-springboot/src/test/java/io/novatec/todobackend/TodobackendApplicationIntegrationTests.java b/labs/automatic-instrumentation/solution/todobackend-springboot/src/test/java/io/novatec/todobackend/TodobackendApplicationIntegrationTests.java
new file mode 100755
index 0000000..b18589d
--- /dev/null
+++ b/labs/automatic-instrumentation/solution/todobackend-springboot/src/test/java/io/novatec/todobackend/TodobackendApplicationIntegrationTests.java
@@ -0,0 +1,12 @@
+package io.novatec.todobackend;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+public class TodobackendApplicationIntegrationTests {
+
+ @Test
+ void contextLoads() {
+ }
+}
\ No newline at end of file