Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Submit Assessment KBTG #29

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions posttest/Dockerfile.multi
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#FROM amazoncorretto:17.0.9-alpine3.18
#WORKDIR /app
#COPY ./build/libs/posttest-0.0.1-SNAPSHOT.jar /app/
#ENTRYPOINT ["java", "-jar", "posttest-0.0.1-SNAPSHOT.jar"]

FROM amazoncorretto:17.0.9-alpine3.18 as builder
WORKDIR /app
ADD . .
RUN ["./gradlew","clean","bootJar"]

FROM gcr.io/distroless/java17-debian12:latest
WORKDIR /app
COPY --from=builder /app/build/libs/posttest-0.0.1-SNAPSHOT.jar posttest-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java", "-jar", "posttest-0.0.1-SNAPSHOT.jar"]
40 changes: 40 additions & 0 deletions posttest/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,48 @@ dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-validation'
testImplementation 'org.testcontainers:testcontainers:1.19.1'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
}

sourceSets {
integrationTest {
java {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/test/java')
}
}
}

configurations {
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
integrationTestImplementation.extendsFrom testImplementation
}

tasks.register('integrationTest', Test) {
// to prevent Mockito's inline mock maker fail on container
jvmArgs('-Djdk.attach.allowAttachSelf=true', '-XX:+StartAttachListener')

description = 'Runs integration tests.'
group = 'verification'
useJUnitPlatform()
filter {
include '**/*IntegrationTest.*'
}
}

tasks.named('test') {
filter {
exclude '**/*IntegrationTest.*'
}
// to prevent Mockito's inline mock maker fail on container
jvmArgs('-Djdk.attach.allowAttachSelf=true', '-XX:+StartAttachListener')
useJUnitPlatform()
finalizedBy jacocoTestReport
}
37 changes: 37 additions & 0 deletions posttest/db/init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
CREATE SEQUENCE public.lottery_id_seq
INCREMENT 1
START 1
MINVALUE 1
MAXVALUE 9223372036854775807
CACHE 1;

CREATE SEQUENCE public.user_ticket_user_id_seq
START WITH 1000000000
INCREMENT BY 1
MINVALUE 1000000000
MAXVALUE 9999999999
CACHE 1;

CREATE TABLE public.lottery
(
id INTEGER NOT NULL,
amount INTEGER,
price NUMERIC(38,2),
ticket_number CHARACTER VARYING(6) COLLATE pg_catalog."default" UNIQUE,
user_id INTEGER,
CONSTRAINT user_id_length CHECK (user_id >= 1000000000 AND user_id <= 9999999999),
CONSTRAINT lottery_pkey PRIMARY KEY (id)
);

CREATE TABLE public.user_ticket
(
user_id INTEGER NOT NULL,
total_price NUMERIC(10,2),
CONSTRAINT user_ticket_pkey PRIMARY KEY (user_id)
);

INSERT INTO lottery (id, amount, price, ticket_number, user_id)
VALUES (101, 1, 300, '112233', null), (102, 2, 150, '090911', null);

INSERT INTO public.user_ticket (user_id, total_price)
VALUES (1111111111, 00.00), (1222222222, 00.00), (1333333555, 00.00);
35 changes: 35 additions & 0 deletions posttest/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
version: '3.8'
services:
app:
image: gcr.io/distroless/java17-debian12:latest
ports:
- "8888:8888"
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/LotteryDB
SPRING_DATASOURCE_USERNAME: postgres
SPRING_DATASOURCE_PASSWORD: admin
SPRING_JPA_HIBERNATE_DDL-AUTO: none
SPRING_DATASOURCE_DRIVER-CLASS-NAME: org.postgresql.Driver
SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT: org.hibernate.dialect.PostgreSQLDialect
SPRING_SECURITY_USER_NAME: admin
SPRING_SECURITY_USER_PASSWORD: password
LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_SECURITY: DEBUG
depends_on:
- db
volumes:
- ./build/libs:/app
entrypoint: ["java", "-jar", "/app/posttest-0.0.1-SNAPSHOT.jar"]

db:
image: postgres:latest
environment:
POSTGRES_DB: LotteryDB
POSTGRES_USER: postgres
POSTGRES_PASSWORD: admin
ports:
- "5432:5432"
volumes:
- ./db:/docker-entrypoint-initdb.d/

volumes:
postgres_data:
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.kbtg.bootcamp.posttest.controller;

import com.kbtg.bootcamp.posttest.dto.AdminRequestDto;
import com.kbtg.bootcamp.posttest.dto.AdminResponseDto;
import com.kbtg.bootcamp.posttest.service.AdminsService;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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;

