diff --git a/pom.xml b/pom.xml index b9ce463c2..e3b302d74 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,8 @@ ${maven.build.timestamp} dd.MM.yyyy HH:mm 17 + 1.5.5.Final + 5.6.14.Final @@ -225,7 +227,11 @@ bootstrap-icons 1.11.3 - + + org.mapstruct + mapstruct + ${org.mapstruct.version} + @@ -273,6 +279,43 @@ + + + org.apache.maven.plugins + maven-compiler-plugin + + + 17 + 17 + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + org.projectlombok + lombok + 1.18.26 + + + org.hibernate + hibernate-jpamodelgen + ${org.hibernate.version} + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + + + + + + maven-surefire-plugin + + -Dspring.profiles.active=test + diff --git a/src/main/java/org/tb/common/configuration/LocalDevSecurityConfiguration.java b/src/main/java/org/tb/common/configuration/LocalDevSecurityConfiguration.java index 0c12a8905..243086ba3 100644 --- a/src/main/java/org/tb/common/configuration/LocalDevSecurityConfiguration.java +++ b/src/main/java/org/tb/common/configuration/LocalDevSecurityConfiguration.java @@ -35,7 +35,7 @@ public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager @Bean public WebSecurityCustomizer ignoringCustomizer() { - return (web) -> web.ignoring().antMatchers("*.png", "/images/**", "/style/**", "/scripts/**", "/webjars/**", "/favicon.ico"); + return (web) -> web.ignoring().antMatchers("*.png", "/images/**", "/style/**", "/scripts/**", "/webjars/**", "/favicon.ico","/rest/doc/**"); } @Bean diff --git a/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteDto.java b/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteDto.java new file mode 100644 index 000000000..86f8ee705 --- /dev/null +++ b/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteDto.java @@ -0,0 +1,23 @@ +package org.tb.rest.favorites.adapter_rest; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.FieldDefaults; + +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Data +@FieldDefaults(level = AccessLevel.PRIVATE) +@Schema(description = "to save your favorite reports", name = "Favorite") +public class FavoriteDto { + Long id; + Long employeeorderId; + int hours; + int minutes; + String comment; +} diff --git a/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteDtoMapper.java b/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteDtoMapper.java new file mode 100644 index 000000000..3ae2f74b6 --- /dev/null +++ b/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteDtoMapper.java @@ -0,0 +1,21 @@ +package org.tb.rest.favorites.adapter_rest; + +import java.util.Collection; +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.ReportingPolicy; +import org.tb.rest.favorites.core.Favorite; + +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface FavoriteDtoMapper { + + FavoriteDto map(Favorite favorite); + Favorite map(FavoriteDto favorite); + + Collection map(Collection favorites); + + +} diff --git a/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteRestEndpoint.java b/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteRestEndpoint.java new file mode 100644 index 000000000..b294ec455 --- /dev/null +++ b/src/main/java/org/tb/rest/favorites/adapter_rest/FavoriteRestEndpoint.java @@ -0,0 +1,63 @@ +package org.tb.rest.favorites.adapter_rest; + +import static org.springframework.http.HttpStatus.UNAUTHORIZED; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.Collection; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.mapstruct.factory.Mappers; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; +import org.tb.auth.AuthorizedUser; +import org.tb.rest.favorites.core.FavoriteService; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping(path = "/rest/favorite") +@SecurityRequirement(name = "bearerAuth") +@Tag(name = "favorite") +public class FavoriteRestEndpoint { + + private final FavoriteService favoriteService; + private final FavoriteDtoMapper favoriteDtoMapper = Mappers.getMapper(FavoriteDtoMapper.class); + private final AuthorizedUser authorizedUser; + + @GetMapping(path = "", produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.OK) + @Operation(security = {@SecurityRequirement(name = "bearerAuth")}) + public Collection getFavorites() { + if(!authorizedUser.isAuthenticated()) { + throw new ResponseStatusException(UNAUTHORIZED); + } + return favoriteDtoMapper.map(favoriteService.getFavorites(authorizedUser.getEmployeeId())); + } + + @PutMapping(path = "", consumes = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.CREATED) + @Operation(security = {@SecurityRequirement(name = "bearerAuth")}) + public FavoriteDto addFavorite(@RequestBody FavoriteDto favorite) { + return favoriteDtoMapper.map(favoriteService.addFavorite(favoriteDtoMapper.map(favorite))); + } + + @DeleteMapping(path = "/{id}") + @ResponseStatus(HttpStatus.OK) + @Operation(security = {@SecurityRequirement(name = "bearerAuth")}) + public void deleteFavorite(@PathVariable long id) { + favoriteService.deleteFavorite(id); + } +} + + diff --git a/src/main/java/org/tb/rest/favorites/core/Favorite.java b/src/main/java/org/tb/rest/favorites/core/Favorite.java new file mode 100644 index 000000000..95f66861e --- /dev/null +++ b/src/main/java/org/tb/rest/favorites/core/Favorite.java @@ -0,0 +1,34 @@ +package org.tb.rest.favorites.core; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Lob; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.FieldDefaults; + +@Builder +@Data +@Entity +@NoArgsConstructor +@AllArgsConstructor +@FieldDefaults(level = AccessLevel.PRIVATE) +public class Favorite { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; + Long employeeId; + Long employeeorderId; + Integer hours; + Integer minutes; + @Lob + @Column(columnDefinition = "text") + String comment; +} diff --git a/src/main/java/org/tb/rest/favorites/core/FavoriteRepository.java b/src/main/java/org/tb/rest/favorites/core/FavoriteRepository.java new file mode 100644 index 000000000..04528ac2c --- /dev/null +++ b/src/main/java/org/tb/rest/favorites/core/FavoriteRepository.java @@ -0,0 +1,13 @@ +package org.tb.rest.favorites.core; + +import java.util.List; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface FavoriteRepository extends CrudRepository, + JpaSpecificationExecutor { + + List findAllByEmployeeId(long employeeId); +} diff --git a/src/main/java/org/tb/rest/favorites/core/FavoriteService.java b/src/main/java/org/tb/rest/favorites/core/FavoriteService.java new file mode 100644 index 000000000..2729f21b5 --- /dev/null +++ b/src/main/java/org/tb/rest/favorites/core/FavoriteService.java @@ -0,0 +1,45 @@ +package org.tb.rest.favorites.core; + +import java.util.Collection; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; +import org.tb.auth.AuthorizedUser; +import org.webjars.NotFoundException; + +@Service +@RequiredArgsConstructor +public class FavoriteService { + + private final FavoriteRepository favoriteRepository; + private final AuthorizedUser authorizedUser; + + public Collection getFavorites(Long employeeId) { + return favoriteRepository.findAllByEmployeeId(employeeId); + } + + public Favorite addFavorite(Favorite favorite) { + favorite.setEmployeeId(authorizedUser.getEmployeeId()); + try { + return favoriteRepository.save(favorite); + } catch (DataIntegrityViolationException e) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage()); + } + } + + public void deleteFavorite(long id) { + Optional favorite = favoriteRepository.findById(id); + if (favorite.isEmpty()) { + throw new NotFoundException("Favorite not found"); + } + if (authorizedUser.getEmployeeId().equals(favorite.get().getEmployeeId())) { + + favoriteRepository.deleteById(id); + } else { + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "not your Favorite"); + } + } +} diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 8deff9366..94e4b6fb9 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -42,3 +42,14 @@ salat: mail-host: localhost auth-service: cache-expiry: 5m +springdoc: + swagger-ui: + path: '/rest/doc/' + try-it-out-enabled: true + api-docs: + path: '/rest/doc/api-docs' + default-produces-media-type: 'application/json' +openapi: + description: 'Open API Documentation for the Salat Endpoints' + version: 0.1 + title: 'Salat API' \ No newline at end of file diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt new file mode 100644 index 000000000..fc0f742a8 --- /dev/null +++ b/src/main/resources/banner.txt @@ -0,0 +1,3 @@ +┏┓ ┓ +┗┓┏┓┃┏┓╋ +┗┛┗┻┗┗┻┗ \ No newline at end of file diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 9102a9ea0..25ba61449 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -746,3 +746,43 @@ databaseChangeLog: referencedTableName: customerorder referencedColumnNames: - id + - changeSet: + id: 21 + author: jp + changes: + - createTable: + tableName: favorite + columns: + - column: + name: id + type: bigint(20) + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: employeeId + type: bigint(20) + constraints: + nullable: false + - column: + name: employeeorderId + type: bigint(20) + constraints: + nullable: false + - column: + name: hours + type: int(11) + constraints: + nullable: false + - column: + name: minutes + type: int(11) + constraints: + nullable: false + - column: + name: comment + type: text + defaultOnNull: true +# - include: +# file: db/changelog/includes/addAllEmployees.sql \ No newline at end of file diff --git a/src/main/webapp/welcome/showWelcome.jsp b/src/main/webapp/welcome/showWelcome.jsp index a71ea10b6..6db5030d2 100644 --- a/src/main/webapp/welcome/showWelcome.jsp +++ b/src/main/webapp/welcome/showWelcome.jsp @@ -33,7 +33,7 @@
-

