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.repository.AccountsRepository;
|
||||
import edu.msudenver.tsp.utilities.PersistenceUtilities;
|
||||
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 javax.validation.Valid;
|
||||
import javax.validation.groups.Default;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/accounts")
|
||||
@@ -14,13 +25,157 @@ public class AccountController {
|
||||
private final AccountsRepository accountsRepository;
|
||||
|
||||
@GetMapping("/")
|
||||
public @ResponseBody Iterable<AccountsDto> getListOfAccounts() {
|
||||
return accountsRepository.findAll();
|
||||
public @ResponseBody
|
||||
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}")
|
||||
public @ResponseBody
|
||||
Optional<AccountsDto> getAccountById(@PathVariable("id") final Integer id) {
|
||||
return accountsRepository.findById(id);
|
||||
ResponseEntity<AccountsDto> getAccountById(@PathVariable("id") final Integer 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;
|
||||
|
||||
interface Insert {}
|
||||
public interface Insert {}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
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