Import von bestehenden CSV-Dateien

- CSV-Dateien im Verzeichniss "import" werden automatisch eingelesen
This commit is contained in:
Matthias Engelien committed 2024-09-08 15:13:20 +02:00
1 parent 1f7dfee78f
commit a0cf2d1854
14 files changed
+409 -12

No files matched your search

+23 -12
View File
@@ -22,6 +22,7 @@
</properties>
<dependencies>
<!-- Spring libs -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@@ -30,18 +31,12 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- CSV handling -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-csv</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- OpenAPI generation -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
@@ -52,7 +47,18 @@
<artifactId>jackson-databind-nullable</artifactId>
<version>0.2.6</version>
</dependency>
<!-- DB driver - change to other driver on DB change -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- confinience -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- testing -->
<dependency>
@@ -60,6 +66,11 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@@ -79,7 +90,7 @@
</inputSpec>
<generatorName>spring</generatorName>
<apiPackage>de.etecture.ga.api</apiPackage>
<modelPackage>de.etecture.ga.model</modelPackage>
<modelPackage>de.etecture.ga.dto</modelPackage>
<supportingFilesToGenerate>
ApiUtil.java
</supportingFilesToGenerate>
@@ -0,0 +1,46 @@
/**
*
*/
package de.etecture.ga.api;
import java.util.List;
import org.springframework.http.ResponseEntity;
import de.etecture.ga.dto.Termin;
import de.etecture.ga.dto.TerminRequest;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
/**
*
*/
public class GarageApiController implements WerkstattApi {
@Override
public ResponseEntity<Termin> getTermin(String werkstattId, String terminId) {
// TODO Auto-generated method stub
return WerkstattApi.super.getTermin(werkstattId, terminId);
}
@Override
public ResponseEntity<List<Termin>> getTermine(String werkstattId, @Valid String von, @Valid String bis,
@Valid String leistungsId) {
// TODO Auto-generated method stub
return WerkstattApi.super.getTermine(werkstattId, von, bis, leistungsId);
}
@Override
public ResponseEntity<List<Termin>> getTerminvorschlaege(String werkstattId, @NotNull @Valid String leistungsId,
@Valid String von, @Valid String bis) {
// TODO Auto-generated method stub
return WerkstattApi.super.getTerminvorschlaege(werkstattId, leistungsId, von, bis);
}
@Override
public ResponseEntity<Termin> postTermin(String werkstattId, @Valid TerminRequest termin) {
// TODO Auto-generated method stub
return WerkstattApi.super.postTermin(werkstattId, termin);
}
}
@@ -0,0 +1,29 @@
package de.etecture.ga.config;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import de.etecture.ga.model.Garage;
import de.etecture.ga.service.GarageImportService;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class Setup {
@Autowired
private GarageImportService importService;
@PostConstruct
private void setupData() {
List<Garage> garages = importService.importGarageData();
// Daten in DB übertragen
}
}
@@ -0,0 +1,25 @@
package de.etecture.ga.model;
import java.time.Duration;
import java.util.Date;
import org.springframework.data.annotation.Id;
import lombok.Data;
@Data
public class Appointment {
@Id
private Long id;
private Garage garage;
private String serviceCode;
private String serviceName;
private Date appointmentTime;
private Duration duration;
}
@@ -0,0 +1,29 @@
package de.etecture.ga.model;
import java.util.ArrayList;
import java.util.List;
import org.springframework.data.annotation.Id;
import lombok.Data;
@Data
public class Garage {
@Id
private Long id;
private String name;
private List<Appointment> appointments;
public Garage addAppointment(Appointment appointment) {
if(this.appointments == null) {
this.appointments = new ArrayList<>();
}
this.appointments.add(appointment);
return this;
}
}
@@ -0,0 +1,20 @@
package de.etecture.ga.model;
import java.time.Duration;
import org.springframework.data.annotation.Id;
import lombok.Data;
@Data
public class MDService {
@Id
private Long id;
private String code;
private String name;
private Duration duration;
}
@@ -0,0 +1,105 @@
package de.etecture.ga.service;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import de.etecture.ga.model.Appointment;
import de.etecture.ga.model.Garage;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class GarageImportService {
private static final String IMPORT_FOLDER = "import";
public List<Garage> importGarageData() {
List<Garage> importData = new ArrayList<>();
try (Stream<Path> files = Files
.list(Paths.get(getClass().getClassLoader().getResource(IMPORT_FOLDER).toURI()))) {
files.filter(Files::isRegularFile).filter(path -> path.toString().endsWith(".csv"))
.map(this::loadGarageData).<Garage>mapMulti(Optional::ifPresent).forEach(importData::add);
} catch (IOException | URISyntaxException e) {
log.error("Can't read file", e);
}
return importData;
}
public Optional<Garage> loadGarageData(final Path file) {
Garage garage = new Garage();
garage.setName(getGarageNameFromFile(file));
List<CSVData> appointments = loadObjectsFromFile(file);
appointments.stream().map(data -> this.fromCSVData(data, garage)).filter(Objects::nonNull)
.forEach(garage::addAppointment);
return Optional.of(garage);
}
private String getGarageNameFromFile(final Path fileName) {
String name = fileName.getFileName().toString();
int pos = name.lastIndexOf(".");
if (pos > 0 && pos < (name.length() - 1)) {
name = name.substring(0, pos);
}
return name;
}
private List<CSVData> loadObjectsFromFile(final Path file) {
try {
CsvSchema bootstrapSchema = CsvSchema.emptySchema().withHeader();
CsvMapper mapper = new CsvMapper();
MappingIterator<CSVData> readValues = mapper.readerFor(CSVData.class).with(bootstrapSchema)
.readValues(file.toFile());
return readValues.readAll();
} catch (Exception e) {
log.error("Error occurred while loading object list from file {}", file, e);
return Collections.emptyList();
}
}
private Appointment fromCSVData(CSVData data, Garage forGarage) {
if (data == null)
return null;
Appointment appointment = new Appointment();
appointment.setGarage(forGarage);
appointment.setAppointmentTime(data.APP_DATE);
appointment.setServiceCode(data.SERVICE);
return appointment;
}
private record CSVData(Date APP_DATE, String SERVICE) {
}
}
@@ -1 +1,10 @@
spring.application.name=Garage appointment management
# Datasource settings
spring.datasource.url=jdbc:h2:mem:etecture
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
# init DB by script
spring.sql.init.mode=always
File renamed without changes.
Internal Server Error - Gitea: Git with a cup of tea
500 Internal Server Error

An error occurred:

An error occurred

Gitea Version: 28.1.0