Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Wendys Racing Horses
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
tu-wien
Wendys Racing Horses
Commits
3d9e918f
Commit
3d9e918f
authored
Mar 22, 2020
by
Ivaylo Ivanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
US06: Add an owner create endpoint to the API
parent
361a09b0
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
200 additions
and
2 deletions
+200
-2
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/endpoint/OwnerEndpoint.java
...en/sepm/assignment/individual/endpoint/OwnerEndpoint.java
+22
-0
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/endpoint/mapper/OwnerMapper.java
...pm/assignment/individual/endpoint/mapper/OwnerMapper.java
+3
-1
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/persistence/OwnerDao.java
...wien/sepm/assignment/individual/persistence/OwnerDao.java
+7
-0
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/persistence/impl/OwnerJdbcDao.java
.../assignment/individual/persistence/impl/OwnerJdbcDao.java
+49
-0
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/service/OwnerService.java
...wien/sepm/assignment/individual/service/OwnerService.java
+10
-0
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/service/impl/SimpleOwnerService.java
...ssignment/individual/service/impl/SimpleOwnerService.java
+8
-0
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/util/Validator.java
.../ac/tuwien/sepm/assignment/individual/util/Validator.java
+3
-0
backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/integration/OwnerEndpointTest.java
.../assignment/individual/integration/OwnerEndpointTest.java
+42
-0
backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/unit/persistence/OwnerDaoTestBase.java
...ignment/individual/unit/persistence/OwnerDaoTestBase.java
+17
-1
backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/unit/service/OwnerServiceTest.java
.../assignment/individual/unit/service/OwnerServiceTest.java
+39
-0
No files found.
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/endpoint/OwnerEndpoint.java
View file @
3d9e918f
...
@@ -2,12 +2,16 @@ package at.ac.tuwien.sepm.assignment.individual.endpoint;
...
@@ -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.dto.OwnerDto
;
import
at.ac.tuwien.sepm.assignment.individual.endpoint.mapper.OwnerMapper
;
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.exception.NotFoundException
;
import
at.ac.tuwien.sepm.assignment.individual.service.OwnerService
;
import
at.ac.tuwien.sepm.assignment.individual.service.OwnerService
;
import
java.lang.invoke.MethodHandles
;
import
java.lang.invoke.MethodHandles
;
import
at.ac.tuwien.sepm.assignment.individual.util.ValidationException
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.dao.DataAccessException
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.server.ResponseStatusException
;
import
org.springframework.web.server.ResponseStatusException
;
...
@@ -36,4 +40,22 @@ public class OwnerEndpoint {
...
@@ -36,4 +40,22 @@ public class OwnerEndpoint {
throw
new
ResponseStatusException
(
HttpStatus
.
NOT_FOUND
,
"Error during reading owner"
,
e
);
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"
);
}
}
}
}
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/endpoint/mapper/OwnerMapper.java
View file @
3d9e918f
...
@@ -11,5 +11,7 @@ public class OwnerMapper {
...
@@ -11,5 +11,7 @@ public class OwnerMapper {
return
new
OwnerDto
(
owner
.
getId
(),
owner
.
getName
(),
owner
.
getCreatedAt
(),
owner
.
getUpdatedAt
());
return
new
OwnerDto
(
owner
.
getId
(),
owner
.
getName
(),
owner
.
getCreatedAt
(),
owner
.
getUpdatedAt
());
}
}
public
Owner
dtoToEntity
(
OwnerDto
owner
)
{
return
new
Owner
(
owner
.
getName
());
}
}
}
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/persistence/OwnerDao.java
View file @
3d9e918f
...
@@ -14,4 +14,11 @@ public interface OwnerDao {
...
@@ -14,4 +14,11 @@ public interface OwnerDao {
*/
*/
Owner
findOneById
(
Long
id
);
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
);
}
}
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/persistence/impl/OwnerJdbcDao.java
View file @
3d9e918f
...
@@ -4,14 +4,20 @@ import at.ac.tuwien.sepm.assignment.individual.entity.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.exception.NotFoundException
;
import
at.ac.tuwien.sepm.assignment.individual.persistence.OwnerDao
;
import
at.ac.tuwien.sepm.assignment.individual.persistence.OwnerDao
;
import
java.lang.invoke.MethodHandles
;
import
java.lang.invoke.MethodHandles
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
java.time.LocalDateTime
;
import
java.util.List
;
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
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.JdbcTemplate
;
import
org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
;
import
org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
;
import
org.springframework.jdbc.support.GeneratedKeyHolder
;
import
org.springframework.jdbc.support.KeyHolder
;
import
org.springframework.stereotype.Repository
;
import
org.springframework.stereotype.Repository
;
@Repository
@Repository
...
@@ -39,6 +45,49 @@ public class OwnerJdbcDao implements OwnerDao {
...
@@ -39,6 +45,49 @@ public class OwnerJdbcDao implements OwnerDao {
return
owners
.
get
(
0
);
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
{
private
Owner
mapRow
(
ResultSet
resultSet
,
int
i
)
throws
SQLException
{
final
Owner
owner
=
new
Owner
();
final
Owner
owner
=
new
Owner
();
...
...
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/service/OwnerService.java
View file @
3d9e918f
...
@@ -2,6 +2,8 @@ package at.ac.tuwien.sepm.assignment.individual.service;
...
@@ -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.entity.Owner
;
import
at.ac.tuwien.sepm.assignment.individual.exception.NotFoundException
;
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
{
public
interface
OwnerService
{
...
@@ -14,4 +16,12 @@ public interface OwnerService {
...
@@ -14,4 +16,12 @@ public interface OwnerService {
*/
*/
Owner
findOneById
(
Long
id
);
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
;
}
}
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/service/impl/SimpleOwnerService.java
View file @
3d9e918f
...
@@ -3,11 +3,13 @@ package at.ac.tuwien.sepm.assignment.individual.service.impl;
...
@@ -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.entity.Owner
;
import
at.ac.tuwien.sepm.assignment.individual.persistence.OwnerDao
;
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.service.OwnerService
;
import
at.ac.tuwien.sepm.assignment.individual.util.ValidationException
;
import
at.ac.tuwien.sepm.assignment.individual.util.Validator
;
import
at.ac.tuwien.sepm.assignment.individual.util.Validator
;
import
java.lang.invoke.MethodHandles
;
import
java.lang.invoke.MethodHandles
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.dao.DataAccessException
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
@Service
@Service
...
@@ -29,4 +31,10 @@ public class SimpleOwnerService implements OwnerService {
...
@@ -29,4 +31,10 @@ public class SimpleOwnerService implements OwnerService {
return
ownerDao
.
findOneById
(
id
);
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
);
}
}
}
backend/src/main/java/at/ac/tuwien/sepm/assignment/individual/util/Validator.java
View file @
3d9e918f
...
@@ -15,6 +15,9 @@ public class Validator {
...
@@ -15,6 +15,9 @@ public class Validator {
public
void
validateNewOwner
(
Owner
owner
)
throws
ValidationException
{
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
{
public
void
validateUpdateOwner
(
Owner
owner
)
throws
ValidationException
{
...
...
backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/integration/OwnerEndpointTest.java
0 → 100644
View file @
3d9e918f
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
());
}
}
backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/unit/persistence/OwnerDaoTestBase.java
View file @
3d9e918f
...
@@ -2,11 +2,13 @@ package at.ac.tuwien.sepm.assignment.individual.unit.persistence;
...
@@ -2,11 +2,13 @@ package at.ac.tuwien.sepm.assignment.individual.unit.persistence;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.*;
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.exception.NotFoundException
;
import
at.ac.tuwien.sepm.assignment.individual.persistence.OwnerDao
;
import
at.ac.tuwien.sepm.assignment.individual.persistence.OwnerDao
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.dao.DataAccessException
;
public
abstract
class
OwnerDaoTestBase
{
public
abstract
class
OwnerDaoTestBase
{
...
@@ -17,7 +19,21 @@ public abstract class OwnerDaoTestBase {
...
@@ -17,7 +19,21 @@ public abstract class OwnerDaoTestBase {
@DisplayName
(
"Finding owner by non-existing ID should throw NotFoundException"
)
@DisplayName
(
"Finding owner by non-existing ID should throw NotFoundException"
)
public
void
findingOwnerById_nonExisting_shouldThrowNotFoundException
()
{
public
void
findingOwnerById_nonExisting_shouldThrowNotFoundException
()
{
assertThrows
(
NotFoundException
.
class
,
assertThrows
(
NotFoundException
.
class
,
()
->
ownerDao
.
findOneById
(
1
L
));
()
->
ownerDao
.
findOneById
(
0
L
));
}
}
@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
));
}
}
}
backend/src/test/java/at/ac/tuwien/sepm/assignment/individual/unit/service/OwnerServiceTest.java
0 → 100644
View file @
3d9e918f
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
));
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment