US06: Add an owner create endpoint to the API
This commit is contained in:
parent
361a09b082
commit
3d9e918f39
@ -2,12 +2,16 @@ package at.ac.tuwien.sepm.assignment.individual.endpoint;
|
||||
|
||||
import at.ac.tuwien.sepm.assignment.individual.endpoint.dto.OwnerDto;
|
||||
import at.ac.tuwien.sepm.assignment.individual.endpoint.mapper.OwnerMapper;
|
||||
import at.ac.tuwien.sepm.assignment.individual.entity.Owner;
|
||||
import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException;
|
||||
import at.ac.tuwien.sepm.assignment.individual.service.OwnerService;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
|
||||
import at.ac.tuwien.sepm.assignment.individual.util.ValidationException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
@ -36,4 +40,22 @@ public class OwnerEndpoint {
|
||||
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Error during reading owner", e);
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
public OwnerDto addHorse(@RequestBody OwnerDto owner) {
|
||||
LOGGER.info("POST " + BASE_URL);
|
||||
try {
|
||||
Owner ownerEntity = ownerMapper.dtoToEntity(owner);
|
||||
return ownerMapper.entityToDto(ownerService.addOwner(ownerEntity));
|
||||
} catch (ValidationException e) {
|
||||
LOGGER.error(e.getMessage());
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
|
||||
"Error during adding new owner: " + e.getMessage());
|
||||
} catch (DataAccessException e) {
|
||||
LOGGER.error(e.getMessage());
|
||||
throw new ResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY,
|
||||
"Something went wrong during the communication with the database");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,5 +11,7 @@ public class OwnerMapper {
|
||||
return new OwnerDto(owner.getId(), owner.getName(), owner.getCreatedAt(), owner.getUpdatedAt());
|
||||
}
|
||||
|
||||
|
||||
public Owner dtoToEntity(OwnerDto owner) {
|
||||
return new Owner(owner.getName());
|
||||
}
|
||||
}
|
||||
|
@ -14,4 +14,11 @@ public interface OwnerDao {
|
||||
*/
|
||||
Owner findOneById(Long id);
|
||||
|
||||
/**
|
||||
* @param owner that specifies the owner to add
|
||||
* @return the newly created horse
|
||||
* @throws DataAccessException will be thrown if something goes wrong during the database access.
|
||||
*/
|
||||
Owner addOwner(Owner owner);
|
||||
|
||||
}
|
||||
|
@ -4,14 +4,20 @@ import at.ac.tuwien.sepm.assignment.individual.entity.Owner;
|
||||
import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException;
|
||||
import at.ac.tuwien.sepm.assignment.individual.persistence.OwnerDao;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.jdbc.support.GeneratedKeyHolder;
|
||||
import org.springframework.jdbc.support.KeyHolder;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@ -39,6 +45,49 @@ public class OwnerJdbcDao implements OwnerDao {
|
||||
return owners.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Owner addOwner(Owner owner) {
|
||||
LOGGER.trace("Add owner {}", owner);
|
||||
final String sql = "INSERT INTO " + TABLE_NAME + "(name, created_at, updated_at) VALUES(?,?,?)";
|
||||
|
||||
try {
|
||||
// Check if the constraints are violated
|
||||
this.validateOwner(owner);
|
||||
|
||||
LocalDateTime currentTime = LocalDateTime.now();
|
||||
|
||||
owner.setCreatedAt(currentTime);
|
||||
owner.setUpdatedAt(currentTime);
|
||||
|
||||
// Create a key holder to get the key of the new record
|
||||
KeyHolder keyHolder = new GeneratedKeyHolder();
|
||||
|
||||
int changes = jdbcTemplate.update(connection -> {
|
||||
PreparedStatement ps = connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
|
||||
|
||||
ps.setString(1, owner.getName());
|
||||
ps.setObject(2, owner.getCreatedAt());
|
||||
ps.setObject(3, owner.getUpdatedAt());
|
||||
return ps;
|
||||
}, keyHolder);
|
||||
|
||||
if (changes == 0)
|
||||
throw new DataAccessException("Creating owner failed, no rows affected") {};
|
||||
|
||||
owner.setId(((Number)keyHolder.getKeys().get("id")).longValue());
|
||||
|
||||
return owner;
|
||||
|
||||
} catch (DataAccessException e) {
|
||||
// We are doing this in order to not change the exception type
|
||||
throw new DataAccessException("Adding new records failed", e) {};
|
||||
}
|
||||
}
|
||||
|
||||
private void validateOwner(Owner owner) throws DataIntegrityViolationException {
|
||||
if(owner.getName() == null || owner.getName().isEmpty())
|
||||
throw new DataIntegrityViolationException("Required parameters for owner missing");
|
||||
}
|
||||
|
||||
private Owner mapRow(ResultSet resultSet, int i) throws SQLException {
|
||||
final Owner owner = new Owner();
|
||||
|
@ -2,6 +2,8 @@ package at.ac.tuwien.sepm.assignment.individual.service;
|
||||
|
||||
import at.ac.tuwien.sepm.assignment.individual.entity.Owner;
|
||||
import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException;
|
||||
import at.ac.tuwien.sepm.assignment.individual.util.ValidationException;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
public interface OwnerService {
|
||||
|
||||
@ -14,4 +16,12 @@ public interface OwnerService {
|
||||
*/
|
||||
Owner findOneById(Long id);
|
||||
|
||||
/**
|
||||
* @param owner to create
|
||||
* @return the new owner
|
||||
* @throws ValidationException will be thrown if something goes wrong during verification.
|
||||
* @throws DataAccessException will be thrown if the horse could not be saved in the database.
|
||||
*/
|
||||
Owner addOwner(Owner owner) throws ValidationException, DataAccessException;
|
||||
|
||||
}
|
||||
|
@ -3,11 +3,13 @@ package at.ac.tuwien.sepm.assignment.individual.service.impl;
|
||||
import at.ac.tuwien.sepm.assignment.individual.entity.Owner;
|
||||
import at.ac.tuwien.sepm.assignment.individual.persistence.OwnerDao;
|
||||
import at.ac.tuwien.sepm.assignment.individual.service.OwnerService;
|
||||
import at.ac.tuwien.sepm.assignment.individual.util.ValidationException;
|
||||
import at.ac.tuwien.sepm.assignment.individual.util.Validator;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@ -29,4 +31,10 @@ public class SimpleOwnerService implements OwnerService {
|
||||
return ownerDao.findOneById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Owner addOwner(Owner owner) throws ValidationException, DataAccessException {
|
||||
LOGGER.trace("addOwner({})", owner);
|
||||
this.validator.validateNewOwner(owner);
|
||||
return ownerDao.addOwner(owner);
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,9 @@ public class Validator {
|
||||
|
||||
|
||||
public void validateNewOwner(Owner owner) throws ValidationException {
|
||||
if(owner.getName() == null || owner.getName().isEmpty()) {
|
||||
throw new ValidationException("Required value name missing");
|
||||
}
|
||||
}
|
||||
|
||||
public void validateUpdateOwner(Owner owner) throws ValidationException {
|
||||
|
@ -0,0 +1,42 @@
|
||||
package at.ac.tuwien.sepm.assignment.individual.integration;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import at.ac.tuwien.sepm.assignment.individual.endpoint.dto.OwnerDto;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@ActiveProfiles("test")
|
||||
public class OwnerEndpointTest {
|
||||
@Value("${spring.upload.path}")
|
||||
private String FILE_BASE_PATH;
|
||||
private static final RestTemplate REST_TEMPLATE = new RestTemplate();
|
||||
private static final String BASE_URL = "http://localhost:";
|
||||
private static final String OWNER_URL = "/owners";
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
|
||||
@Test
|
||||
@DisplayName("Adding a new owner with the correct parameters will return HTTP 201 and the new OwnerDto")
|
||||
public void addingNewOwner_correctParameters_shouldReturnStatus201AndOwner() {
|
||||
OwnerDto newOwner = new OwnerDto("Chad");
|
||||
|
||||
HttpEntity<OwnerDto> request = new HttpEntity<>(newOwner);
|
||||
ResponseEntity<OwnerDto> response = REST_TEMPLATE
|
||||
.exchange(BASE_URL + port + OWNER_URL, HttpMethod.POST, request, OwnerDto.class);
|
||||
|
||||
// Compare everything except ids and timestamps
|
||||
assertEquals(response.getStatusCode(), HttpStatus.CREATED);
|
||||
assertEquals(newOwner.getName(), response.getBody().getName());
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,13 @@ package at.ac.tuwien.sepm.assignment.individual.unit.persistence;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import at.ac.tuwien.sepm.assignment.individual.entity.Owner;
|
||||
import at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException;
|
||||
import at.ac.tuwien.sepm.assignment.individual.persistence.OwnerDao;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
public abstract class OwnerDaoTestBase {
|
||||
|
||||
@ -17,7 +19,21 @@ public abstract class OwnerDaoTestBase {
|
||||
@DisplayName("Finding owner by non-existing ID should throw NotFoundException")
|
||||
public void findingOwnerById_nonExisting_shouldThrowNotFoundException() {
|
||||
assertThrows(NotFoundException.class,
|
||||
() -> ownerDao.findOneById(1L));
|
||||
() -> ownerDao.findOneById(0L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Adding a new owner with the correct parameters should return the owner")
|
||||
public void addingNewOwner_correctParameters_shouldReturnOwner() {
|
||||
Owner newOwner = new Owner("Chad");
|
||||
Owner savedOwner = ownerDao.addOwner(newOwner);
|
||||
assertEquals(newOwner, savedOwner);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Adding a new horse with the incorrect parameters should throw DataAccessException")
|
||||
public void addingNewOwner_incorrectParameters_shouldThrowDataAccess() {
|
||||
Owner newOwner = new Owner("");
|
||||
assertThrows(DataAccessException.class, () -> ownerDao.addOwner(newOwner));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
package at.ac.tuwien.sepm.assignment.individual.unit.service;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import at.ac.tuwien.sepm.assignment.individual.entity.Owner;
|
||||
import at.ac.tuwien.sepm.assignment.individual.service.OwnerService;
|
||||
import at.ac.tuwien.sepm.assignment.individual.util.ValidationException;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@SpringBootTest
|
||||
@ActiveProfiles("test")
|
||||
public class OwnerServiceTest {
|
||||
@Autowired
|
||||
OwnerService ownerService;
|
||||
|
||||
@Test
|
||||
@DisplayName("Adding a new owner with the correct parameters will return the new owner")
|
||||
public void addingNewOwner_correctParameters_shouldReturnOwner() {
|
||||
Owner newOwner = new Owner("Chad");
|
||||
Owner savedOwner = ownerService.addOwner(newOwner);
|
||||
assertEquals(newOwner, savedOwner);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Adding a new owner with the incorrect parameters will throw a ValidationException")
|
||||
public void addingNewOwner_incorrectParameters_shouldThrowValidation() {
|
||||
Owner newOwner = new Owner("");
|
||||
assertThrows(ValidationException.class, () -> ownerService.addOwner(newOwner));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user