PAN-48 Created the AccountController and created the copyNonNullProperties method
This commit is contained in:
+159
-4
@@ -2,11 +2,22 @@ package edu.msudenver.tsp.persistence.controller;
|
|||||||
|
|
||||||
import edu.msudenver.tsp.persistence.dto.AccountsDto;
|
import edu.msudenver.tsp.persistence.dto.AccountsDto;
|
||||||
import edu.msudenver.tsp.persistence.repository.AccountsRepository;
|
import edu.msudenver.tsp.persistence.repository.AccountsRepository;
|
||||||
|
import edu.msudenver.tsp.utilities.PersistenceUtilities;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.util.StopWatch;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import javax.validation.groups.Default;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@RequestMapping("/accounts")
|
@RequestMapping("/accounts")
|
||||||
@@ -14,13 +25,157 @@ public class AccountController {
|
|||||||
private final AccountsRepository accountsRepository;
|
private final AccountsRepository accountsRepository;
|
||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public @ResponseBody Iterable<AccountsDto> getListOfAccounts() {
|
public @ResponseBody
|
||||||
return accountsRepository.findAll();
|
ResponseEntity<Iterable<AccountsDto>> getListOfAccounts() {
|
||||||
|
LOG.info("Received request to list all accounts");
|
||||||
|
|
||||||
|
LOG.debug("Querying for list of accounts");
|
||||||
|
|
||||||
|
final StopWatch stopWatch = new StopWatch();
|
||||||
|
stopWatch.start();
|
||||||
|
|
||||||
|
final List<AccountsDto> listOfAccounts = (List<AccountsDto>) accountsRepository.findAll();
|
||||||
|
|
||||||
|
stopWatch.stop();
|
||||||
|
|
||||||
|
LOG.debug("Successfully completed query. Query took " + stopWatch.getTotalTimeMillis() + "ms to complete");
|
||||||
|
LOG.info("Returning list of all accounts with size of " + listOfAccounts.size());
|
||||||
|
|
||||||
|
return new ResponseEntity<>(listOfAccounts, HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public @ResponseBody
|
public @ResponseBody
|
||||||
Optional<AccountsDto> getAccountById(@PathVariable("id") final Integer id) {
|
ResponseEntity<AccountsDto> getAccountById(@PathVariable("id") final Integer id) {
|
||||||
return accountsRepository.findById(id);
|
LOG.info("Received request to query for account with id " + id);
|
||||||
|
if (id == null) {
|
||||||
|
LOG.error("ERROR: ID was null");
|
||||||
|
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.debug("Querying for account with id " + id);
|
||||||
|
final StopWatch stopWatch = new StopWatch();
|
||||||
|
stopWatch.start();
|
||||||
|
|
||||||
|
final Optional<AccountsDto> account = accountsRepository.findById(id);
|
||||||
|
|
||||||
|
stopWatch.stop();
|
||||||
|
|
||||||
|
LOG.debug("Received response from server: query took " + stopWatch.getTotalTimeMillis() + "ms to complete");
|
||||||
|
return account.map(accountDto -> {
|
||||||
|
LOG.info("Returning account with id " + id);
|
||||||
|
return new ResponseEntity<>(accountDto, HttpStatus.OK);
|
||||||
|
}).orElseGet(
|
||||||
|
() -> {
|
||||||
|
LOG.warn("No account was found with id " + id);
|
||||||
|
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/")
|
||||||
|
@Validated({AccountsDto.Insert.class, Default.class})
|
||||||
|
public @ResponseBody ResponseEntity<AccountsDto> insertAccount(
|
||||||
|
@Valid @RequestBody final AccountsDto accountsDto, final BindingResult bindingResult) {
|
||||||
|
|
||||||
|
LOG.info("Received request to insert a new account");
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
LOG.error("Binding result is unprocessable");
|
||||||
|
return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accountsDto == null) {
|
||||||
|
LOG.error("Passed account is unprocessable");
|
||||||
|
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.debug("Saving new account");
|
||||||
|
|
||||||
|
final StopWatch stopWatch = new StopWatch();
|
||||||
|
stopWatch.start();
|
||||||
|
|
||||||
|
final AccountsDto savedAccount = accountsRepository.save(accountsDto);
|
||||||
|
|
||||||
|
stopWatch.stop();
|
||||||
|
|
||||||
|
LOG.debug("Received response from server: query took " + stopWatch.getTotalTimeMillis() + "ms to complete");
|
||||||
|
LOG.info("Returning the newly created account");
|
||||||
|
return new ResponseEntity<>(savedAccount, HttpStatus.CREATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/{id}")
|
||||||
|
public @ResponseBody ResponseEntity<AccountsDto> updateAccount(
|
||||||
|
@PathVariable("id") final Integer id,
|
||||||
|
@RequestBody final AccountsDto accountsDto, final BindingResult bindingResult) {
|
||||||
|
|
||||||
|
LOG.info("Received request to update an account");
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
LOG.error("Binding result is unprocessable");
|
||||||
|
return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accountsDto == null) {
|
||||||
|
LOG.error("Passed entity is null");
|
||||||
|
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == null) {
|
||||||
|
LOG.error("Account ID must be specified");
|
||||||
|
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.debug("Checking for existence of account with id " + id);
|
||||||
|
|
||||||
|
final StopWatch stopWatch = new StopWatch();
|
||||||
|
stopWatch.start();
|
||||||
|
|
||||||
|
final Optional<AccountsDto> existingAccount = accountsRepository.findById(id);
|
||||||
|
|
||||||
|
stopWatch.stop();
|
||||||
|
|
||||||
|
LOG.debug("Received response from server: query took " + stopWatch.getTotalTimeMillis() + "ms to complete");
|
||||||
|
|
||||||
|
if (!existingAccount.isPresent()) {
|
||||||
|
LOG.error("No account associated with id " + id);
|
||||||
|
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
PersistenceUtilities.copyNonNullProperties(accountsDto, existingAccount.get());
|
||||||
|
existingAccount.get().setVersion(existingAccount.get().getVersion()+ 1);
|
||||||
|
|
||||||
|
LOG.info("Updating account with id " + id);
|
||||||
|
LOG.debug("Querying for account with ID " + id);
|
||||||
|
|
||||||
|
stopWatch.start();
|
||||||
|
|
||||||
|
final AccountsDto updatedAccount = accountsRepository.save(existingAccount.get());
|
||||||
|
|
||||||
|
stopWatch.stop();
|
||||||
|
|
||||||
|
LOG.debug("Received response from server: query took " + stopWatch.getTotalTimeMillis() + "ms to complete");
|
||||||
|
|
||||||
|
return new ResponseEntity<>(updatedAccount, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public @ResponseBody ResponseEntity<Void> deleteAccountById(@PathVariable("id") final Integer id) {
|
||||||
|
LOG.info("Received request to delete account with id " + id);
|
||||||
|
if (id == null) {
|
||||||
|
LOG.error("Specified Id is null");
|
||||||
|
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.debug("Deleting account with id " + id);
|
||||||
|
|
||||||
|
final StopWatch stopWatch = new StopWatch();
|
||||||
|
stopWatch.start();
|
||||||
|
|
||||||
|
accountsRepository.deleteById(id);
|
||||||
|
|
||||||
|
stopWatch.stop();
|
||||||
|
|
||||||
|
LOG.debug("Received response from server: query took " + stopWatch.getTotalTimeMillis() + "ms to complete");
|
||||||
|
|
||||||
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -27,5 +27,5 @@ public class AccountsDto extends BaseDto implements Serializable {
|
|||||||
|
|
||||||
public static final long serialVersionUID = 7095627971593953734L;
|
public static final long serialVersionUID = 7095627971593953734L;
|
||||||
|
|
||||||
interface Insert {}
|
public interface Insert {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
|
||||||
compile fileTree(dir: 'lib', include: '**/*.jar')
|
compile fileTree(dir: 'lib', include: '**/*.jar')
|
||||||
|
|
||||||
|
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||||
}
|
}
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package edu.msudenver.tsp.utilities;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.BeanWrapper;
|
||||||
|
import org.springframework.beans.BeanWrapperImpl;
|
||||||
|
|
||||||
|
import java.beans.FeatureDescriptor;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public abstract class PersistenceUtilities {
|
||||||
|
|
||||||
|
private static String[] getNullPropertyNames(final Object source) {
|
||||||
|
final BeanWrapper wrappedSource = new BeanWrapperImpl(source);
|
||||||
|
return Stream.of(wrappedSource.getPropertyDescriptors())
|
||||||
|
.map(FeatureDescriptor::getName)
|
||||||
|
.filter(propertyName -> wrappedSource.getPropertyValue(propertyName) == null
|
||||||
|
|| propertyName.equals("id"))
|
||||||
|
.toArray(String[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void copyNonNullProperties(final Object source, final Object target) {
|
||||||
|
BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user