change git root

This commit is contained in:
2019-03-03 16:13:24 -07:00
parent a1d5a82570
commit 96c90a3c49
71 changed files with 180 additions and 18 deletions
@@ -0,0 +1,109 @@
package edu.msudenver.tsp.persistence;
import org.hibernate.SessionFactory;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBuilder;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import javax.sql.DataSource;
import java.util.Properties;
@SpringBootApplication
@EnableJpaRepositories
@EnableJpaAuditing
@EntityScan
public class PersistenceApi {
@Value("${spring.datasource.username}") private String username;
@Value("${spring.datasource.password}") private String password;
@Value("${spring.jpa.hibernate.ddl-auto}") private String hibernateTablePolicy;
@Value("${spring.datasource.url}") private String databaseUrl;
@Value("${spring.jpa.properties.hibernate.dialect}") private String hibernateDialect;
@Value("${spring.jpa.show-sql}") private String showSql;
@Value("${spring.datasource.driver-class-name}") private String driverClassName;
@Value("${spring.datasource.tomcat.max-active}") private String tomcatPoolMaxActive;
public static void main(final String[] args) {
SpringApplication.run(PersistenceApi.class, args);
}
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setJpaVendorAdapter(vendorAdapter());
em.setDataSource(getDataSource());
em.setPersistenceProviderClass(HibernatePersistenceProvider.class);
em.setPackagesToScan("edu.msudenver.tsp.persistence");
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public JpaTransactionManager jpaTransactionManager() {
final JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return jpaTransactionManager;
}
private HibernateJpaVendorAdapter vendorAdapter() {
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(true);
return vendorAdapter;
}
@Bean(name = "dataSource")
public DataSource getDataSource(){
return DataSourceBuilder
.create()
.username(username)
.password(password)
.url(databaseUrl)
.driverClassName(driverClassName)
.build();
}
@Bean(name = "sessionFactory")
public SessionFactory getSessionFactory(final DataSource dataSource) {
final LocalSessionFactoryBuilder sessionFactoryBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionFactoryBuilder.scanPackages("edu.msudenver.tsp.persistence.dto");
return sessionFactoryBuilder.buildSessionFactory();
}
@Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager(final SessionFactory sessionFactory) {
return new HibernateTransactionManager(sessionFactory);
}
@Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
return initializer;
}
Properties additionalProperties() {
final Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "update");
properties.setProperty("hibernate.dialect", hibernateDialect);
properties.setProperty("spring.jpa.show-sql", showSql);
properties.setProperty("spring.datasource.tomcat.max-active", tomcatPoolMaxActive);
properties.setProperty("hibernate.id.new_generator_mappings","false");
return properties;
}
}
@@ -0,0 +1,181 @@
package edu.msudenver.tsp.persistence.controller;
import edu.msudenver.tsp.persistence.dto.AccountDto;
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")
public class AccountController {
private final AccountsRepository accountsRepository;
@GetMapping("/")
public @ResponseBody
ResponseEntity<Iterable<AccountDto>> 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<AccountDto> listOfAccounts = (List<AccountDto>) 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
ResponseEntity<AccountDto> 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<AccountDto> 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({AccountDto.Insert.class, Default.class})
public @ResponseBody ResponseEntity<AccountDto> insertAccount(
@Valid @RequestBody final AccountDto accountDto, 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 (accountDto == 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 AccountDto savedAccount = accountsRepository.save(accountDto);
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<AccountDto> updateAccount(
@PathVariable("id") final Integer id,
@RequestBody final AccountDto accountDto, 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 (accountDto == 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<AccountDto> 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(accountDto, 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 AccountDto 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);
}
}
@@ -0,0 +1,181 @@
package edu.msudenver.tsp.persistence.controller;
import edu.msudenver.tsp.persistence.dto.DefinitionDto;
import edu.msudenver.tsp.persistence.repository.DefinitionRepository;
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(path = "/definitions/")
public class DefinitionController {
private final DefinitionRepository definitionRepository;
@GetMapping("/")
public @ResponseBody
ResponseEntity<Iterable<DefinitionDto>> getAllDefinitions() {
LOG.info("Received request to list all definitions");
LOG.debug("Querying for list of all definitions");
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
final List<DefinitionDto> listOfDefinitions = definitionRepository.findAll();
stopWatch.stop();
LOG.debug("Successfully completed query. Query took " + stopWatch.getTotalTimeMillis() + "ms to complete");
LOG.info("Returning list of all definition with size " + listOfDefinitions.size());
return new ResponseEntity<>(listOfDefinitions, HttpStatus.OK);
}
@GetMapping("/{id}")
public @ResponseBody
ResponseEntity<DefinitionDto> getDefinitionById(@PathVariable("id") final Integer id) {
LOG.info("Received request to query for definition with id " + id);
if (id == null) {
LOG.error("ERROR: ID was null");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
LOG.debug("Querying for definition with id " + id);
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
final Optional<DefinitionDto> definition = definitionRepository.findById(id);
stopWatch.stop();
LOG.debug("Received response from server: query took " + stopWatch.getTotalTimeMillis() + "ms to complete");
return definition.map(definitionDto -> {
LOG.info("Returning definition with id " + id);
return new ResponseEntity<>(definitionDto, HttpStatus.OK);
}).orElseGet(
() -> {
LOG.warn("No definition was found with id " + id);
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
});
}
@PostMapping("/")
@Validated({DefinitionDto.Insert.class, Default.class})
public @ResponseBody ResponseEntity<DefinitionDto> insertDefinition(
@Valid @RequestBody final DefinitionDto definitionDto,
final BindingResult bindingResult) {
LOG.info("Received request to insert a new definition");
if (bindingResult.hasErrors()) {
LOG.error("Binding result is unprocessable");
return new ResponseEntity<>(HttpStatus.UNPROCESSABLE_ENTITY);
}
if (definitionDto == null) {
LOG.error("Passed entity is unprocessable");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
LOG.debug("Saving new definition");
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
final DefinitionDto savedDefinition = definitionRepository.save(definitionDto);
stopWatch.stop();
LOG.debug("Received response from server: query took " + stopWatch.getTotalTimeMillis() + "ms to complete");
LOG.info("Returning the newly created definition with id " + savedDefinition.getId());
return new ResponseEntity<>(savedDefinition, HttpStatus.CREATED);
}
@PatchMapping("/{id}")
public @ResponseBody ResponseEntity<DefinitionDto> updateDefinition(
@PathVariable("id") final Integer id,
@RequestBody final DefinitionDto definitionDto, 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 (definitionDto == null) {
LOG.error("Passed entity is null");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
if (id == null) {
LOG.error("Definition ID must be specified");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
LOG.debug("Checking for existence of definition with id " + id);
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
final Optional<DefinitionDto> existingDefinition = definitionRepository.findById(id);
stopWatch.stop();
LOG.debug("Received response from server: query took " + stopWatch.getTotalTimeMillis() + "ms to complete");
if (!existingDefinition.isPresent()) {
LOG.error("No definition associated with id " + id);
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
PersistenceUtilities.copyNonNullProperties(definitionDto, existingDefinition.get());
existingDefinition.get().setVersion(existingDefinition.get().getVersion()+ 1);
LOG.info("Updating definition with id " + id);
LOG.debug("Querying for definition with ID " + id);
stopWatch.start();
final DefinitionDto updatedDefinition = definitionRepository.save(existingDefinition.get());
stopWatch.stop();
LOG.debug("Received response from server: query took " + stopWatch.getTotalTimeMillis() + "ms to complete");
return new ResponseEntity<>(updatedDefinition, HttpStatus.OK);
}
@DeleteMapping("/{id}")
public @ResponseBody ResponseEntity<Void> deleteDefinitionById(@PathVariable("id") final Integer id) {
LOG.info("Received request to delete definition with id " + id);
if (id == null) {
LOG.error("Specified id is null");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
LOG.debug("Deleting definition with id " + id);
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
definitionRepository.deleteById(id);
stopWatch.stop();
LOG.debug("Received response from server: query took " + stopWatch.getTotalTimeMillis() + "ms to complete");
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
}
@@ -0,0 +1,11 @@
package edu.msudenver.tsp.persistence.controller;
import edu.msudenver.tsp.persistence.repository.NotationRepository;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
@Component
@AllArgsConstructor
public class NotationController {
final private NotationRepository notationRepository;
}
@@ -0,0 +1,11 @@
package edu.msudenver.tsp.persistence.controller;
import edu.msudenver.tsp.persistence.repository.ProofRepository;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
@Component
@AllArgsConstructor
public class ProofController {
final private ProofRepository proofRepository;
}
@@ -0,0 +1,11 @@
package edu.msudenver.tsp.persistence.controller;
import edu.msudenver.tsp.persistence.repository.TheoremRepository;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
@Component
@AllArgsConstructor
public class TheoremController {
final private TheoremRepository theoremRepository;
}
@@ -0,0 +1,31 @@
package edu.msudenver.tsp.persistence.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Date;
@Entity(name = "accounts")
@EntityListeners(AuditingEntityListener.class)
@Data
@EqualsAndHashCode(callSuper = true)
public class AccountDto extends BaseDto implements Serializable {
@NotBlank(groups = Insert.class, message = "A username must be specified") @Size(max = 50) private String username;
@NotBlank(groups = Insert.class, message = "A password must be specified") @Size(max = 256) private String password;
@NotNull @JsonProperty("administrator_status") private boolean administratorStatus;
@Temporal(TemporalType.DATE) @JsonProperty("last_login") private Date lastLogin;
public static final long serialVersionUID = 7095627971593953734L;
public interface Insert {}
}
@@ -0,0 +1,40 @@
package edu.msudenver.tsp.persistence.dto;
import com.vladmihalcea.hibernate.type.array.IntArrayType;
import com.vladmihalcea.hibernate.type.array.StringArrayType;
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
import com.vladmihalcea.hibernate.type.json.JsonNodeBinaryType;
import com.vladmihalcea.hibernate.type.json.JsonNodeStringType;
import com.vladmihalcea.hibernate.type.json.JsonStringType;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;
import javax.persistence.*;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@MappedSuperclass
@TypeDefs({
@TypeDef(name = "string-array", typeClass = StringArrayType.class),
@TypeDef(name = "int-array", typeClass = IntArrayType.class),
@TypeDef(name = "json", typeClass = JsonStringType.class),
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class),
@TypeDef(name = "jsonb-node", typeClass = JsonNodeBinaryType.class),
@TypeDef(name = "json-node", typeClass = JsonNodeStringType.class),
})
public class BaseDto implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Version
private Integer version;
public static final long serialVersionUID = -1686252381978213945L;
}
@@ -0,0 +1,17 @@
package edu.msudenver.tsp.persistence.dto;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.util.List;
@Getter
@Setter
@ToString
public class Definition implements Serializable {
private List<String> definitions;
public static final long serialVersionUID = -2208496232532214840L;
}
@@ -0,0 +1,34 @@
package edu.msudenver.tsp.persistence.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Type;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.io.Serializable;
@Entity(name = "definitions")
@Table(name = "definitions")
@EntityListeners(AuditingEntityListener.class)
@Data
@EqualsAndHashCode(callSuper = true)
public class DefinitionDto extends BaseDto implements Serializable {
@NotBlank(groups = Insert.class, message = "A name must be specified")
@Size(min = 1, max = 200, message = "Must be between 1 and 200 characters")
private String name;
@NotBlank(groups = Insert.class, message = "At least one (1) definition must be specified")
@Type(type = "json") @Column(columnDefinition = "jsonb") private Definition definition;
@Type(type = "json") @Column(columnDefinition = "jsonb") private Notation notation;
public static final long serialVersionUID = -5314619286352932857L;
public interface Insert {}
}
@@ -0,0 +1,16 @@
package edu.msudenver.tsp.persistence.dto;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.util.List;
@Getter
@Setter
@ToString
public class Notation implements Serializable {
private List<String> notations;
public static final long serialVersionUID = 2301438318932336121L;
}
@@ -0,0 +1,4 @@
package edu.msudenver.tsp.persistence.dto;
public class NotationDto extends BaseDto {
}
@@ -0,0 +1,4 @@
package edu.msudenver.tsp.persistence.dto;
public class ProofDto extends BaseDto {
}
@@ -0,0 +1,4 @@
package edu.msudenver.tsp.persistence.dto;
public class TheoremDto extends BaseDto {
}
@@ -0,0 +1,9 @@
package edu.msudenver.tsp.persistence.repository;
import edu.msudenver.tsp.persistence.dto.AccountDto;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface AccountsRepository extends CrudRepository<AccountDto, Integer> {
}
@@ -0,0 +1,11 @@
package edu.msudenver.tsp.persistence.repository;
import edu.msudenver.tsp.persistence.dto.DefinitionDto;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface DefinitionRepository extends JpaRepository<DefinitionDto, Integer> {
}
@@ -0,0 +1,7 @@
package edu.msudenver.tsp.persistence.repository;
import edu.msudenver.tsp.persistence.dto.BaseDto;
import org.springframework.data.repository.CrudRepository;
public interface NotationRepository extends CrudRepository<BaseDto, Long> {
}
@@ -0,0 +1,7 @@
package edu.msudenver.tsp.persistence.repository;
import edu.msudenver.tsp.persistence.dto.BaseDto;
import org.springframework.data.repository.CrudRepository;
public interface ProofRepository extends CrudRepository<BaseDto, Long> {
}
@@ -0,0 +1,7 @@
package edu.msudenver.tsp.persistence.repository;
import edu.msudenver.tsp.persistence.dto.BaseDto;
import org.springframework.data.repository.CrudRepository;
public interface TheoremRepository extends CrudRepository<BaseDto, Long> {
}
@@ -0,0 +1,13 @@
spring.jpa.hibernate.ddl-auto = none
spring.jpa.database=mysql
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/pandamonium?autoReconnect=true&useSSL=false
spring.datasource.username=panda
spring.datasource.password=secret
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect
spring.jpa.show-sql = true
spring.datasource.tomcat.test-while-idle=true
spring.datasource.tomcat.validation-query=SELECT 1
logging.level.org.springframework.web=DEBUG
spring.datasource.tomcat.max-active=5
server.port=8090