diff --git a/.gitignore b/.gitignore index a1c2a23..3585c55 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,7 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +.idea/ + +target/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2d3d943 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM postgres +ENV POSTGRES_PASSWORD admin +ENV POSTGRES_DB postgres +COPY sqlscripts/docker_init.sql /docker-entrypoint-initdb.d/ \ No newline at end of file diff --git a/developer_guide/forecasting_api_doc.txt b/developer_guide/forecasting_api_doc.txt new file mode 100644 index 0000000..213394f --- /dev/null +++ b/developer_guide/forecasting_api_doc.txt @@ -0,0 +1,28 @@ +1. created a simple spring boot web application using spring intializer website. +2. using postgres as a datasource hence creating a db to provide as spring datasource. For now + only one db is created in the name of the tenant. + //TODO In a larger picture we need to serve the api for multiple clients. + // TODO Need to discuss with Sebin on how to design services that can serve multiple clients. + + The following is the command is spawn a docker container with container name postgresdb + that runs postgres server with user postgres and password admin + + docker container run --name postgresdb -e POSTGRES_PASSWORD=admin -d -p 5432:5432 postgres + use the command to check the running containers + docker container ls + +3. create a sql script that creates a database and a user for the database. +4. copy the script to the docker container + docker cp sqlscripts/forecaster.sql postgresdb:/ +5. enter into the docker container bash + docker container exec -it postgresdb bash +6. run the following command to execute the copied sql + psql -U postgres --file forecaster.sql +7. Spring offers multiple ways to configure datasource beans. one way is to set in the application.properties + another way is using java config beans. + // TODO Need to discuss with sebin how they configure multiple datasources in their company and in general. + for now going with application.properties +8. set the following properties in application.properties.(Remember that properties file doesn't allow spaces) + spring.datasource.url=jdbc:postgresql://localhost:5432/walmartdb + spring.datasource.username=walmart + spring.datasource.password=walmart@123 diff --git a/init.sh b/init.sh new file mode 100644 index 0000000..83d49e3 --- /dev/null +++ b/init.sh @@ -0,0 +1,5 @@ +docker build -t postgres_forecasting . + +docker run -it --name postgresdb -d -p 5432:5432 postgres_forecasting + +docker container exec -it postgresdb bash \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..5c60267 --- /dev/null +++ b/pom.xml @@ -0,0 +1,92 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.3.4.RELEASE + + + com.example + forecasting + 0.0.1-SNAPSHOT + forecasting + Forecasting API + + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-validation + 2.3.4.RELEASE + + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.postgresql + postgresql + runtime + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + org.mindrot + jbcrypt + 0.4 + + + + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/sqlscripts/docker_init.sql b/sqlscripts/docker_init.sql new file mode 100644 index 0000000..548cf82 --- /dev/null +++ b/sqlscripts/docker_init.sql @@ -0,0 +1,25 @@ +create user walmart with password 'walmart@123'; +create database walmartdb with template=template0 owner=walmart; +\connect walmartdb; +alter default privileges grant all on tables to walmart; +alter default privileges grant all on sequences to walmart; + +create extension "uuid-ossp"; + +create table orgs_enabled( + org_id integer primary key not null, + org_name varchar(30) not null, + is_enabled boolean not null default true +); + +create table users ( + user_id UUID primary key not null, + first_name varchar(20) not null, + last_name varchar(20), + email varchar(30) not null, + password text not null, + org_id integer not null +); + +alter table users add constraint org_id_fk foreign key (org_id) references orgs_enabled(org_id); +create sequence org_id_seq increment 1 start 1; \ No newline at end of file diff --git a/sqlscripts/forecaster.sql b/sqlscripts/forecaster.sql new file mode 100644 index 0000000..6429026 --- /dev/null +++ b/sqlscripts/forecaster.sql @@ -0,0 +1,28 @@ +drop database walmartdb; +drop user walmart; +drop sequence user_seq; +create user walmart with password 'walmart@123'; +create database walmartdb with template=template0 owner=walmart; +\connect walmartdb; +alter default privileges grant all on tables to walmart; +alter default privileges grant all on sequences to walmart; + +create table orgs_enabled( + org_id integer primary key not null, + org_name varchar(30) not null, + is_enabled boolean not null default true +); + +create table users ( + user_id UUID primary key not null, + first_name varchar(20) not null, + last_name varchar(20) not null, + email varchar(30) not null, + password text not null, + org_id integer not null +); + +alter table users add constraint org_id_fk foreign key (org_id) references orgs_enabled(org_id); + +create sequence user_seq increment 1 start 1; +create sequence org_id increment 1 start 1; \ No newline at end of file diff --git a/src/main/java/com/example/forecasting/ForecastingApplication.java b/src/main/java/com/example/forecasting/ForecastingApplication.java new file mode 100644 index 0000000..2d7610d --- /dev/null +++ b/src/main/java/com/example/forecasting/ForecastingApplication.java @@ -0,0 +1,13 @@ +package com.example.forecasting; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ForecastingApplication { + + public static void main(String[] args) { + SpringApplication.run(ForecastingApplication.class, args); + } + +} diff --git a/src/main/java/com/example/forecasting/datasource/PostgresDataSource.java b/src/main/java/com/example/forecasting/datasource/PostgresDataSource.java new file mode 100644 index 0000000..b3f9133 --- /dev/null +++ b/src/main/java/com/example/forecasting/datasource/PostgresDataSource.java @@ -0,0 +1,43 @@ +package com.example.forecasting.datasource; + +import com.zaxxer.hikari.HikariDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.jdbc.core.JdbcTemplate; + +import javax.sql.DataSource; +import javax.validation.constraints.NotNull; + +@Configuration +public class PostgresDataSource { + + @Autowired + private Environment environment; + + @Bean + @ConfigurationProperties("app.postgresource") + public HikariDataSource hikariDataSource(){ + System.out.println("My Own Spring Bean of Data Source is Created "); + HikariDataSource hds = DataSourceBuilder + .create() + .type(HikariDataSource.class) + .build(); + + Integer maxPoolSize = Integer.parseInt(environment.getProperty("app.postgresource.maxPoolSize")); + hds.setJdbcUrl(environment.getProperty("app.postgresource.jdbcUrl")); + hds.setUsername(environment.getProperty("app.postgresource.username")); + hds.setPassword(environment.getProperty("app.postgresource.password")); + hds.setMaximumPoolSize(maxPoolSize); + return hds; + } + + @Bean("walmart-postgres") + public JdbcTemplate jdbcTemplate(){ + return new JdbcTemplate(hikariDataSource()); + } +} diff --git a/src/main/java/com/example/forecasting/datasource/PostgresDataSourceLoader.java b/src/main/java/com/example/forecasting/datasource/PostgresDataSourceLoader.java new file mode 100644 index 0000000..4435c9b --- /dev/null +++ b/src/main/java/com/example/forecasting/datasource/PostgresDataSourceLoader.java @@ -0,0 +1,26 @@ +package com.example.forecasting.datasource; + +import com.zaxxer.hikari.HikariDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +import java.sql.Connection; +import java.sql.SQLException; + +@Component +public class PostgresDataSourceLoader implements ApplicationRunner { + private final HikariDataSource hikariDataSource; + + @Autowired + public PostgresDataSourceLoader(HikariDataSource hikariDataSource) { + this.hikariDataSource = hikariDataSource; + } + + @Override + public void run(ApplicationArguments args) throws SQLException { + Connection conn = hikariDataSource.getConnection(); + conn.close(); + } +} diff --git a/src/main/java/com/example/forecasting/entities/Org.java b/src/main/java/com/example/forecasting/entities/Org.java new file mode 100644 index 0000000..102fca3 --- /dev/null +++ b/src/main/java/com/example/forecasting/entities/Org.java @@ -0,0 +1,20 @@ +package com.example.forecasting.entities; + + +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.validation.constraints.NotBlank; + +public class Org { + + @NotBlank(message = "org name cannot be blank") + private String orgName; + + public Org(@JsonProperty(value = "org_name", required = true) String orgName){ + this.orgName = orgName; + } + + public String getOrgName(){ + return orgName; + } +} diff --git a/src/main/java/com/example/forecasting/entities/User.java b/src/main/java/com/example/forecasting/entities/User.java new file mode 100644 index 0000000..997d88a --- /dev/null +++ b/src/main/java/com/example/forecasting/entities/User.java @@ -0,0 +1,72 @@ +package com.example.forecasting.entities; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.springframework.lang.Nullable; +import javax.validation.constraints.NotBlank; +import java.util.UUID; + +@JsonIgnoreProperties(value = {"id"}) +public class User { + + private final UUID id; + @NotBlank(message = "First Name cannot be blank.") + private final String firstName; + // TODO implement a custom validator + @Nullable + private final String lastName; + @NotBlank(message = "email cannot be blank.") + private final String email; + @NotBlank(message = "password cannot be blank.") + private final String password; + // TODO implement a custom validator + private final String orgName; + + + public User(UUID id, + @JsonProperty(value = "first_name", required = true) String firstName, + @Nullable @JsonProperty("last_name") String lastName, + @JsonProperty(value = "email", required = true) String email, + @JsonProperty(value = "password", + access = JsonProperty.Access.WRITE_ONLY, + required = true) String password, + @JsonProperty(value = "org_name", required = true) String orgName) + { + + System.out.println("id is " + id); + System.out.println("first name is " + firstName); + System.out.println("last name is " + lastName); + System.out.println("email is " + email); + System.out.println("password is " + password); + System.out.println("org name is " + orgName); + + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.email = email; + this.password = password; + this.orgName = orgName; + } + + public String getOrgName() { + return orgName; + } + + public String getFirstName() { + return firstName; + } + + @Nullable + public String getLastName() { + return lastName; + } + + public String getEmail() { + return email; + } + + public String getPassword() { + return password; + } + +} diff --git a/src/main/java/com/example/forecasting/exceptions/GlobalExceptionHandler.java b/src/main/java/com/example/forecasting/exceptions/GlobalExceptionHandler.java new file mode 100644 index 0000000..06063b5 --- /dev/null +++ b/src/main/java/com/example/forecasting/exceptions/GlobalExceptionHandler.java @@ -0,0 +1,25 @@ +package com.example.forecasting.exceptions; + +import com.fasterxml.jackson.databind.exc.MismatchedInputException; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.MissingMatrixVariableException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import java.util.HashMap; +import java.util.Map; + +@ControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(MismatchedInputException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ResponseBody + public Map reyHandleChey(MismatchedInputException e){ + Map map = new HashMap<>(); + map.put("message", "rey handle chestunna message ila vacchindi"); + return map; + } +} diff --git a/src/main/java/com/example/forecasting/exceptions/ResourceAlreadyExists.java b/src/main/java/com/example/forecasting/exceptions/ResourceAlreadyExists.java new file mode 100644 index 0000000..44b9321 --- /dev/null +++ b/src/main/java/com/example/forecasting/exceptions/ResourceAlreadyExists.java @@ -0,0 +1,11 @@ +package com.example.forecasting.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.CONFLICT) +public class ResourceAlreadyExists extends RuntimeException{ + public ResourceAlreadyExists(String message){ + super(message); + } +} diff --git a/src/main/java/com/example/forecasting/exceptions/ResourceNotFoundException.java b/src/main/java/com/example/forecasting/exceptions/ResourceNotFoundException.java new file mode 100644 index 0000000..4539c0e --- /dev/null +++ b/src/main/java/com/example/forecasting/exceptions/ResourceNotFoundException.java @@ -0,0 +1,15 @@ +package com.example.forecasting.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.NOT_FOUND) +public class ResourceNotFoundException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public ResourceNotFoundException(String message){ + super(message); + } +} + diff --git a/src/main/java/com/example/forecasting/repositories/OrgRepository.java b/src/main/java/com/example/forecasting/repositories/OrgRepository.java new file mode 100644 index 0000000..1c2a414 --- /dev/null +++ b/src/main/java/com/example/forecasting/repositories/OrgRepository.java @@ -0,0 +1,12 @@ +package com.example.forecasting.repositories; + +public interface OrgRepository { + + public void createOrg(String org_name); + + public Integer getOrgId(String org_name); + + public void disableOrg(String org_name); + + +} diff --git a/src/main/java/com/example/forecasting/repositories/OrgRepositoryImpl.java b/src/main/java/com/example/forecasting/repositories/OrgRepositoryImpl.java new file mode 100644 index 0000000..5aab4a4 --- /dev/null +++ b/src/main/java/com/example/forecasting/repositories/OrgRepositoryImpl.java @@ -0,0 +1,56 @@ +package com.example.forecasting.repositories; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Repository; + +import javax.sql.StatementEvent; +import java.sql.PreparedStatement; +import java.sql.Statement; + + +@Repository("jdbcOrgTemplateDao") +public class OrgRepositoryImpl implements OrgRepository { + + @Qualifier("walmart-postgres") + @Autowired + private JdbcTemplate jdbcTemplate; + + private static final String ORG_CREATE_SQL = "insert into orgs_enabled (org_id, org_name) values (nextval('org_id_seq'), ?)"; + + private static final String GET_ORG_ID = "select org_id from orgs_enabled where org_name = ?"; + + @Override + public void createOrg(String org_name){ + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(ORG_CREATE_SQL, + Statement.RETURN_GENERATED_KEYS); + ps.setString(1, org_name); + return ps; + }, keyHolder); + + Integer createdOrgId = (Integer) keyHolder.getKeys().get("org_id"); + } + + @Override + public Integer getOrgId(String org_name){ + return jdbcTemplate.queryForObject(GET_ORG_ID, new Object[]{org_name}, orgIdMapper); + } + + private RowMapper orgIdMapper = ((rs, rowNum) -> { + return new Integer(rs.getString("org_id")); + }); + + @Override + public void disableOrg(String org_name){ + + + } + +} \ No newline at end of file diff --git a/src/main/java/com/example/forecasting/repositories/UserRepository.java b/src/main/java/com/example/forecasting/repositories/UserRepository.java new file mode 100644 index 0000000..b1d7e47 --- /dev/null +++ b/src/main/java/com/example/forecasting/repositories/UserRepository.java @@ -0,0 +1,19 @@ +package com.example.forecasting.repositories; + + +import com.example.forecasting.entities.User; +import org.springframework.stereotype.Repository; + +import java.util.UUID; + + +@Repository +public interface UserRepository { + + public void createUser(String firstName, String lastName, String email, String password, Integer orgId); + + public Integer getCountByEmail(String email); + + public User validateUser(String email, String password); + +} diff --git a/src/main/java/com/example/forecasting/repositories/jdbcUserRepositoryImpl.java b/src/main/java/com/example/forecasting/repositories/jdbcUserRepositoryImpl.java new file mode 100644 index 0000000..0a811d5 --- /dev/null +++ b/src/main/java/com/example/forecasting/repositories/jdbcUserRepositoryImpl.java @@ -0,0 +1,44 @@ +package com.example.forecasting.repositories; + +import com.example.forecasting.entities.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import java.sql.PreparedStatement; +import java.sql.Statement; + + +@Repository("jdbcTemplateDao") +public class jdbcUserRepositoryImpl implements UserRepository { + + @Qualifier("walmart-postgres") + @Autowired + private JdbcTemplate jdbcTemplate; + + private static final String SQL_CREATE = "insert into users (user_id, first_name, last_name, email, password, org_id) values (uuid_generate_v4(), ?, ?, ?, ?, ?)"; + + @Override + public void createUser(String firstName, String lastName, String email, String password, Integer orgId) { + jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(SQL_CREATE); + ps.setString(1, firstName); + ps.setString(2, lastName); + ps.setString(3, email); + ps.setString(4, password); + ps.setInt(5, orgId); + return ps; + }); + } + + @Override + public Integer getCountByEmail(String email) { + return null; + } + + @Override + public User validateUser(String email, String password) { + return null; + } +} diff --git a/src/main/java/com/example/forecasting/resources/OrgResource.java b/src/main/java/com/example/forecasting/resources/OrgResource.java new file mode 100644 index 0000000..0e3d0ba --- /dev/null +++ b/src/main/java/com/example/forecasting/resources/OrgResource.java @@ -0,0 +1,25 @@ +package com.example.forecasting.resources; + +import com.example.forecasting.entities.Org; +import com.example.forecasting.services.OrgService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +@RestController +@RequestMapping(value = "/orgs/") +public class OrgResource { + + @Autowired + private OrgService orgService; + + @PostMapping(value = "/register_org") + public void registerOrg(@Valid @NotNull @RequestBody Org orgBody) { + orgService.createOrg(orgBody.getOrgName()); + } +} diff --git a/src/main/java/com/example/forecasting/resources/UserResource.java b/src/main/java/com/example/forecasting/resources/UserResource.java new file mode 100644 index 0000000..46c5625 --- /dev/null +++ b/src/main/java/com/example/forecasting/resources/UserResource.java @@ -0,0 +1,42 @@ +package com.example.forecasting.resources; + + +import com.example.forecasting.entities.User; +import com.example.forecasting.services.UserService; +import com.fasterxml.jackson.core.JsonProcessingException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.Map; + +@RestController +@RequestMapping("/users/") +public class UserResource { + + private final UserService userService; + + @Autowired + public UserResource(UserService userService) { + this.userService = userService; + } + + @PostMapping("/login") + public ResponseEntity> loginUser(@RequestBody Map userMap){ + + return null; + } + + @PostMapping("/register") + public void registerUser(@Valid @NotNull @RequestBody User userMap) { + userService.registerUser(userMap.getFirstName(), + userMap.getLastName(), + userMap.getEmail(), + userMap.getPassword(), + userMap.getOrgName()); + + } +} diff --git a/src/main/java/com/example/forecasting/services/OrgService.java b/src/main/java/com/example/forecasting/services/OrgService.java new file mode 100644 index 0000000..a86f0b1 --- /dev/null +++ b/src/main/java/com/example/forecasting/services/OrgService.java @@ -0,0 +1,14 @@ +package com.example.forecasting.services; + +public interface OrgService { + + public void createOrg(String orgName); + + public boolean orgExists(String orgName); + + public boolean orgEnabled(String orgName); + + public void disableOrg(String orgName); + + public void deleteOrg(String orgName); +} diff --git a/src/main/java/com/example/forecasting/services/OrgServiceImpl.java b/src/main/java/com/example/forecasting/services/OrgServiceImpl.java new file mode 100644 index 0000000..b174534 --- /dev/null +++ b/src/main/java/com/example/forecasting/services/OrgServiceImpl.java @@ -0,0 +1,42 @@ +package com.example.forecasting.services; + +import com.example.forecasting.repositories.OrgRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class OrgServiceImpl implements OrgService{ + private OrgRepository orgRepository; + + public OrgServiceImpl(@Qualifier("jdbcOrgTemplateDao") OrgRepository orgRepository){ + this.orgRepository = orgRepository; + } + + @Override + public void createOrg(String orgName) { + orgRepository.createOrg(orgName); + } + + @Override + public boolean orgExists(String orgName) { + return false; + } + + @Override + public boolean orgEnabled(String orgName) { + return false; + } + + @Override + public void disableOrg(String orgName) { + + } + + @Override + public void deleteOrg(String orgName) { + + } +} diff --git a/src/main/java/com/example/forecasting/services/UserService.java b/src/main/java/com/example/forecasting/services/UserService.java new file mode 100644 index 0000000..8fec340 --- /dev/null +++ b/src/main/java/com/example/forecasting/services/UserService.java @@ -0,0 +1,18 @@ +package com.example.forecasting.services; + +import com.example.forecasting.entities.User; +import com.example.forecasting.exceptions.ResourceAlreadyExists; + +import java.sql.SQLDataException; + +public interface UserService { + + User validateUser(String email, String password, String org_name); + + void registerUser(String firstName, + String lastName, + String email, + String password, + String org_name); + +} diff --git a/src/main/java/com/example/forecasting/services/UserServiceImpl.java b/src/main/java/com/example/forecasting/services/UserServiceImpl.java new file mode 100644 index 0000000..0b4dca7 --- /dev/null +++ b/src/main/java/com/example/forecasting/services/UserServiceImpl.java @@ -0,0 +1,46 @@ +package com.example.forecasting.services; + +import com.example.forecasting.entities.User; +import com.example.forecasting.exceptions.ResourceAlreadyExists; +import com.example.forecasting.repositories.OrgRepository; +import com.example.forecasting.repositories.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + + +@Service +@Transactional +public class UserServiceImpl implements UserService { + private UserRepository userRepository; + + private OrgRepository orgRepository; + + @Autowired + public UserServiceImpl(@Qualifier("jdbcTemplateDao") UserRepository userRepository, + @Qualifier("jdbcOrgTemplateDao") OrgRepository orgRepository){ + this.userRepository = userRepository; + this.orgRepository = orgRepository; + } + + @Override + public User validateUser(String email, + String password, + String org_name){ + + return null; + } + + @Override + public void registerUser(String firstName, + String lastName, + String email, + String password, + String org_name) { + + Integer orgId = orgRepository.getOrgId(org_name); + + userRepository.createUser(firstName, lastName, email, password, orgId); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..99386b4 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,18 @@ +#spring: +# datasource: +# url: jdbc://postgresql://localhost:5432/walmartdb +# username: walmart +# password: walmart@123 + +app: + postgresource: + jdbcUrl: jdbc:postgresql://localhost:5432/walmartdb + username: walmart + password: walmart@123 + maxPoolSize: 15 + +server: + port: 8085 + error: + include-stacktrace: never + diff --git a/src/main/resources/db/migration/V1__forecastingtables.sql b/src/main/resources/db/migration/V1__forecastingtables.sql new file mode 100644 index 0000000..d986eff --- /dev/null +++ b/src/main/resources/db/migration/V1__forecastingtables.sql @@ -0,0 +1,20 @@ +\connect walmartdb; + + +create table orgs_enabled( + org_id integer primary key not null, + org_name varchar(30) not null, + is_enabled boolean not null default true +); + +create table users ( + user_id UUID primary key not null, + first_name varchar(20) not null, + last_name varchar(20), + email varchar(30) not null, + password text not null, + org_id integer not null +); + +alter table users add constraint org_id_fk foreign key (org_id) references orgs_enabled(org_id); +create sequence org_id_seq increment 1 start 1; \ No newline at end of file diff --git a/src/test/java/com/example/forecasting/ForecastingApplicationTests.java b/src/test/java/com/example/forecasting/ForecastingApplicationTests.java new file mode 100644 index 0000000..9199d0b --- /dev/null +++ b/src/test/java/com/example/forecasting/ForecastingApplicationTests.java @@ -0,0 +1,13 @@ +package com.example.forecasting; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ForecastingApplicationTests { + + @Test + void contextLoads() { + } + +}