Skip to content

Commit

Permalink
Add code from Spring Boot live demo
Browse files Browse the repository at this point in the history
* refactored and commented for assignment 4
  • Loading branch information
sbaltes committed May 22, 2024
1 parent 0ec0c4a commit 9aef0ca
Show file tree
Hide file tree
Showing 22 changed files with 450 additions and 164 deletions.
12 changes: 3 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,13 @@ curl http://localhost:8080/list
### Append to list

```bash
curl --header "Content-Type: application/json" --request POST --data '[0.5, 0.6]' http://localhost:8080/list
curl --header "Content-Type: application/json" --request POST --data '[{"value": 0.5, "metadata": ""}, {"value": 0.6, "metadata": ""}]' http://localhost:8080/list
```

### Append to list with verbose output
### Append to list (malformed body)

```bash
curl --verbose --header "Content-Type: application/json" --request POST --data '[0.5, 0.6]' http://localhost:8080/list
```

### Append to list with verbose output (malformed body)

```bash
curl --verbose --header "Content-Type: application/json" --request POST --data '[0.5, 0.6' http://localhost:8080/list
curl --header "Content-Type: application/json" --request POST --data '[{"value": 0.5; "metadata": ""}]' http://localhost:8080/list
```

### Clear list
Expand Down
32 changes: 32 additions & 0 deletions api/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>de.unibayreuth.se.teaching.list</groupId>
<artifactId>parent</artifactId>
<version>0.5.0</version>
</parent>

<artifactId>api</artifactId>

<dependencies>
<dependency>
<groupId>de.unibayreuth.se.teaching.list</groupId>
<artifactId>business</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${springdoc.openapi.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package de.unibayreuth.se.teaching.list.api.controller;

import de.unibayreuth.se.teaching.list.api.dto.ListElementDto;
import de.unibayreuth.se.teaching.list.business.ports.ListService;
import de.unibayreuth.se.teaching.list.business.ports.Value;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;

@Controller
@RequiredArgsConstructor
public class ListController {
private final ListService listService;

@GetMapping(value = "/list")
public ResponseEntity<List<ListElementDto>> getList() {
return ResponseEntity.ok(listService.get().stream()
// this::toDto is short for "apply that method to all elements in the stream"
// in this case: map(element -> toDto(element)
.map(this::toDto)
.toList()
);
}

@PostMapping(value = "/list")
public ResponseEntity<List<ListElementDto>> appendList(@RequestBody List<ListElementDto> elements) {
listService.append(elements.stream()
.map(this::toValue)
.toList()
);
// ResponseEntity.ok(...) is a shortcut for "create a response entity with status 200 (OK) and the provided body
return ResponseEntity.ok(listService.get().stream()
.map(this::toDto)
.toList());
}

/**
* Mapper function to convert a Value to a ListElementDto.
* @param value the Value object (from the business layer) to map to a ListElementDto
* @return the mapped ListElementDto
*/
private ListElementDto toDto(Value value) {
return new ListElementDto(value.getDoubleValue(), "");
}

/**
* Mapper function to convert a ListElementDto to a Value.
* @param dto the ListElementDto object to map to a Value object (for the business layer)
* @return the mapped Value object
*/
private Value toValue(ListElementDto dto) {
return new Value(dto.value());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package de.unibayreuth.se.teaching.list.api.dto;

/**
* Data transfer object for list elements, to be used in the list controller API endpoints.
*
* @param value The value of the list element.
* @param metadata Metadata of the list element (to showcase the DTO might look different from the internal data model).
*/
public record ListElementDto(double value, String metadata) {

}
48 changes: 48 additions & 0 deletions application/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>de.unibayreuth.se.teaching.list</groupId>
<artifactId>parent</artifactId>
<version>0.5.0</version>
</parent>

<artifactId>application</artifactId>

<dependencies>
<dependency>
<groupId>de.unibayreuth.se.teaching.list</groupId>
<artifactId>business</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>de.unibayreuth.se.teaching.list</groupId>
<artifactId>api</artifactId>
<version>${project.version}</version>
</dependency>
<!--dependency>
<groupId>de.unibayreuth.se.teaching.list</groupId>
<artifactId>data</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* Main class to start the Spring Boot application in production.
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
Expand Down
15 changes: 15 additions & 0 deletions application/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
spring:
application:
name: se24-demo
#datasource:
# driver-class-name: org.postgresql.Driver
#flyway:
# enabled: true
# locations: classpath:db/migration
# validate-on-migrate: true

#springdoc:
# api-docs:
# path: /api-docs
# swagger-ui:
# path: /swagger-ui.html
30 changes: 30 additions & 0 deletions business/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>de.unibayreuth.se.teaching.list</groupId>
<artifactId>parent</artifactId>
<version>0.5.0</version>
</parent>

<artifactId>business</artifactId>

<properties>
<maven.cucumber.testsuite>de.unibayreuth.se.teaching.list.business.impl.CucumberListTestRunner</maven.cucumber.testsuite>
</properties>


<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.plugin.surefire.version}</version>
<configuration>
<test>${maven.cucumber.testsuite}</test>
</configuration>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
package de.unibayreuth.se.teaching.list;
package de.unibayreuth.se.teaching.list.business.impl;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
* Doubly linked list
* Our doubly linked list implementation from previous assignments.
*/
@Getter
@Setter
@Slf4j
@Component
public class DoublyLinkedList {
private Element start;
private Element end;
Expand Down Expand Up @@ -137,7 +139,7 @@ public boolean isEmpty() {
}

/**
* Add an element at the correct position in a sorted list
* Insert an element at the correct position in a sorted list
* @param e Element to insert into the sorted list
*/
public void insert(Element e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package de.unibayreuth.se.teaching.list.business.impl;

import de.unibayreuth.se.teaching.list.business.ports.ListService;
import de.unibayreuth.se.teaching.list.business.ports.Value;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

@Service
@RequiredArgsConstructor
public class ListServiceImpl implements ListService {
private final DoublyLinkedList list;

@Override
public List<Value> get() {
return Arrays.stream(list.asArray())
// Our list uses the primitive type "double" but streams require the reference type "Double."
// Related concept: Autoboxing (https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html)
.boxed()
.map(Value::new) // same shortcut as used in the controller, here: call constructor with value as argument
.toList();
}

@Override
public void append(List<Value> valuesToAppend) {
valuesToAppend.forEach(
value -> list.append(value.getDoubleValue())
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package de.unibayreuth.se.teaching.list.business.ports;

import java.util.List;

/**
* Interface for the implementation of the list service that the business layer provides as a port.
*/
public interface ListService {
List<Value> get();
void append(List<Value> valuesToAppend);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package de.unibayreuth.se.teaching.list.business.ports;

import lombok.Data;

/**
* Class which stores the value of a list element.
*/
@Data
public class Value {
private final Double doubleValue;
private Long longValue; // example for a derived value that the business layer might provide
}
Loading

0 comments on commit 9aef0ca

Please sign in to comment.