<repo_name>timleschinsky/se-server<file_sep>/settings.gradle
rootProject.name = 'se_spring_demo'

<file_sep>/src/main/java/com/ovgu/se/openapispringboot/demo/model/ItemDbo.java
package com.ovgu.se.openapispringboot.demo.model;

import io.swagger.models.auth.In;
import lombok.*;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.math.BigDecimal;
import java.time.LocalDate;

@AllArgsConstructor
@NoArgsConstructor
@Entity
@Data
@Builder
public class ItemDbo {

    @Id
    @GeneratedValue
    private Integer id;

    @Column(unique = true)
    private String name;

    private String description;

    private Double price;

    private Double tax;

    private LocalDate listedSince;

    private String manufacturer;

    public Item toItem() {
        return new Item()
                .id(id)
                .name(name)
                .price(price)
                .tax(tax)
                .listedSince(listedSince)
                .manufacturer(manufacturer)
                .description(description);
    }

    public ItemDbo(Item item) {
        name = item.getName();
        description = item.getDescription();
        price = item.getPrice();
        tax = item.getTax();
        listedSince = LocalDate.now();
        manufacturer = item.getManufacturer();
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }
}
<file_sep>/src/main/java/com/ovgu/se/openapispringboot/demo/data/ItemRepository.java
package com.ovgu.se.openapispringboot.demo.data;

import com.ovgu.se.openapispringboot.demo.model.ItemDbo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.List;

@Transactional
public interface ItemRepository extends JpaRepository<ItemDbo, Integer> {

    @Query("SELECT i FROM ItemDbo i WHERE (:name is null or i.name = :name) and (:manufacturer is null"
            + " or i.manufacturer = :manufacturer) and (:description is null or i.description = :description)" +
            "and (:priceGe is null or i.price > :priceGe) and (:priceLe is null or i.price < :priceLe)")
    List<ItemDbo> findByNameAndManufacturerAndDescriptionAndPriceIsBetween(
            @Param("name") String name,
            @Param("manufacturer") String manufacturer,
            @Param("description") String description,
            @Param("priceGe") Double priceGe,
            @Param("priceLe") Double priceLe);
}
<file_sep>/Dockerfile
FROM openjdk:11.0.8-slim
VOLUME /tmp
COPY / /build/
RUN cd /build && ./gradlew bootJar && cp build/libs/*.jar /app.jar && cd .. && rm -rf /build
ENTRYPOINT ["java","-jar","/app.jar"]
EXPOSE 8080
<file_sep>/src/main/java/com/ovgu/se/openapispringboot/demo/service/ItemApiImpl.java
package com.ovgu.se.openapispringboot.demo.service;

import com.ovgu.se.openapispringboot.demo.data.ItemRepository;
import com.ovgu.se.openapispringboot.demo.api.ItemApiDelegate;
import com.ovgu.se.openapispringboot.demo.model.Item;
import com.ovgu.se.openapispringboot.demo.model.ItemDbo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ItemApiImpl implements ItemApiDelegate {

    private final ItemRepository itemRepository;
    private final Logger log = LoggerFactory.getLogger(ItemApiImpl.class);

    @Autowired
    public ItemApiImpl(ItemRepository itemRepository) {
        this.itemRepository = itemRepository;
    }

    @Override
    public ResponseEntity<Item> createItem(Item item) {
        ItemDbo savedItem = new ItemDbo(item);
        savedItem = itemRepository.save(savedItem);
        log.info("Item posted");
        return ResponseEntity.ok(savedItem.toItem());
    }

    @Override
    public ResponseEntity<Void> deleteItem(Integer id) {
        log.info("ID: {} will be deleted", id);
        ItemDbo itemDbo = itemRepository.findById(id).orElseThrow();
        itemRepository.delete(itemDbo);
        log.info("Item deleted");
        return ResponseEntity.ok().build();
    }

    @Override
    public ResponseEntity<Item> getItem(Integer id) {
        log.info("Item {} get", id);
        ItemDbo itemDbo = itemRepository.findById(id).orElseThrow();
        return ResponseEntity.ok(itemDbo.toItem());
    }

    @Override
    public ResponseEntity<List<Item>> getItems(String name, String manufacturer, String description, Double priceGe, Double priceLe) {
        log.info("Items get");
        List<Item> itemList = itemRepository
                .findByNameAndManufacturerAndDescriptionAndPriceIsBetween(name, manufacturer, description, priceGe, priceLe)
                .parallelStream()
                .map(ItemDbo::toItem).collect(Collectors.toUnmodifiableList());
        return ResponseEntity.ok(itemList);
    }

    @Override
    public ResponseEntity<Item> updateItem(Integer id, Item item) {
        log.info("Item {} updating", id);
        ItemDbo itemDbo = itemRepository.findById(id).orElseThrow();
        itemDbo.setDescription(item.getDescription());
        itemDbo.setManufacturer(item.getManufacturer());
        itemDbo.setName(item.getName());
        itemDbo.setTax(item.getTax());
        itemDbo.setPrice(item.getPrice());
        itemDbo = itemRepository.save(itemDbo);
        log.info("Item updated");
        return ResponseEntity.ok(itemDbo.toItem());
    }
}
<file_sep>/build.gradle
plugins {
    id 'java'
    id "org.openapi.generator" version "4.3.1"
    id 'org.springframework.boot' version '2.3.2.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
}

group = 'com.ovgu.se.openapispringboot.demo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.0.1.RELEASE'
    implementation 'org.springframework.boot:spring-boot-starter-web:2.0.1.RELEASE'
    runtimeOnly 'com.h2database:h2'
    implementation "io.springfox:springfox-swagger2:2.8.0"
    implementation "io.springfox:springfox-swagger-ui:2.8.0"
    implementation "org.openapitools:jackson-databind-nullable:0.1.0"
    implementation "javax.validation:validation-api"
    implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

openApiGenerate {
    generatorName = "spring"
    inputSpec = "openapi.json"
    outputDir = "$buildDir/generated"
    configOptions = [
            basePackage            : "com.ovgu.se.openapispringboot.demo",
            apiPackage             : "com.ovgu.se.openapispringboot.demo.api",
            configPackage          : "com.ovgu.se.openapispringboot.demo.config",
            modelPackage           : "com.ovgu.se.openapispringboot.demo.model",
            hideGenerationTimestamp: "true",
            dateLibrary            : "java8",
            delegatePattern        : "true"
    ]
    systemProperties = [
            modelTests     : "false",
            modelDocs      : "false",
            apiTests       : "false",
            apiDocs        : "false"
    ]
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn tasks.openApiGenerate
}

sourceSets.main.java.srcDirs += "$buildDir/generated/src/main/java"
<file_sep>/README.md
# Spring Demo Server for SE Summer term 2020

## Build
- Build by `gradle build`.
- Create JAR by `gradle build bootJar`

## Build Docker
- Build this app to a Docker container with the included Dockerfile
- This is done automatically with the Docker automated build as image `tbd`.

## Run
- Run by `gradle bootRun`
<file_sep>/src/main/resources/application.properties
springfox.documentation.swagger.v2.path=/api-docs
server.port=8080
spring.jackson.date-format=com.ovgu.se.openapispringboot.demo.RFC3339DateFormat
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
server.servlet.contextPath=/api/spring
spring.profiles.active=development