@RestController
@RequestMapping("/admin")
public class AdminsController {
private final AdminsService adminService;

public AdminsController(AdminsService adminService) {
this.adminService = adminService;
}

@PostMapping("/lotteries")
public ResponseEntity<AdminResponseDto> checkAdminRoles(@Valid @RequestBody AdminRequestDto requestDto) throws Exception {
AdminResponseDto responseDto;
this.adminService.validateAdminReq(requestDto);
responseDto = this.adminService.createLottery(requestDto);
return ResponseEntity.status(HttpStatus.CREATED).body(responseDto);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.kbtg.bootcamp.posttest.controller;


import com.kbtg.bootcamp.posttest.dto.ProductResponseDTO;
import com.kbtg.bootcamp.posttest.service.ProductService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("")
public class ProductController {
private final ProductService productService;

public ProductController(ProductService productService) {
this.productService = productService;
}

@GetMapping("/lotteries")
public ProductResponseDTO getProductList() throws Exception {
return this.productService.getAllProduct();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.kbtg.bootcamp.posttest.controller;

import com.kbtg.bootcamp.posttest.dto.ProductResponseDTO;
import com.kbtg.bootcamp.posttest.dto.UserResponseDto;
import com.kbtg.bootcamp.posttest.service.UserService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/users")
public class UserController {

private final UserService userService;

public UserController(UserService userService) {
this.userService = userService;
}

@PostMapping("/{userId}/lotteries/{ticketId}")
public ResponseEntity<UserResponseDto> buyLotteryTicket(@PathVariable String userId, @PathVariable String ticketId)throws Exception {
UserResponseDto responseDto;
responseDto = this.userService.buyLotteryTicketProcess(userId,ticketId);
return ResponseEntity.status(HttpStatus.CREATED).body(responseDto);
}

@GetMapping("/{userId}/lotteries")
public ResponseEntity<ProductResponseDTO> getAllMyTickets(@PathVariable String userId)throws Exception {
ProductResponseDTO responseDto;
responseDto = this.userService.getAllMyTicketsProcess(userId);
return ResponseEntity.status(HttpStatus.OK).body(responseDto);
}

@DeleteMapping("/{userId}/lotteries/{ticketId}")
public ResponseEntity<ProductResponseDTO> deleteLotteryTicket(@PathVariable String userId, @PathVariable String ticketId)throws Exception {
ProductResponseDTO responseDto;
responseDto = this.userService.deleteLotteryTicketProcess(userId,ticketId);
return ResponseEntity.status(HttpStatus.OK).body(responseDto);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.kbtg.bootcamp.posttest.dao;


import com.kbtg.bootcamp.posttest.entity.LotteryEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface LotteryRepository extends JpaRepository<LotteryEntity, Long>, JpaSpecificationExecutor<LotteryEntity> {

@Query(value = "select * from lottery where user_id = :userId ",nativeQuery = true)
List<LotteryEntity> findByUserId(@Param("userId") Long userId);

@Query(value = "select * from lottery where user_id is null ",nativeQuery = true)
List<LotteryEntity> findAllWithOutOwner();

@Query(value = "select * from lottery where id = :id and user_id = :user_id ",nativeQuery = true)
LotteryEntity findByIdAndUserId(@Param("id") Long id,@Param("user_id") Long user_id);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.kbtg.bootcamp.posttest.dao;


import com.kbtg.bootcamp.posttest.entity.UserTicketEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface UserTicketRepository extends JpaRepository<UserTicketEntity, Long>, JpaSpecificationExecutor<UserTicketEntity> {
@Query(value = "select * from user_ticket where user_id = :user_id ",nativeQuery = true)
UserTicketEntity findByUserId(@Param("user_id") Long userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.kbtg.bootcamp.posttest.dto;

public class AdminRequestDto {

private String ticket;

private Integer price;

private Integer amount;

public AdminRequestDto(String ticket, Integer price, Integer amount) {
this.ticket = ticket;
this.price = price;
this.amount = amount;
}

public String getTicket() {
return ticket;
}

public void setTicket(String ticket) {
this.ticket = ticket;
}

public Integer getPrice() {
return price;
}

public void setPrice(Integer price) {
this.price = price;
}

public Integer getAmount() {
return amount;
}

public void setAmount(Integer amount) {
this.amount = amount;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.kbtg.bootcamp.posttest.dto;

public class AdminResponseDto {
private String ticket;

public AdminResponseDto(){

}

public AdminResponseDto(String ticket) {
this.ticket = ticket;
}

public String getTicket() {
return ticket;
}

public void setTicket(String ticket) {
this.ticket = ticket;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.kbtg.bootcamp.posttest.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;

import java.util.List;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ProductResponseDTO {
private List<String> tickets;

private String ticket;


private String totalPrice;

public ProductResponseDTO() {
}

public ProductResponseDTO(List<String> tickets,String ticket, String totalPrice) {
this.tickets = tickets;
this.ticket = ticket;
this.totalPrice = totalPrice;
}

public List<String> getTickets() {
return tickets;
}

public void setTickets(List<String> tickets) {
this.tickets = tickets;
}

public String getTotalPrice() {
return totalPrice;
}

public void setTotalPrice(String totalPrice) {
this.totalPrice = totalPrice;
}

public String getTicket() {
return ticket;
}

public void setTicket(String ticket) {
this.ticket = ticket;
}
}
Loading