Probier die neue REST API aus!

+

Probier die neue REST API aus!





diff --git a/startDB.bat b/startDB.bat new file mode 100644 index 000000000..a018d25ac --- /dev/null +++ b/startDB.bat @@ -0,0 +1 @@ +docker-compose -f .\docker-compose-infra.yml up \ No newline at end of file diff --git a/testdb/testdb.sql b/testdb/testdb.sql index 75f677135..569b51024 100644 --- a/testdb/testdb.sql +++ b/testdb/testdb.sql @@ -99,7 +99,11 @@ CREATE TABLE `customerorder` ( LOCK TABLES `customerorder` WRITE; /*!40000 ALTER TABLE `customerorder` DISABLE KEYS */; -INSERT INTO `customerorder` VALUES (5190,'2006-12-05 13:35:24','mm','EUR',NULL,NULL,'Urlaub','2007-01-01','\0',0,'2007-07-16 12:44:37','adm','Urlaub','---','---','Urlaub','URLAUB',0,NULL,7,3201,1680,1680),(5191,'2006-12-05 13:36:31','mm','EUR',NULL,NULL,'Krankheit','2007-01-01','\0',0,'2007-07-16 12:44:09','adm','Krankheit','---','---','Krankheit','KRANK',0,NULL,7,3201,1680,1680),(180969,'2019-09-11 04:51:49','bm','EUR',NULL,NULL,'Rumsitzen','2019-09-11','\0',100,NULL,NULL,'Ergonomische Studie','Dörte Dörtersen','Hans Hansmann','Rumsitzen','111',0,'2023-10-21',NULL,181388,178367,178367); +INSERT INTO `customerorder` VALUES + (5190,'2006-12-05 13:35:24','mm','EUR',NULL,NULL,'Urlaub','2007-01-01','\0',0,'2007-07-16 12:44:37','adm','Urlaub','---','---','Urlaub','URLAUB',0,NULL,7,3201,1680,1680), + (5191,'2006-12-05 13:36:31','mm','EUR',NULL,NULL,'Krankheit','2007-01-01','\0',0,'2007-07-16 12:44:09','adm','Krankheit','---','---','Krankheit','KRANK',0,NULL,7,3201,1680,1680), + (180969,'2019-09-11 04:51:49','bm','EUR',NULL,NULL,'Rumsitzen','2019-09-11','\0',100,NULL,NULL,'Ergonomische Studie','Dörte Dörtersen','Hans Hansmann','Rumsitzen','111',0,NULL,NULL,181388,178367,178367), + (180970,'2019-09-11 04:51:49','bm','EUR',NULL,NULL,'Fortbildung','2019-09-11','\0',100,NULL,NULL,'Fortbildung','Dörte Dörtersen','Hans Hansmann','Fortbildung','i976',0,NULL,NULL,3201,1680,1680); /*!40000 ALTER TABLE `customerorder` ENABLE KEYS */; UNLOCK TABLES; @@ -222,7 +226,9 @@ CREATE TABLE `employeeorder` ( LOCK TABLES `employeeorder` WRITE; /*!40000 ALTER TABLE `employeeorder` DISABLE KEYS */; -INSERT INTO `employeeorder` VALUES (183209,'2019-09-11 04:54:51','bm',NULL,NULL,'2019-09-11',NULL,NULL,'','2022-10-21',NULL,NULL,180662,180692),(183210,'2019-09-11 04:55:00','system',240,0,'2019-09-11',NULL,NULL,' ','2019-12-31',NULL,NULL,180662,60208),(183211,'2019-09-11 04:55:00','system',NULL,NULL,'2019-09-11',NULL,NULL,' ','2019-12-31',NULL,NULL,180662,5861); +INSERT INTO `employeeorder` VALUES (183209,'2019-09-11 04:54:51','bm',NULL,NULL,'2019-09-11',NULL,NULL,'',NULL,NULL,NULL,180662,180692), + (183210,'2019-09-11 04:55:00','system',240,0,'2019-09-11',NULL,NULL,' ',NULL,NULL,NULL,180662,60208), + (183211,'2019-09-11 04:55:00','system',NULL,NULL,'2019-09-11',NULL,NULL,' ',NULL,NULL,NULL,180662,5861); /*!40000 ALTER TABLE `employeeorder` ENABLE KEYS */; UNLOCK TABLES; @@ -523,7 +529,9 @@ CREATE TABLE `suborder` ( LOCK TABLES `suborder` WRITE; /*!40000 ALTER TABLE `suborder` DISABLE KEYS */; -INSERT INTO `suborder` VALUES (5861,'\0','2006-12-22 14:14:18','adm','EUR',NULL,NULL,'Krankheit 2019','\0','2019-01-01','\0',0,'N','2009-02-02 10:42:35','adm','\0','Krankheit 2019','2019','','','\0','2019-12-31',3,5191,NULL),(60208,'\0','2010-01-04 13:27:24','adm','EUR',NULL,NULL,'Urlaub 2019','\0','2019-01-01','\0',0,'N','2011-05-17 14:23:53','adm','\0','Urlaub 2019','2019','','','\0','2019-12-31',3,5190,NULL),(180692,'','2019-09-11 04:53:23','bm','EUR',NULL,NULL,'Testen der Stuhlpolsterung','\0','2019-09-11','\0',100,'Y',NULL,NULL,'\0','Stuhlpolsterung','111.01','\0','SP1','\0','2023-10-21',NULL,180969,NULL); +INSERT INTO `suborder` VALUES (5861,'\0','2006-12-22 14:14:18','adm','EUR',NULL,NULL,'Krankheit 2019','\0','2019-01-01','\0',0,'N','2009-02-02 10:42:35','adm','\0','Krankheit 2019','2019','','','\0',NULL,3,5191,NULL), + (60208,'\0','2010-01-04 13:27:24','adm','EUR',NULL,NULL,'Urlaub 2019','\0','2019-01-01','\0',0,'N','2011-05-17 14:23:53','adm','\0','Urlaub 2019','2019','','','\0',NULL,3,5190,NULL), + (180692,'\0','2019-09-11 04:53:23','bm','EUR',NULL,NULL,'Testen der Stuhlpolsterung','\0','2019-09-11','\0',100,'Y',NULL,NULL,'\0','Stuhlpolsterung','111.01','\0','SP1','\0',NULL,NULL,180969,NULL); /*!40000 ALTER TABLE `suborder` ENABLE KEYS */; UNLOCK TABLES; @@ -649,3 +657,17 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2019-09-11 7:07:08 + +DROP TABLE IF EXISTS `favorite`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `favorite` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `employeeId`bigint(20) NOT NULL, + `employeeorderId` bigint(20) NOT NULL, + `hours` int(11) NOT NULL, + `minutes` int(11) NOT NULL, + `comment` text COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`id`), +) ENGINE=InnoDB AUTO_INCREMENT=183915 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */;