From 490f859fdcda86ba652daa840cbdafe653e75475 Mon Sep 17 00:00:00 2001 From: JaeYong Date: Mon, 28 Aug 2023 16:41:41 +0900 Subject: [PATCH 01/83] =?UTF-8?q?=EA=B8=B0=EC=B4=88=20Entity,=20Auditable,?= =?UTF-8?q?=20Swagger=20=EC=83=98=ED=94=8C=EC=BD=94=EB=93=9C=20=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mapstruct 의존성 추가 H2 데이터베이스 연결 추가 --- server/008main_project/build.gradle | 3 + .../stockholm/main_project/Application.java | 2 + .../main_project/audit/Auditable.java | 24 ++++++++ .../main_project/board/entity/Board.java | 37 +++++++++++++ .../main_project/board/entity/Comment.java | 30 ++++++++++ .../main_project/config/SwaggerConfig.java | 53 ++++++++++++++++++ .../main_project/member/entity/Member.java | 51 +++++++++++++++++ .../main_project/stock/entity/Company.java | 27 +++++++++ .../main_project/stock/entity/StockHold.java | 33 +++++++++++ .../main_project/stock/entity/StockOrder.java | 36 ++++++++++++ .../swaggersample/HelloController.java | 55 +++++++++++++++++++ .../swaggersample/HelloPostDto.java | 12 ++++ .../swaggersample/HelloResponse.java | 16 ++++++ .../src/main/resources/application.yml | 27 +++++++++ 14 files changed, 406 insertions(+) create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/audit/Auditable.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Board.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Comment.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/config/SwaggerConfig.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Member.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockHold.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockOrder.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloController.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloPostDto.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloResponse.java diff --git a/server/008main_project/build.gradle b/server/008main_project/build.gradle index a069a99d..c3d93d6d 100644 --- a/server/008main_project/build.gradle +++ b/server/008main_project/build.gradle @@ -26,6 +26,9 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' + implementation 'org.springdoc:springdoc-openapi-ui:1.6.15' + implementation 'org.mapstruct:mapstruct:1.5.3.Final' + annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final' runtimeOnly 'com.h2database:h2' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/Application.java b/server/008main_project/src/main/java/com/stockholm/main_project/Application.java index a5f09ec6..d20b44ab 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/Application.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/Application.java @@ -2,7 +2,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +@EnableJpaAuditing @SpringBootApplication public class Application { diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/audit/Auditable.java b/server/008main_project/src/main/java/com/stockholm/main_project/audit/Auditable.java new file mode 100644 index 00000000..812dfa7b --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/audit/Auditable.java @@ -0,0 +1,24 @@ +package com.stockholm.main_project.audit; + +import lombok.Getter; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.Column; +import javax.persistence.EntityListeners; +import javax.persistence.MappedSuperclass; +import java.time.LocalDateTime; + +@Getter +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +public abstract class Auditable { + @CreatedDate + @Column(updatable = false) + LocalDateTime createdAt; + + @LastModifiedDate + @Column + LocalDateTime modifiedAt; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Board.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Board.java new file mode 100644 index 00000000..0ec42074 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Board.java @@ -0,0 +1,37 @@ +package com.stockholm.main_project.board.entity; + +import com.stockholm.main_project.audit.Auditable; +import com.stockholm.main_project.member.entity.Member; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.*; + + +@Entity +@Getter +@Setter +@NoArgsConstructor +public class Board extends Auditable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long boardId; + + @Column + private String title; + + @Column + private String body; + + @Column + private String fileName; + + @Column + private String filePath; + + @ManyToOne + @JoinColumn(name = "MEMBER_ID") + private Member member; + +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Comment.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Comment.java new file mode 100644 index 00000000..6b446972 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Comment.java @@ -0,0 +1,30 @@ +package com.stockholm.main_project.board.entity; + +import com.stockholm.main_project.audit.Auditable; +import com.stockholm.main_project.member.entity.Member; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.*; + +@Entity +@Getter +@Setter +@NoArgsConstructor +public class Comment extends Auditable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long commentId; + + @Column + private String body; + + @ManyToOne + @JoinColumn(name = "BOARD_ID") + private Board board; + + @ManyToOne + @JoinColumn(name = "MEMBER_ID") + private Member member; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/config/SwaggerConfig.java b/server/008main_project/src/main/java/com/stockholm/main_project/config/SwaggerConfig.java new file mode 100644 index 00000000..7480e32e --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/config/SwaggerConfig.java @@ -0,0 +1,53 @@ +package com.stockholm.main_project.config; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import lombok.RequiredArgsConstructor; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; + +@OpenAPIDefinition( + info = @Info(title = "Stockholm API 명세서", + description = "모의주식 투자 연습 사이트", + version = "v1")) +@RequiredArgsConstructor +@Configuration +public class SwaggerConfig { + + @Bean + public OpenAPI openAPI() { + + + // SecuritySecheme명 + String jwtSchemeName = "jwtAuth"; + // API 요청헤더에 인증정보 포함 + SecurityRequirement securityRequirement = new SecurityRequirement().addList(jwtSchemeName); + // SecuritySchemes 등록 + Components components = new Components() + .addSecuritySchemes(jwtSchemeName, new SecurityScheme() + .name(jwtSchemeName) + .type(SecurityScheme.Type.HTTP) // HTTP 방식 + .scheme("bearer") + .bearerFormat("JWT")); // 토큰 형식을 지정하는 임의의 문자(Optional) + + return new OpenAPI() + .addSecurityItem(securityRequirement) + .components(components); + } + + @Bean + public GroupedOpenApi chatOpenApi() { + String[] paths = {"/stockholm/**"}; + + return GroupedOpenApi.builder() + .group("stockholm API v1") + .pathsToMatch(paths) + .build(); + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Member.java b/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Member.java new file mode 100644 index 00000000..99060911 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Member.java @@ -0,0 +1,51 @@ +package com.stockholm.main_project.member.entity; + +import com.stockholm.main_project.audit.Auditable; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@Setter +@NoArgsConstructor +public class Member extends Auditable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long memberId; + + @Column + private String email; + + @Column + private String name; + + @Column + private String password; + + @Column + private long cash; + + @Enumerated(value = EnumType.STRING) + @Column(length = 20, nullable = false) + private MemberStatus memberStatus = MemberStatus.MEMBER_ACTIVE; + + @ElementCollection(fetch = FetchType.EAGER) + private List roles = new ArrayList<>(); + + public enum MemberStatus { + MEMBER_ACTIVE("활동중"), + MEMBER_QUIT("탈퇴 상태"); + + @Getter + private String status; + + MemberStatus(String status) { + this.status = status; + } + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java new file mode 100644 index 00000000..ac5f5c2a --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java @@ -0,0 +1,27 @@ +package com.stockholm.main_project.stock.entity; + +import com.stockholm.main_project.audit.Auditable; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.*; + +@Entity +@Getter +@Setter +@NoArgsConstructor +public class Company extends Auditable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long companyId; + + @Column + private int code; + + @Column + private String korname; + + @Column + private String information; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockHold.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockHold.java new file mode 100644 index 00000000..b0b3745b --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockHold.java @@ -0,0 +1,33 @@ +package com.stockholm.main_project.stock.entity; + +import com.stockholm.main_project.audit.Auditable; +import com.stockholm.main_project.member.entity.Member; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.*; + +@Entity +@Getter +@Setter +@NoArgsConstructor +public class StockHold extends Auditable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long stockHoldId; + + @Column + private int stockCount; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "COMPANY_ID") + private Company company; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "MEMBER_ID") + private Member member; + + @Column + private long price; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockOrder.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockOrder.java new file mode 100644 index 00000000..d2c60473 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockOrder.java @@ -0,0 +1,36 @@ +package com.stockholm.main_project.stock.entity; + +import com.stockholm.main_project.audit.Auditable; +import com.stockholm.main_project.member.entity.Member; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.*; + +@Entity +@Getter +@Setter +@NoArgsConstructor +public class StockOrder extends Auditable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long stockOrderId; + + @Column + private int stockCount; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "MEMBER_ID") + private Member member; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "COMPANY_ID") + private Company company; + + @Column + private boolean orderType; + + @Column + private long price; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloController.java b/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloController.java new file mode 100644 index 00000000..29bef8a8 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloController.java @@ -0,0 +1,55 @@ +package com.stockholm.main_project.swaggersample; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/stockholm") +public class HelloController { + + @Operation(summary = "hello post 요청", description = "post됩니다.", tags = { "Member" }) + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(schema = @Schema(implementation = HelloResponse.class))), + @ApiResponse(responseCode = "400", description = "BAD REQUEST"), + @ApiResponse(responseCode = "404", description = "NOT FOUND"), + @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR") + }) + @PostMapping + public ResponseEntity helloPost( + @RequestBody @Schema(implementation = HelloPostDto.class) HelloPostDto helloPostDto) { + HelloResponse helloResponse = new HelloResponse(); + + helloResponse.setId(1); + helloResponse.setText(helloResponse.getText()); + + return new ResponseEntity<>(helloResponse, HttpStatus.OK); + } + + @Operation(summary = "hello get 요청", description = "get됩니다.", tags = { "Member" }) + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "OK", + content = @Content(schema = @Schema(implementation = HelloResponse.class))), + @ApiResponse(responseCode = "400", description = "BAD REQUEST"), + @ApiResponse(responseCode = "404", description = "NOT FOUND"), + @ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR") + }) + @GetMapping("{id}") + public ResponseEntity helloGet( + @Parameter(description = "id값") + @PathVariable("id") String id) { + HelloResponse helloResponse = new HelloResponse(); + + helloResponse.setId(1); + helloResponse.setText("hello"); + + return new ResponseEntity<>(helloResponse, HttpStatus.OK); + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloPostDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloPostDto.java new file mode 100644 index 00000000..9e64411a --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloPostDto.java @@ -0,0 +1,12 @@ +package com.stockholm.main_project.swaggersample; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class HelloPostDto { + @Schema(description = "내용", defaultValue = "hello") + private String text; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloResponse.java b/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloResponse.java new file mode 100644 index 00000000..f4c1b438 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/swaggersample/HelloResponse.java @@ -0,0 +1,16 @@ +package com.stockholm.main_project.swaggersample; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class HelloResponse { + @Schema(description = "아이디", defaultValue = "1") + private long id; + @Schema(description = "내용", defaultValue = "hello") + private String text; +} diff --git a/server/008main_project/src/main/resources/application.yml b/server/008main_project/src/main/resources/application.yml index 8b137891..c5ede541 100644 --- a/server/008main_project/src/main/resources/application.yml +++ b/server/008main_project/src/main/resources/application.yml @@ -1 +1,28 @@ +spring: + h2: + console: + enabled: true + path: /h2 + settings: + web-allow-others: true + datasource: + url: jdbc:h2:mem:test + jpa: + hibernate: + ddl-auto: create-drop + show-sql: true +springdoc: + swagger-ui: + path: /swagger-ui.html + groups-order: DESC + operationsSorter: method + disable-swagger-default-url: true + display-request-duration: true + api-docs: + path: /api-docs + show-actuator: true + default-consumes-media-type: application/json + default-produces-media-type: application/json + paths-to-match: + - /stockholm/** \ No newline at end of file From 2b99e3e275e5d3ba7331aed90b8164b0f13d8434 Mon Sep 17 00:00:00 2001 From: JaeYong Date: Tue, 29 Aug 2023 10:31:52 +0900 Subject: [PATCH 02/83] =?UTF-8?q?[Fix]=20Entity=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit StockHold 테이블 삭제 Image 테이블 추가 Cash 테이블 추가 StockOrder 필드 추가 --- .../main_project/board/entity/Board.java | 6 ---- .../main_project/board/entity/Image.java | 25 ++++++++++++++++ .../main_project/member/entity/Cash.java | 27 +++++++++++++++++ .../main_project/member/entity/Member.java | 3 -- .../main_project/stock/entity/Company.java | 2 +- .../entity/{StockHold.java => Star.java} | 16 ++++------ .../main_project/stock/entity/StockOrder.java | 29 +++++++++++++++++-- 7 files changed, 85 insertions(+), 23 deletions(-) create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Image.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Cash.java rename server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/{StockHold.java => Star.java} (79%) diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Board.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Board.java index 0ec42074..2aab95de 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Board.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Board.java @@ -24,12 +24,6 @@ public class Board extends Auditable { @Column private String body; - @Column - private String fileName; - - @Column - private String filePath; - @ManyToOne @JoinColumn(name = "MEMBER_ID") private Member member; diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Image.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Image.java new file mode 100644 index 00000000..58c2c040 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Image.java @@ -0,0 +1,25 @@ +package com.stockholm.main_project.board.entity; + +import com.stockholm.main_project.audit.Auditable; +import com.stockholm.main_project.member.entity.Member; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.*; + +@Getter +@Setter +@NoArgsConstructor +public class Image extends Auditable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long imageId; + + @ManyToOne + @JoinColumn(name = "BOARD_ID") + private Board board; + + @Column + private String imageUrl; +} \ No newline at end of file diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Cash.java b/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Cash.java new file mode 100644 index 00000000..8fd10e62 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Cash.java @@ -0,0 +1,27 @@ +package com.stockholm.main_project.member.entity; + +import com.stockholm.main_project.audit.Auditable; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.*; + + +@Entity +@Getter +@Setter +@NoArgsConstructor +public class Cash extends Auditable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long cashId; + + @ManyToOne + @JoinColumn(name = "MEMBER_ID") + private Member member; + + @Column + private long money; + +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Member.java b/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Member.java index 99060911..1a51ebb6 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Member.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Member.java @@ -27,9 +27,6 @@ public class Member extends Auditable { @Column private String password; - @Column - private long cash; - @Enumerated(value = EnumType.STRING) @Column(length = 20, nullable = false) private MemberStatus memberStatus = MemberStatus.MEMBER_ACTIVE; diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java index ac5f5c2a..1b6bc8fc 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java @@ -20,7 +20,7 @@ public class Company extends Auditable { private int code; @Column - private String korname; + private String korName; @Column private String information; diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockHold.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Star.java similarity index 79% rename from server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockHold.java rename to server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Star.java index b0b3745b..c0d9dabd 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockHold.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Star.java @@ -12,22 +12,16 @@ @Getter @Setter @NoArgsConstructor -public class StockHold extends Auditable { +public class Star extends Auditable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private long stockHoldId; - - @Column - private int stockCount; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "COMPANY_ID") - private Company company; + private long starId; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "MEMBER_ID") private Member member; - @Column - private long price; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "COMPANY_ID") + private Company company; } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockOrder.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockOrder.java index d2c60473..94343413 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockOrder.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockOrder.java @@ -28,9 +28,34 @@ public class StockOrder extends Auditable { @JoinColumn(name = "COMPANY_ID") private Company company; - @Column - private boolean orderType; + @Enumerated(value = EnumType.STRING) + @Column(length = 20, nullable = false) + private OrderTypes OrderTypes; + + @Enumerated(value = EnumType.STRING) + @Column(length = 20, nullable = false) + private OrderStatus OrderStatus; @Column private long price; + + public enum OrderTypes { + SELL("매도"), + BUY("매수"); + @Getter + private String types; + + OrderTypes(String types) { this.types = types; } + } + + public enum OrderStatus { + ORDER_COMPLETE("채결 완료"), + ORDER_WAIT("체결 대기"); + @Getter + private String status; + + OrderStatus(String status) { + this.status = status; + } + } } From f699d94922b3c192bf2db9a74edf024130063b3d Mon Sep 17 00:00:00 2001 From: ChoHD Date: Tue, 29 Aug 2023 15:45:17 +0900 Subject: [PATCH 03/83] =?UTF-8?q?Feat:=20API=20=ED=98=B8=EC=B6=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2023.08.29 --- .../stockdata/controller/StockController.java | 36 +++++++ .../stockdata/dto/StockasbiDataConverter.java | 48 ++++++++++ .../stock/stockdata/dto/StockasbiDataDto.java | 22 +++++ .../stock/stockdata/service/StockService.java | 94 +++++++++++++++++++ 4 files changed, 200 insertions(+) create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java new file mode 100644 index 00000000..0f4f6442 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java @@ -0,0 +1,36 @@ +package com.stockholm.main_project.stock.stockdata.controller; + + +import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataDto; +import com.stockholm.main_project.stock.stockdata.service.StockService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +@Controller +public class StockController { + + @Autowired + private StockService stockService; + + + @ResponseBody + @GetMapping("/stockasbi") + public ResponseEntity> getStockasbiData() { + List stockDatas = stockService.getStockasbiData(); + return ResponseEntity.ok(stockDatas); + } + @ResponseBody + @GetMapping("/stockhour") + public ResponseEntity> getStockhourData() { + List stockDatas = stockService.getStockhourData(); + return ResponseEntity.ok(stockDatas); + } +} + diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java new file mode 100644 index 00000000..4eacbeba --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java @@ -0,0 +1,48 @@ +package com.stockholm.main_project.stock.stockdata.dto; + +import java.util.Map; + +public class StockasbiDataConverter { + public StockasbiDataDto convertToStockasbiDataDto(Map apiResponse) { + StockasbiDataDto dto = new StockasbiDataDto(); + + Map output1 = (Map) apiResponse.get("output1"); + Map output2 = (Map) apiResponse.get("output2"); + + dto.setAskp1((String) output1.get("askp1")); + dto.setAskp2((String) output1.get("askp2")); + dto.setAskp1((String) output1.get("askp3")); + dto.setAskp1((String) output1.get("askp4")); + dto.setAskp1((String) output1.get("askp5")); + + dto.setBidp1((String) output1.get("bidp1")); + dto.setBidp2((String) output1.get("bidp2")); + dto.setBidp1((String) output1.get("bidp3")); + dto.setBidp1((String) output1.get("bidp4")); + dto.setBidp1((String) output1.get("bidp5")); + + + dto.setAskp_rsqn1((String) output1.get("askp_rsqn1")); + dto.setAskp_rsqn2((String) output1.get("askp_rsqn2")); + dto.setAskp_rsqn2((String) output1.get("askp_rsqn3")); + dto.setAskp_rsqn2((String) output1.get("askp_rsqn4")); + dto.setAskp_rsqn2((String) output1.get("askp_rsqn5")); + + dto.setBidp_rsqn1((String) output1.get("bidp_rsqn1")); + dto.setBidp_rsqn2((String) output1.get("bidp_rsqn2")); + dto.setBidp_rsqn1((String) output1.get("bidp_rsqn3")); + dto.setBidp_rsqn1((String) output1.get("bidp_rsqn4")); + dto.setBidp_rsqn1((String) output1.get("bidp_rsqn5")); + + + + dto.setAspr_acpt_hour((String) output2.get("aspr_acpt_hour")); + dto.setStck_prpr((String) output2.get("stck_prpr")); + dto.setStck_oprc((String) output2.get("stck_oprc")); + dto.setStck_hgpr((String) output2.get("stck_hgpr")); + dto.setStck_lwpr((String) output2.get("stck_lwpr")); + dto.setStck_sdpr((String) output2.get("stck_sdpr")); + + return dto; + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java new file mode 100644 index 00000000..a6b7edd8 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java @@ -0,0 +1,22 @@ +package com.stockholm.main_project.stock.stockdata.dto; + +import lombok.*; + +import javax.persistence.Entity; + + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class StockasbiDataDto { + private String askp1, askp2, askp3, askp4, askp5; + private String bidp1, bidp2, bidp3, bidp4, bidp5; + private String askp_rsqn1, askp_rsqn2, askp_rsqn3, askp_rsqn4, askp_rsqn5; + private String bidp_rsqn1, bidp_rsqn2, bidp_rsqn3, bidp_rsqn4, bidp_rsqn5; + private String aspr_acpt_hour; + private String stck_prpr; + private String stck_oprc; + private String stck_hgpr; + private String stck_lwpr; + private String stck_sdpr; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java new file mode 100644 index 00000000..9fe81463 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java @@ -0,0 +1,94 @@ +package com.stockholm.main_project.stock.stockdata.service; + + +import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataConverter; +import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataDto; +import org.springframework.stereotype.Service; +import org.springframework.http.*; +import org.springframework.web.client.RestTemplate; + +import java.util.*; + + +@Service +public class StockService { + private final StockasbiDataConverter converter = new StockasbiDataConverter(); + private final String APP_KEY = "PSjMh9iyz0EFvbpWkvuYHfLiFuHyNAtLoG9h"; + private final String APP_SECRET = "vtzv7bG78qgtThPEujr1MWDJHKTawSoEDRfAJzB/lYvwj67HdzUsyUavVGD4kORIeGS5q6BJBwoICXy97h8d3RaSAvhK03Yu/seFm0t+22ZQBv4GKhxvU5jGwdMrsucyKuQ0EtXfkJxJoLFsqIO1UA1n3r4HX0D5RxIe8I8efwEYVbidAn4="; + private final String TOKEN_URL = "https://openapi.koreainvestment.com:9443/oauth2/tokenP"; + private final String STOCKASBI_URL = "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-asking-price-exp-ccn"; + private final String STOCKHOUR_URL = "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-time-itemconclusion"; + private final String START_TIME = "155000"; + + private final List DEFAULT_STOCK_CODES = Arrays.asList( + "005930", "373220", "000660", "207940", "005490" +// "005935", "006400" +// "051910" +// "005380", "003670" +// "035420", "000270", "012330", "035720", "068270" + ); + + private RestTemplate restTemplate = new RestTemplate(); + + public String getAccessToken() { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + Map body = new HashMap<>(); + body.put("grant_type", "client_credentials"); + body.put("appkey", APP_KEY); + body.put("appsecret", APP_SECRET); + + HttpEntity> request = new HttpEntity<>(body, headers); + + ResponseEntity response = restTemplate.postForEntity(TOKEN_URL, request, Map.class); + + return response.getBody().get("access_token").toString(); + } + + public List getStockasbiData() { + List stockDatas = new ArrayList<>(); + for (String stockCode : DEFAULT_STOCK_CODES) { + String token = getAccessToken(); + + HttpHeaders headers = new HttpHeaders(); + headers.add("Authorization", "Bearer " + token); + headers.add("appkey", APP_KEY); + headers.add("appsecret", APP_SECRET); + headers.add("tr_id", "FHKST01010200"); + + String uri = STOCKASBI_URL + "?FID_COND_MRKT_DIV_CODE=J&FID_INPUT_ISCD=" + stockCode; + + HttpEntity entity = new HttpEntity<>("parameters", headers); + + ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, Map.class); + StockasbiDataDto dto = converter.convertToStockasbiDataDto(response.getBody()); + + stockDatas.add(dto); + } + return stockDatas; + } + public List getStockhourData() { + List stockDatas = new ArrayList<>(); + for (String stockCode : DEFAULT_STOCK_CODES) { + String token = getAccessToken(); + + HttpHeaders headers = new HttpHeaders(); + headers.add("Authorization", "Bearer " + token); + headers.add("appkey", APP_KEY); + headers.add("appsecret", APP_SECRET); + headers.add("tr_id", "FHPST01060000"); + + String uri = STOCKHOUR_URL + + "?FID_COND_MRKT_DIV_CODE=J&FID_INPUT_ISCD=" + stockCode + + "&FID_INPUT_HOUR_1=" + START_TIME; + + HttpEntity entity = new HttpEntity<>("parameters", headers); + + ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class); + + stockDatas.add(response.getBody()); + } + return stockDatas; + } +} From 7503900c9d1f38a79938ea0620ef986d50248301 Mon Sep 17 00:00:00 2001 From: ChoHD Date: Tue, 29 Aug 2023 17:32:19 +0900 Subject: [PATCH 04/83] =?UTF-8?q?Feat:=20API=20=ED=98=B8=EC=B6=9C=20(?= =?UTF-8?q?=EC=A3=BC=EC=8B=9D=EB=8B=B9=EC=9D=BC=EB=B6=84=EB=B4=89=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C,=20=EC=A3=BC=EC=8B=9D=ED=98=84=EC=9E=AC=EA=B0=80=20?= =?UTF-8?q?=ED=98=B8=EA=B0=80/=EC=98=88=EC=83=81=EC=B3=AC=EA=B2=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2023.08.29 --- .../stockdata/controller/StockController.java | 7 ++-- .../stockdata/dto/StockasbiDataConverter.java | 26 +++++++------- .../stock/stockdata/dto/StockasbiDataDto.java | 3 +- .../stockdata/dto/StockminConverter.java | 31 ++++++++++++++++ .../stock/stockdata/dto/StockminDto.java | 16 +++++++++ .../stock/stockdata/service/StockService.java | 36 +++++++++++-------- 6 files changed, 86 insertions(+), 33 deletions(-) create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockminConverter.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockminDto.java diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java index 0f4f6442..b2dc8586 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java @@ -2,6 +2,7 @@ import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataDto; +import com.stockholm.main_project.stock.stockdata.dto.StockminDto; import com.stockholm.main_project.stock.stockdata.service.StockService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; @@ -27,9 +28,9 @@ public ResponseEntity> getStockasbiData() { return ResponseEntity.ok(stockDatas); } @ResponseBody - @GetMapping("/stockhour") - public ResponseEntity> getStockhourData() { - List stockDatas = stockService.getStockhourData(); + @GetMapping("/stockmin") + public ResponseEntity> getStockminData() { + List stockDatas = stockService.getStockminData(); return ResponseEntity.ok(stockDatas); } } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java index 4eacbeba..dd76fb85 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java @@ -11,32 +11,30 @@ public StockasbiDataDto convertToStockasbiDataDto(Map apiRespons dto.setAskp1((String) output1.get("askp1")); dto.setAskp2((String) output1.get("askp2")); - dto.setAskp1((String) output1.get("askp3")); - dto.setAskp1((String) output1.get("askp4")); - dto.setAskp1((String) output1.get("askp5")); + dto.setAskp3((String) output1.get("askp3")); + dto.setAskp4((String) output1.get("askp4")); + dto.setAskp5((String) output1.get("askp5")); dto.setBidp1((String) output1.get("bidp1")); dto.setBidp2((String) output1.get("bidp2")); - dto.setBidp1((String) output1.get("bidp3")); - dto.setBidp1((String) output1.get("bidp4")); - dto.setBidp1((String) output1.get("bidp5")); + dto.setBidp3((String) output1.get("bidp3")); + dto.setBidp4((String) output1.get("bidp4")); + dto.setBidp5((String) output1.get("bidp5")); dto.setAskp_rsqn1((String) output1.get("askp_rsqn1")); dto.setAskp_rsqn2((String) output1.get("askp_rsqn2")); - dto.setAskp_rsqn2((String) output1.get("askp_rsqn3")); - dto.setAskp_rsqn2((String) output1.get("askp_rsqn4")); - dto.setAskp_rsqn2((String) output1.get("askp_rsqn5")); + dto.setAskp_rsqn3((String) output1.get("askp_rsqn3")); + dto.setAskp_rsqn4((String) output1.get("askp_rsqn4")); + dto.setAskp_rsqn5((String) output1.get("askp_rsqn5")); dto.setBidp_rsqn1((String) output1.get("bidp_rsqn1")); dto.setBidp_rsqn2((String) output1.get("bidp_rsqn2")); - dto.setBidp_rsqn1((String) output1.get("bidp_rsqn3")); - dto.setBidp_rsqn1((String) output1.get("bidp_rsqn4")); - dto.setBidp_rsqn1((String) output1.get("bidp_rsqn5")); + dto.setBidp_rsqn3((String) output1.get("bidp_rsqn3")); + dto.setBidp_rsqn4((String) output1.get("bidp_rsqn4")); + dto.setBidp_rsqn5((String) output1.get("bidp_rsqn5")); - - dto.setAspr_acpt_hour((String) output2.get("aspr_acpt_hour")); dto.setStck_prpr((String) output2.get("stck_prpr")); dto.setStck_oprc((String) output2.get("stck_oprc")); dto.setStck_hgpr((String) output2.get("stck_hgpr")); diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java index a6b7edd8..176b4ac3 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java @@ -7,13 +7,12 @@ @Data @NoArgsConstructor -@AllArgsConstructor public class StockasbiDataDto { private String askp1, askp2, askp3, askp4, askp5; private String bidp1, bidp2, bidp3, bidp4, bidp5; private String askp_rsqn1, askp_rsqn2, askp_rsqn3, askp_rsqn4, askp_rsqn5; private String bidp_rsqn1, bidp_rsqn2, bidp_rsqn3, bidp_rsqn4, bidp_rsqn5; - private String aspr_acpt_hour; + private String stck_prpr; private String stck_oprc; private String stck_hgpr; diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockminConverter.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockminConverter.java new file mode 100644 index 00000000..541331ee --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockminConverter.java @@ -0,0 +1,31 @@ +package com.stockholm.main_project.stock.stockdata.dto; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class StockminConverter { + public List convertToStockminDtos(Map apiResponse) { + List dtos = new ArrayList<>(); + + Map output1 = (Map) apiResponse.get("output1"); + List> output2List = (List>) apiResponse.get("output2"); + + for (Map output2 : output2List) { + StockminDto dto = new StockminDto(); + + dto.setHtsKorIsnm((String) output1.get("hts_kor_isnm")); + dto.setStckPrdyClpr((String) output1.get("stck_prdy_clpr")); + dto.setAcmlVol((String) output1.get("acml_vol")); + dto.setStckPrpr((String) output1.get("stck_prpr")); + + dto.setStckPrpr((String) output2.get("stck_prpr")); + dto.setStckOprc((String) output2.get("stck_oprc")); + dto.setStckHgpr((String) output2.get("stck_hgpr")); + dto.setStckLwpr((String) output2.get("stck_lwpr")); + + dtos.add(dto); + } + return dtos; + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockminDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockminDto.java new file mode 100644 index 00000000..34dc27bf --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockminDto.java @@ -0,0 +1,16 @@ +package com.stockholm.main_project.stock.stockdata.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class StockminDto { + private String htsKorIsnm; // HTS 한글 종목명 + private String stckPrdyClpr; // 주식 전일 종가 + private String acmlVol; // 누적 거래량 + private String stckPrpr; // 주식 현재가 + private String stckOprc; // 주식 시가2 + private String stckHgpr; // 주식 최고가 + private String stckLwpr; // 주식 최저가 +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java index 9fe81463..c388ec85 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java @@ -3,6 +3,8 @@ import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataConverter; import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataDto; +import com.stockholm.main_project.stock.stockdata.dto.StockminConverter; +import com.stockholm.main_project.stock.stockdata.dto.StockminDto; import org.springframework.stereotype.Service; import org.springframework.http.*; import org.springframework.web.client.RestTemplate; @@ -13,18 +15,23 @@ @Service public class StockService { private final StockasbiDataConverter converter = new StockasbiDataConverter(); + private final StockminConverter stockminConverter = new StockminConverter(); private final String APP_KEY = "PSjMh9iyz0EFvbpWkvuYHfLiFuHyNAtLoG9h"; private final String APP_SECRET = "vtzv7bG78qgtThPEujr1MWDJHKTawSoEDRfAJzB/lYvwj67HdzUsyUavVGD4kORIeGS5q6BJBwoICXy97h8d3RaSAvhK03Yu/seFm0t+22ZQBv4GKhxvU5jGwdMrsucyKuQ0EtXfkJxJoLFsqIO1UA1n3r4HX0D5RxIe8I8efwEYVbidAn4="; private final String TOKEN_URL = "https://openapi.koreainvestment.com:9443/oauth2/tokenP"; private final String STOCKASBI_URL = "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-asking-price-exp-ccn"; - private final String STOCKHOUR_URL = "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-time-itemconclusion"; - private final String START_TIME = "155000"; + private final String STOCKHOUR_URL = "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-time-itemchartprice"; + private final String FID_ETC_CLS_CODE = ""; + private final String FID_COND_MRKT_DIV_CODE = "J"; + private final String FID_INPUT_HOUR_1 = "123000"; + private final String FID_PW_DATA_INCU_YN = "Y"; + private final List DEFAULT_STOCK_CODES = Arrays.asList( - "005930", "373220", "000660", "207940", "005490" -// "005935", "006400" -// "051910" -// "005380", "003670" + "005930", "373220", "000660", "207940", "005490", + "005935", "006400" + //, "051910" +// , "005380", "003670" // "035420", "000270", "012330", "035720", "068270" ); @@ -68,8 +75,8 @@ public List getStockasbiData() { } return stockDatas; } - public List getStockhourData() { - List stockDatas = new ArrayList<>(); + public List getStockminData() { + List stockDatas = new ArrayList<>(); for (String stockCode : DEFAULT_STOCK_CODES) { String token = getAccessToken(); @@ -77,17 +84,18 @@ public List getStockhourData() { headers.add("Authorization", "Bearer " + token); headers.add("appkey", APP_KEY); headers.add("appsecret", APP_SECRET); - headers.add("tr_id", "FHPST01060000"); + headers.add("tr_id", "FHKST03010200"); + + String uri = STOCKHOUR_URL + "?FID_COND_MRKT_DIV_CODE=" + FID_COND_MRKT_DIV_CODE + "&FID_INPUT_ISCD=" + stockCode + "&FID_ETC_CLS_CODE=" + FID_ETC_CLS_CODE + + "&FID_INPUT_HOUR_1=" + FID_INPUT_HOUR_1 + "&FID_PW_DATA_INCU_YN=" + FID_PW_DATA_INCU_YN; - String uri = STOCKHOUR_URL - + "?FID_COND_MRKT_DIV_CODE=J&FID_INPUT_ISCD=" + stockCode - + "&FID_INPUT_HOUR_1=" + START_TIME; HttpEntity entity = new HttpEntity<>("parameters", headers); - ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class); + ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, Map.class); + List dtos = stockminConverter.convertToStockminDtos(response.getBody()); - stockDatas.add(response.getBody()); + stockDatas.addAll(dtos); } return stockDatas; } From 4cfcbe9c18044d3798e96579900ea73a3e800154 Mon Sep 17 00:00:00 2001 From: JaeYong Date: Tue, 29 Aug 2023 20:40:21 +0900 Subject: [PATCH 05/83] =?UTF-8?q?[Feat]=20=EB=B0=B1=EC=97=94=EB=93=9C=20?= =?UTF-8?q?=EC=84=9C=EB=B2=84=20CI=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -Dockerfile 생성 -main.yml 파일 생성 Issues #8 --- .../.github/workflows/main.yml | 26 +++++++++++++++++++ server/008main_project/Dockerfile | 11 ++++++++ 2 files changed, 37 insertions(+) create mode 100644 server/008main_project/.github/workflows/main.yml create mode 100644 server/008main_project/Dockerfile diff --git a/server/008main_project/.github/workflows/main.yml b/server/008main_project/.github/workflows/main.yml new file mode 100644 index 00000000..2e4033f8 --- /dev/null +++ b/server/008main_project/.github/workflows/main.yml @@ -0,0 +1,26 @@ +name: Java CI with Gradle + +on: + pull_request: + branches: [ dev-server, main ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'zulu' + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with Gradle + run: ./gradlew build + - name: Docker build + run: | + docker login -u ${{ secrets.DOCKER_HUB_USERNAME }} -p ${{ secrets.DOCKER_HUB_PASSWORD }} + docker buildx build --push --platform linux/amd64,linux/arm64 -t ${{ secrets.DOCKER_HUB_USERNAME }}/stockholm:${GITHUB_SHA::7} . diff --git a/server/008main_project/Dockerfile b/server/008main_project/Dockerfile new file mode 100644 index 00000000..28d757b7 --- /dev/null +++ b/server/008main_project/Dockerfile @@ -0,0 +1,11 @@ +# (1) base-image +FROM openjdk:11 + +# (2) COPY에서 사용될 경로 변수 +ARG JAR_FILE=build/libs/*-SNAPSHOT.jar + +# (3) jar 빌드 파일을 도커 컨테이너로 복사 +COPY ${JAR_FILE} app.jar + +# (4) jar 파일 실행 +ENTRYPOINT ["java","-jar","/app.jar"] \ No newline at end of file From f5d717658e2825ecbe921d87b33c1f2e5c37c825 Mon Sep 17 00:00:00 2001 From: JaeYong Date: Tue, 29 Aug 2023 20:53:39 +0900 Subject: [PATCH 06/83] =?UTF-8?q?[Fix]=20=EB=B0=B1=EC=97=94=EB=93=9C=20?= =?UTF-8?q?=EC=84=9C=EB=B2=84=20CI=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -build.gradle 설정 추가 Issues #8 --- server/008main_project/build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/008main_project/build.gradle b/server/008main_project/build.gradle index c3d93d6d..0ff737ff 100644 --- a/server/008main_project/build.gradle +++ b/server/008main_project/build.gradle @@ -38,3 +38,7 @@ dependencies { tasks.named('test') { useJUnitPlatform() } + +jar { + enabled = false +} From cbdba623bff0e547bc2ed61a5a0c2f64d4a06f0e Mon Sep 17 00:00:00 2001 From: JaeYong Date: Tue, 29 Aug 2023 20:53:39 +0900 Subject: [PATCH 07/83] =?UTF-8?q?[Fix]=20=EB=B0=B1=EC=97=94=EB=93=9C=20?= =?UTF-8?q?=EC=84=9C=EB=B2=84=20CI=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -build.gradle 설정 추가 -main 브랜치 제거 Issues #8 --- server/008main_project/.github/workflows/main.yml | 2 +- server/008main_project/build.gradle | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/server/008main_project/.github/workflows/main.yml b/server/008main_project/.github/workflows/main.yml index 2e4033f8..174154de 100644 --- a/server/008main_project/.github/workflows/main.yml +++ b/server/008main_project/.github/workflows/main.yml @@ -2,7 +2,7 @@ name: Java CI with Gradle on: pull_request: - branches: [ dev-server, main ] + branches: [ dev-server ] jobs: build: diff --git a/server/008main_project/build.gradle b/server/008main_project/build.gradle index c3d93d6d..0ff737ff 100644 --- a/server/008main_project/build.gradle +++ b/server/008main_project/build.gradle @@ -38,3 +38,7 @@ dependencies { tasks.named('test') { useJUnitPlatform() } + +jar { + enabled = false +} From 8726a9dc24a8ee9c808677a17fb4906769a6b42a Mon Sep 17 00:00:00 2001 From: rkddnr Date: Wed, 30 Aug 2023 10:18:24 +0900 Subject: [PATCH 08/83] =?UTF-8?q?Feat:=20=EC=9E=90=EC=B2=B4=20=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=20=EA=B0=80=EC=9E=85,=EB=A1=9C=EA=B7=B8=EC=9D=B8,=20J?= =?UTF-8?q?wt=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issues #4 --- .idea/.gitignore | 3 + .idea/compiler.xml | 15 +++ .idea/gradle.xml | 16 +++ .idea/jarRepositories.xml | 20 +++ .idea/misc.xml | 7 + .idea/modules.xml | 9 ++ .idea/modules/008main_project.main.iml | 8 ++ .idea/seb45_main_008.iml | 9 ++ .idea/uiDesigner.xml | 124 ++++++++++++++++++ .idea/vcs.xml | 6 + server/008main_project/build.gradle | 9 ++ .../auth/erroesponse/ErrorResponse.java | 21 +++ .../auth/filter/JwtAuthenticationFilter.java | 85 ++++++++++++ .../auth/filter/JwtVerificationFilter.java | 58 ++++++++ .../MemberAuthenticationFailureHandler.java | 37 ++++++ .../MemberAuthenticationSuccessHandler.java | 30 +++++ .../main_project/auth/jwt/JwtTokenizer.java | 101 ++++++++++++++ .../main_project/auth/logindto/LoginDto.java | 10 ++ .../memberdetail/MemberDetailsService.java | 71 ++++++++++ .../auth/utils/CustomAuthorityUtils.java | 28 ++++ .../config/SecurityConfiguration.java | 92 +++++++++++++ .../member/controller/MemberController.java | 58 ++++++++ .../member/dto/MemberPatchDto.java | 13 ++ .../member/dto/MemberPostDto.java | 15 +++ .../member/dto/MemberResponseDto.java | 15 +++ .../main_project/member/entity/Member.java | 9 +- .../member/mapper/MemberMapper.java | 20 +++ .../member/repository/MemberRepository.java | 11 ++ .../member/service/MemberService.java | 66 ++++++++++ .../src/main/resources/application.yml | 7 +- 30 files changed, 966 insertions(+), 7 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/modules/008main_project.main.iml create mode 100644 .idea/seb45_main_008.iml create mode 100644 .idea/uiDesigner.xml create mode 100644 .idea/vcs.xml create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/erroesponse/ErrorResponse.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtAuthenticationFilter.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtVerificationFilter.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/handler/MemberAuthenticationFailureHandler.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/handler/MemberAuthenticationSuccessHandler.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/JwtTokenizer.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/logindto/LoginDto.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/memberdetail/MemberDetailsService.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/utils/CustomAuthorityUtils.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/config/SecurityConfiguration.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/member/controller/MemberController.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/member/dto/MemberPatchDto.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/member/dto/MemberPostDto.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/member/dto/MemberResponseDto.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/member/mapper/MemberMapper.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/member/repository/MemberRepository.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/member/service/MemberService.java diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..26d33521 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 00000000..ab2110df --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 00000000..2a89c9f4 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 00000000..fdc392fe --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..acea2b35 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..94f9a64b --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/008main_project.main.iml b/.idea/modules/008main_project.main.iml new file mode 100644 index 00000000..5e995830 --- /dev/null +++ b/.idea/modules/008main_project.main.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/seb45_main_008.iml b/.idea/seb45_main_008.iml new file mode 100644 index 00000000..d6ebd480 --- /dev/null +++ b/.idea/seb45_main_008.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 00000000..2b63946d --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/server/008main_project/build.gradle b/server/008main_project/build.gradle index c3d93d6d..44916b0a 100644 --- a/server/008main_project/build.gradle +++ b/server/008main_project/build.gradle @@ -33,6 +33,15 @@ dependencies { runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' + // security 작업을 위한 의존성 + implementation 'com.google.code.gson:gson:2.8.8' // gson 의존성 추가 + implementation 'org.springframework.boot:spring-boot-starter-security' + testImplementation 'org.springframework.security:spring-security-test' +// implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' } tasks.named('test') { diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/erroesponse/ErrorResponse.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/erroesponse/ErrorResponse.java new file mode 100644 index 00000000..66a0fc99 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/erroesponse/ErrorResponse.java @@ -0,0 +1,21 @@ +package com.stockholm.main_project.auth.erroesponse; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.http.HttpStatus; + +@Getter +@Setter +public class ErrorResponse { + private int status; + private String error; + private String message; + + public static ErrorResponse of(HttpStatus httpStatus) { + ErrorResponse errorResponse = new ErrorResponse(); + errorResponse.setStatus(httpStatus.value()); + errorResponse.setError(httpStatus.getReasonPhrase()); + errorResponse.setMessage("Authentication failed"); + return errorResponse; + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtAuthenticationFilter.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtAuthenticationFilter.java new file mode 100644 index 00000000..0b637778 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtAuthenticationFilter.java @@ -0,0 +1,85 @@ +package com.stockholm.main_project.auth.filter; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.stockholm.main_project.auth.jwt.JwtTokenizer; +import com.stockholm.main_project.auth.logindto.LoginDto; +import com.stockholm.main_project.member.entity.Member; +import lombok.SneakyThrows; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { + private final AuthenticationManager authenticationManager; + private final JwtTokenizer jwtTokenizer; + + public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtTokenizer jwtTokenizer) { + this.authenticationManager = authenticationManager; + this.jwtTokenizer = jwtTokenizer; + } + + @SneakyThrows + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) { + ObjectMapper objectMapper = new ObjectMapper(); + LoginDto loginDto = objectMapper.readValue(request.getInputStream(), LoginDto.class); + UsernamePasswordAuthenticationToken authenticationToken = + new UsernamePasswordAuthenticationToken(loginDto.getEmail(), loginDto.getPassword()); + + return authenticationManager.authenticate(authenticationToken); + } + + @Override + protected void successfulAuthentication(HttpServletRequest request, + HttpServletResponse response, + FilterChain chain, + Authentication authResult) throws ServletException, IOException { + Member member = (Member) authResult.getPrincipal(); + + String accessToken = delegateAccessToken(member); + String refreshToken = delegateRefreshToken(member); + + response.setHeader("Authorization", "Bearer " + accessToken); + response.setHeader("Refresh", refreshToken); + //response.setHeader("Access-Control-Expose-Headers", "Authorization"); + //response.addHeader("Access-Control-Expose-Headers", "MemberId"); + + this.getSuccessHandler().onAuthenticationSuccess(request, response, authResult); + } + + + private String delegateAccessToken(Member member) { + Map claims = new HashMap<>(); + claims.put("memberEmail", member.getEmail()); + claims.put("roles", member.getRoles()); + + String subject = member.getEmail(); + Date expiration = jwtTokenizer.getTokenExpiration(jwtTokenizer.getAccessTokenExpirationMinutes()); + + String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); + + String accessToken = jwtTokenizer.generateAccessToken(claims, subject, expiration, base64EncodedSecretKey); + + return accessToken; + } + + private String delegateRefreshToken(Member member) { + String subject = member.getEmail(); + Date expiration = jwtTokenizer.getTokenExpiration(jwtTokenizer.getRefreshTokenExpirationMinutes()); + String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); + + String refreshToken = jwtTokenizer.generateRefreshToken(subject, expiration, base64EncodedSecretKey); + + return refreshToken; + } +} \ No newline at end of file diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtVerificationFilter.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtVerificationFilter.java new file mode 100644 index 00000000..b592cf4c --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/filter/JwtVerificationFilter.java @@ -0,0 +1,58 @@ +package com.stockholm.main_project.auth.filter; + +import com.stockholm.main_project.auth.jwt.JwtTokenizer; +import com.stockholm.main_project.auth.utils.CustomAuthorityUtils; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public class JwtVerificationFilter extends OncePerRequestFilter { + private final JwtTokenizer jwtTokenizer; + private final CustomAuthorityUtils authorityUtils; + + // (2) + public JwtVerificationFilter(JwtTokenizer jwtTokenizer, + CustomAuthorityUtils authorityUtils) { + this.jwtTokenizer = jwtTokenizer; + this.authorityUtils = authorityUtils; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + Map claims = verifyJws(request); + setAuthenticationToContext(claims); + filterChain.doFilter(request, response); + } + + @Override + protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { + String authorization = request.getHeader("Authorization"); + + return authorization == null || !authorization.startsWith("Bearer"); + } + + private Map verifyJws(HttpServletRequest request) { + String jws = request.getHeader("Authorization").replace("Bearer ", ""); + String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); + Map claims = jwtTokenizer.getClaims(jws, base64EncodedSecretKey).getBody(); + + return claims; + } + + private void setAuthenticationToContext(Map claims) { + String memberEmail = (String) claims.get("email"); + List authorities = authorityUtils.createAuthorities((List)claims.get("roles")); + Authentication authentication = new UsernamePasswordAuthenticationToken(memberEmail, null, authorities); + SecurityContextHolder.getContext().setAuthentication(authentication); + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/handler/MemberAuthenticationFailureHandler.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/handler/MemberAuthenticationFailureHandler.java new file mode 100644 index 00000000..601b8b67 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/handler/MemberAuthenticationFailureHandler.java @@ -0,0 +1,37 @@ +package com.stockholm.main_project.auth.handler; + +import com.google.gson.Gson; +import com.stockholm.main_project.auth.erroesponse.ErrorResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Slf4j +public class MemberAuthenticationFailureHandler implements AuthenticationFailureHandler { + + @Override + public void onAuthenticationFailure(HttpServletRequest request, + HttpServletResponse response, + AuthenticationException exception) throws IOException, ServletException { + log.error("# Authentication failed: {}", exception.getMessage()); + + sendErrorResponse(response); + } + + private void sendErrorResponse(HttpServletResponse response) throws IOException { + Gson gson = new Gson(); + ErrorResponse errorResponse = ErrorResponse.of(HttpStatus.UNAUTHORIZED); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + response.getWriter().write(gson.toJson(errorResponse, ErrorResponse.class)); + } +} + + diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/handler/MemberAuthenticationSuccessHandler.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/handler/MemberAuthenticationSuccessHandler.java new file mode 100644 index 00000000..71e4e9ac --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/handler/MemberAuthenticationSuccessHandler.java @@ -0,0 +1,30 @@ +package com.stockholm.main_project.auth.handler; + +import com.google.gson.Gson; +import com.stockholm.main_project.auth.erroesponse.ErrorResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Slf4j +public class MemberAuthenticationSuccessHandler implements AuthenticationSuccessHandler { + + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, + HttpServletResponse response, + Authentication authentication) throws IOException, ServletException { + + log.info("# Authenticated successfully!"); + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/JwtTokenizer.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/JwtTokenizer.java new file mode 100644 index 00000000..d9e75045 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/jwt/JwtTokenizer.java @@ -0,0 +1,101 @@ +package com.stockholm.main_project.auth.jwt; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.io.Encoders; +import io.jsonwebtoken.security.Keys; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.nio.charset.StandardCharsets; +import java.security.Key; +import java.util.Calendar; +import java.util.Date; +import java.util.Map; + + +@Component +public class JwtTokenizer { + + @Getter + @Value("abcdefgabcdefgabcdefgabcdefgabcdefg") //임시 키 + private String secretKey; + + @Getter + @Value("${jwt.access-token-expiration-minutes}") //Access Token에 대한 만료 시간 정보 + private int accessTokenExpirationMinutes; + + @Getter + @Value("${jwt.refresh-token-expiration-minutes}") //Refresh Token에 대한 만료 시간 정보 + private int refreshTokenExpirationMinutes; + + public String encodeBase64SecretKey(String secretKey){ + + return Encoders.BASE64.encode(secretKey.getBytes(StandardCharsets.UTF_8)); + } + + public String generateAccessToken(Map claims, + String subject, + Date expiration, + String base64EncodedSecretKey){ + Key key = getKeyFromBase64EncodedKey(base64EncodedSecretKey); + + return Jwts.builder() + .setClaims(claims) + .setSubject(subject) + .setIssuedAt(Calendar.getInstance().getTime()) + .setExpiration(expiration) + .signWith(key) + .compact(); + } + + public String generateRefreshToken(String subject, Date expiration, String base64EncodedSecretKey){ + Key key = getKeyFromBase64EncodedKey(base64EncodedSecretKey); + + return Jwts.builder() + .setSubject(subject) + .setIssuedAt(Calendar.getInstance().getTime()) + .setExpiration(expiration) + .signWith(key) + .compact(); + } + + public Jws getClaims(String jws, String base64EncodedSecretKey){ + Key key = getKeyFromBase64EncodedKey(base64EncodedSecretKey); + + Jws claims = Jwts.parserBuilder() + .setSigningKey(key) + .build() + .parseClaimsJws(jws); + return claims; + } + + public void verifySignature(String jws, String base64EncodedSecretKey){ + Key key = getKeyFromBase64EncodedKey(base64EncodedSecretKey); + + Jwts.parserBuilder() + .setSigningKey(key) + .build() + .parseClaimsJws(jws); + + } + + public Date getTokenExpiration(int expirationMinutes) { + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.MINUTE, expirationMinutes); + Date expiration = calendar.getTime(); + + return expiration; + } + + private Key getKeyFromBase64EncodedKey(String base64EncodedSecretKey) { + byte[] keyBytes = Decoders.BASE64.decode(base64EncodedSecretKey); + Key key = Keys.hmacShaKeyFor(keyBytes); + + return key; + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/logindto/LoginDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/logindto/LoginDto.java new file mode 100644 index 00000000..de46e8d0 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/logindto/LoginDto.java @@ -0,0 +1,10 @@ +package com.stockholm.main_project.auth.logindto; + +import lombok.Getter; + +@Getter +public class LoginDto { + private String email; + private String password; + +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/memberdetail/MemberDetailsService.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/memberdetail/MemberDetailsService.java new file mode 100644 index 00000000..8c777677 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/memberdetail/MemberDetailsService.java @@ -0,0 +1,71 @@ +package com.stockholm.main_project.auth.memberdetail; + +import com.stockholm.main_project.auth.utils.CustomAuthorityUtils; +import com.stockholm.main_project.member.entity.Member; +import com.stockholm.main_project.member.repository.MemberRepository; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Optional; + +@Component +public class MemberDetailsService implements UserDetailsService { + private final MemberRepository memberRepository; + private final CustomAuthorityUtils authorityUtils; + + public MemberDetailsService(MemberRepository memberRepository, CustomAuthorityUtils authorityUtils) { + this.memberRepository = memberRepository; + this.authorityUtils = authorityUtils; + } + + @Override + public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { + Optional optionalMember = memberRepository.findByEmail(email); + Member findMember = optionalMember.orElseThrow(() -> new UsernameNotFoundException("User not found")); + + return new MemberDetails(findMember); + } + + private final class MemberDetails extends Member implements UserDetails { + MemberDetails(Member member) { + setMemberId(member.getMemberId()); + setEmail(member.getEmail()); + setPassword(member.getPassword()); + setRoles(member.getRoles()); + } + + @Override + public Collection getAuthorities() { + return authorityUtils.createAuthorities(this.getRoles()); + } + + @Override + public String getUsername() { + return getEmail(); + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/auth/utils/CustomAuthorityUtils.java b/server/008main_project/src/main/java/com/stockholm/main_project/auth/utils/CustomAuthorityUtils.java new file mode 100644 index 00000000..542cc7bd --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/auth/utils/CustomAuthorityUtils.java @@ -0,0 +1,28 @@ +package com.stockholm.main_project.auth.utils; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +@Component +public class CustomAuthorityUtils { + + private final List USER_ROLES = AuthorityUtils.createAuthorityList("ROLE_USER"); + private final List USER_ROLES_STRING = List.of("USER"); + + public List createRoles(String email) { + + return USER_ROLES_STRING; + } + + public List createAuthorities(List roles) { + List authorities = roles.stream() + .map(role -> new SimpleGrantedAuthority("ROLE_" + role)) + .collect(Collectors.toList()); + return authorities; + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/config/SecurityConfiguration.java b/server/008main_project/src/main/java/com/stockholm/main_project/config/SecurityConfiguration.java new file mode 100644 index 00000000..d5945704 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/config/SecurityConfiguration.java @@ -0,0 +1,92 @@ +package com.stockholm.main_project.config; + +import com.stockholm.main_project.auth.filter.JwtAuthenticationFilter; +import com.stockholm.main_project.auth.filter.JwtVerificationFilter; +import com.stockholm.main_project.auth.handler.MemberAuthenticationFailureHandler; +import com.stockholm.main_project.auth.handler.MemberAuthenticationSuccessHandler; +import com.stockholm.main_project.auth.jwt.JwtTokenizer; +import com.stockholm.main_project.auth.utils.CustomAuthorityUtils; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.Arrays; + +import static org.springframework.security.config.Customizer.withDefaults; + +@Configuration +@EnableWebSecurity +public class SecurityConfiguration { + private final JwtTokenizer jwtTokenizer; + private final CustomAuthorityUtils authorityUtils; + + public SecurityConfiguration(JwtTokenizer jwtTokenizer, CustomAuthorityUtils authorityUtils) { + this.jwtTokenizer = jwtTokenizer; + this.authorityUtils = authorityUtils; + } + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception { + httpSecurity + .headers().frameOptions().sameOrigin() //H2 웹 콘솔에 정상적으로 접근 가능하도록 설정 + .and() + .csrf().disable() //CSRF 공격에 대한 설정 + .cors(withDefaults()) // CORS 설정을 추가 + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)//.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)를 통해서 세션을 생성하지 않도록 설정 + .and() + .formLogin().disable() // JSON 포맷 전달 방식 사용을 위해 비활성화 + .httpBasic().disable() // request 전송마다 로그인 정보를 받지 않을 것임으로 비활성화 + .apply(new CustomFilterConfigurer()) + .and() + .authorizeHttpRequests(authorize -> authorize + .antMatchers("members/login").permitAll() + .anyRequest().permitAll() + ); + + return httpSecurity.build(); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return PasswordEncoderFactories.createDelegatingPasswordEncoder(); + } + @Bean + CorsConfigurationSource corsConfigurationSource(){ + CorsConfiguration configuration = new CorsConfiguration(); + configuration.setAllowedOrigins(Arrays.asList("*")); + configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PATCH", "DELETE")); + configuration.setAllowCredentials(true); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", configuration); + + return source; + } + public class CustomFilterConfigurer extends AbstractHttpConfigurer { + @Override + public void configure(HttpSecurity builder) throws Exception { + AuthenticationManager authenticationManager = builder.getSharedObject(AuthenticationManager.class); + + JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager, jwtTokenizer); + jwtAuthenticationFilter.setFilterProcessesUrl("/members/login"); + jwtAuthenticationFilter.setAuthenticationSuccessHandler(new MemberAuthenticationSuccessHandler()); + jwtAuthenticationFilter.setAuthenticationFailureHandler(new MemberAuthenticationFailureHandler()); + builder.addFilter(jwtAuthenticationFilter); + + JwtVerificationFilter jwtVerificationFilter = new JwtVerificationFilter(jwtTokenizer, authorityUtils); + + builder + .addFilter(jwtAuthenticationFilter) + .addFilterAfter(jwtVerificationFilter, JwtAuthenticationFilter.class); + } + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/member/controller/MemberController.java b/server/008main_project/src/main/java/com/stockholm/main_project/member/controller/MemberController.java new file mode 100644 index 00000000..05c371c9 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/member/controller/MemberController.java @@ -0,0 +1,58 @@ +package com.stockholm.main_project.member.controller; + +import com.stockholm.main_project.member.dto.MemberPatchDto; +import com.stockholm.main_project.member.dto.MemberPostDto; +import com.stockholm.main_project.member.entity.Member; +import com.stockholm.main_project.member.mapper.MemberMapper; +import com.stockholm.main_project.member.repository.MemberRepository; +import com.stockholm.main_project.member.service.MemberService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/members") +public class MemberController { + private final MemberService memberService; + private final MemberMapper mapper; + + + public MemberController(MemberService memberService, MemberMapper mapper) { + this.memberService = memberService; + this.mapper = mapper; + } + + @PostMapping + public ResponseEntity postUser(@RequestBody MemberPostDto memberPostDto){ + Member member = mapper.memberPostToMember(memberPostDto); + + Member response = memberService.createMember(member); + + return new ResponseEntity<>(mapper.memberToMemberResponseDto(response), + HttpStatus.CREATED); + } + + @PatchMapping("{userId}") + private ResponseEntity patchUser(@PathVariable long memberId, @RequestBody MemberPatchDto memberPatchDto){ + memberPatchDto.setMemberId(memberId); + + Member response = memberService.updateMember(mapper.memberPatchToMember(memberPatchDto)); + + return new ResponseEntity<>(mapper.memberToMemberResponseDto(response), + HttpStatus.OK); + } + + @GetMapping("{userId}") + private ResponseEntity getUser(@PathVariable long memberId){ + Member response = memberService.findMember(memberId); + + return new ResponseEntity<>(mapper.memberToMemberResponseDto(response), HttpStatus.OK); + } + + @DeleteMapping("{userId}") + private ResponseEntity deleteUser(@PathVariable long memberId){ + memberService.deleteMember(memberId); + + return new ResponseEntity(HttpStatus.NO_CONTENT); + } +} \ No newline at end of file diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/member/dto/MemberPatchDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/member/dto/MemberPatchDto.java new file mode 100644 index 00000000..231b1d06 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/member/dto/MemberPatchDto.java @@ -0,0 +1,13 @@ +package com.stockholm.main_project.member.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class MemberPatchDto { + private long memberId; + private String email; + private String name; + +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/member/dto/MemberPostDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/member/dto/MemberPostDto.java new file mode 100644 index 00000000..ccc6a3ce --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/member/dto/MemberPostDto.java @@ -0,0 +1,15 @@ +package com.stockholm.main_project.member.dto; + +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotNull; + +@Getter +@Setter +public class MemberPostDto { + private String email; + private String name; + private String password; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/member/dto/MemberResponseDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/member/dto/MemberResponseDto.java new file mode 100644 index 00000000..38e48d45 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/member/dto/MemberResponseDto.java @@ -0,0 +1,15 @@ +package com.stockholm.main_project.member.dto; + +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Getter +@Setter +public class MemberResponseDto { + public long memberId; + public String email; + private String name; + private LocalDateTime createdAt; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Member.java b/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Member.java index 1a51ebb6..2d318bc1 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Member.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/member/entity/Member.java @@ -9,22 +9,21 @@ import java.util.ArrayList; import java.util.List; -@Entity +@Entity(name = "members") @Getter @Setter -@NoArgsConstructor public class Member extends Auditable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long memberId; - @Column + @Column(length = 30, nullable = false) private String email; - @Column + @Column(length = 10, nullable = false) private String name; - @Column + @Column(length = 255, nullable = false) private String password; @Enumerated(value = EnumType.STRING) diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/member/mapper/MemberMapper.java b/server/008main_project/src/main/java/com/stockholm/main_project/member/mapper/MemberMapper.java new file mode 100644 index 00000000..4644056b --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/member/mapper/MemberMapper.java @@ -0,0 +1,20 @@ +package com.stockholm.main_project.member.mapper; + +import com.stockholm.main_project.member.dto.MemberPatchDto; +import com.stockholm.main_project.member.dto.MemberPostDto; +import com.stockholm.main_project.member.dto.MemberResponseDto; +import com.stockholm.main_project.member.entity.Member; +import com.stockholm.main_project.member.repository.MemberRepository; +import org.mapstruct.Mapper; + +@Mapper(componentModel = "spring") +public interface MemberMapper { + + Member memberPostToMember(MemberPostDto requestBody); + + Member memberPatchToMember(MemberPatchDto requestBody); + + MemberResponseDto memberToMemberResponseDto(Member member); + + +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/member/repository/MemberRepository.java b/server/008main_project/src/main/java/com/stockholm/main_project/member/repository/MemberRepository.java new file mode 100644 index 00000000..64679bbd --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/member/repository/MemberRepository.java @@ -0,0 +1,11 @@ +package com.stockholm.main_project.member.repository; + +import com.stockholm.main_project.member.entity.Member; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface MemberRepository extends JpaRepository { + + Optional findByEmail(String email); +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/member/service/MemberService.java b/server/008main_project/src/main/java/com/stockholm/main_project/member/service/MemberService.java new file mode 100644 index 00000000..965b1ba2 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/member/service/MemberService.java @@ -0,0 +1,66 @@ +package com.stockholm.main_project.member.service; + +import com.stockholm.main_project.auth.utils.CustomAuthorityUtils; +import com.stockholm.main_project.member.entity.Member; +import com.stockholm.main_project.member.repository.MemberRepository; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class MemberService { + + private final MemberRepository memberRepository; + private final PasswordEncoder passwordEncoder; + private final CustomAuthorityUtils authorityUtils; + + public MemberService(MemberRepository memberRepository, PasswordEncoder passwordEncoder, CustomAuthorityUtils authorityUtils) { + this.memberRepository = memberRepository; + this.passwordEncoder = passwordEncoder; + this.authorityUtils = authorityUtils; + } + + public Member createMember(Member member) { + String encryptedPassword = passwordEncoder.encode(member.getPassword()); + member.setPassword(encryptedPassword); + + List roles = authorityUtils.createRoles(member.getEmail()); + member.setRoles(roles); + + member.setMemberStatus(Member.MemberStatus.MEMBER_ACTIVE); + Member saveMember = memberRepository.save(member); + System.out.println("# Create Member in DB"); + + return saveMember; + } + + public Member updateMember(Member member) { + Optional optionalMember = memberRepository.findById(member.getMemberId()); + + if (optionalMember.isPresent()) { + Member foundMember = optionalMember.get(); + + if (member.getName() != null) { + foundMember.setName(member.getName()); + } + memberRepository.save(foundMember); + + return foundMember; + } + + return null; + } + + public Member findMember(long memberId) { + + return memberRepository.findById(memberId).orElse(null); + } + + public void deleteMember(long memberId) { + + memberRepository.deleteById(memberId); + } +} + diff --git a/server/008main_project/src/main/resources/application.yml b/server/008main_project/src/main/resources/application.yml index c5ede541..b8ee4aad 100644 --- a/server/008main_project/src/main/resources/application.yml +++ b/server/008main_project/src/main/resources/application.yml @@ -11,7 +11,6 @@ spring: hibernate: ddl-auto: create-drop show-sql: true - springdoc: swagger-ui: path: /swagger-ui.html @@ -25,4 +24,8 @@ springdoc: default-consumes-media-type: application/json default-produces-media-type: application/json paths-to-match: - - /stockholm/** \ No newline at end of file + - /stockholm/** +jwt: + #key: ${JWT_SECRET_KEY} + access-token-expiration-minutes: 40 + refresh-token-expiration-minutes: 420 \ No newline at end of file From c852cf30244917dae121bcff79d9ffe2415ae96c Mon Sep 17 00:00:00 2001 From: JaeYong Date: Wed, 30 Aug 2023 10:44:40 +0900 Subject: [PATCH 09/83] =?UTF-8?q?[Feat]=20api=20=ED=8C=8C=EC=8B=B1=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84,=20Scheduler=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -StockScheduler.java 구현 -Dto 파일 생성 Issues #5 --- .../stockholm/main_project/Application.java | 2 + .../scheduler/StockScheduler.java | 124 ++++++++++++++++++ .../stockdata/controller/StockController.java | 12 +- .../stock/stockdata/dto/StockAsBiOutput1.java | 38 ++++++ .../stock/stockdata/dto/StockAsBiOutput2.java | 16 +++ .../stock/stockdata/dto/StockMinDto.java | 13 ++ .../stock/stockdata/dto/StockMinOutput1.java | 13 ++ .../stock/stockdata/dto/StockMinOutput2.java | 16 +++ .../stockdata/dto/StockasbiDataConverter.java | 96 +++++++------- .../stock/stockdata/dto/StockasbiDataDto.java | 15 +-- .../stock/stockdata/service/StockService.java | 62 ++++++--- 11 files changed, 319 insertions(+), 88 deletions(-) create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/scheduler/StockScheduler.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput1.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput2.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinDto.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput1.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput2.java diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/Application.java b/server/008main_project/src/main/java/com/stockholm/main_project/Application.java index d20b44ab..1ed435c3 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/Application.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/Application.java @@ -3,7 +3,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.scheduling.annotation.EnableScheduling; +@EnableScheduling @EnableJpaAuditing @SpringBootApplication public class Application { diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/scheduler/StockScheduler.java b/server/008main_project/src/main/java/com/stockholm/main_project/scheduler/StockScheduler.java new file mode 100644 index 00000000..28dec214 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/scheduler/StockScheduler.java @@ -0,0 +1,124 @@ +//package com.stockholm.main_project.scheduler; +// +//import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataDto; +//import com.stockholm.main_project.stock.stockdata.service.StockService; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.scheduling.annotation.Scheduled; +//import org.springframework.stereotype.Service; +// +//import java.util.List; +// +//@Slf4j +//@Service +//public class StockScheduler { +// private StockService stockService; +// +// public StockScheduler(StockService stockService) { +// this.stockService = stockService; +// } +// +// @Scheduled(fixedRate = 60000) +// public void run() { +// List stockasbiDataDtos = stockService.getStockasbiData(); +// +// System.out.println("run1"); +// +// for(StockasbiDataDto stockasbiDataDto : stockasbiDataDtos) { +// log.info(stockasbiDataDto.getOutput1().getAskp1()); +// log.info(stockasbiDataDto.getOutput1().getAskp2()); +// log.info(stockasbiDataDto.getOutput1().getAskp3()); +// log.info(stockasbiDataDto.getOutput1().getAskp4()); +// log.info(stockasbiDataDto.getOutput1().getAskp5()); +// } +// } +// +// @Scheduled(fixedRate = 60000, initialDelay = 1000) +// public void run2() { +// List stockasbiDataDtos = stockService.getStockasbiData(); +// +// System.out.println("run2"); +// +// for(StockasbiDataDto stockasbiDataDto : stockasbiDataDtos) { +// log.info(stockasbiDataDto.getOutput1().getAskp1()); +// log.info(stockasbiDataDto.getOutput1().getAskp2()); +// log.info(stockasbiDataDto.getOutput1().getAskp3()); +// log.info(stockasbiDataDto.getOutput1().getAskp4()); +// log.info(stockasbiDataDto.getOutput1().getAskp5()); +// } +// } +// +// @Scheduled(fixedRate = 60000, initialDelay = 2000) +// public void run3() { +// List stockasbiDataDtos = stockService.getStockasbiData(); +// +// System.out.println("run3"); +// +// for(StockasbiDataDto stockasbiDataDto : stockasbiDataDtos) { +// log.info(stockasbiDataDto.getOutput1().getAskp1()); +// log.info(stockasbiDataDto.getOutput1().getAskp2()); +// log.info(stockasbiDataDto.getOutput1().getAskp3()); +// log.info(stockasbiDataDto.getOutput1().getAskp4()); +// log.info(stockasbiDataDto.getOutput1().getAskp5()); +// } +// } +// +// @Scheduled(fixedRate = 60000, initialDelay = 3000) +// public void run4() { +// List stockasbiDataDtos = stockService.getStockasbiData(); +// +// System.out.println("run4"); +// +// for(StockasbiDataDto stockasbiDataDto : stockasbiDataDtos) { +// log.info(stockasbiDataDto.getOutput1().getAskp1()); +// log.info(stockasbiDataDto.getOutput1().getAskp2()); +// log.info(stockasbiDataDto.getOutput1().getAskp3()); +// log.info(stockasbiDataDto.getOutput1().getAskp4()); +// log.info(stockasbiDataDto.getOutput1().getAskp5()); +// } +// } +// +// @Scheduled(fixedRate = 60000, initialDelay = 4000) +// public void run5() { +// List stockasbiDataDtos = stockService.getStockasbiData(); +// +// System.out.println("run5"); +// +// for(StockasbiDataDto stockasbiDataDto : stockasbiDataDtos) { +// log.info(stockasbiDataDto.getOutput1().getAskp1()); +// log.info(stockasbiDataDto.getOutput1().getAskp2()); +// log.info(stockasbiDataDto.getOutput1().getAskp3()); +// log.info(stockasbiDataDto.getOutput1().getAskp4()); +// log.info(stockasbiDataDto.getOutput1().getAskp5()); +// } +// } +// +// @Scheduled(fixedRate = 60000, initialDelay = 5000) +// public void run6() { +// List stockasbiDataDtos = stockService.getStockasbiData(); +// +// System.out.println("run6"); +// +// for(StockasbiDataDto stockasbiDataDto : stockasbiDataDtos) { +// log.info(stockasbiDataDto.getOutput1().getAskp1()); +// log.info(stockasbiDataDto.getOutput1().getAskp2()); +// log.info(stockasbiDataDto.getOutput1().getAskp3()); +// log.info(stockasbiDataDto.getOutput1().getAskp4()); +// log.info(stockasbiDataDto.getOutput1().getAskp5()); +// } +// } +// +// @Scheduled(fixedRate = 60000, initialDelay = 6000) +// public void run7() { +// List stockasbiDataDtos = stockService.getStockasbiData(); +// +// System.out.println("run7"); +// +// for(StockasbiDataDto stockasbiDataDto : stockasbiDataDtos) { +// log.info(stockasbiDataDto.getOutput1().getAskp1()); +// log.info(stockasbiDataDto.getOutput1().getAskp2()); +// log.info(stockasbiDataDto.getOutput1().getAskp3()); +// log.info(stockasbiDataDto.getOutput1().getAskp4()); +// log.info(stockasbiDataDto.getOutput1().getAskp5()); +// } +// } +//} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java index 0f4f6442..b2b7b919 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java @@ -2,16 +2,14 @@ import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataDto; +import com.stockholm.main_project.stock.stockdata.dto.StockMinDto; import com.stockholm.main_project.stock.stockdata.service.StockService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import java.util.List; -import java.util.Map; @Controller public class StockController { @@ -22,14 +20,14 @@ public class StockController { @ResponseBody @GetMapping("/stockasbi") - public ResponseEntity> getStockasbiData() { + public ResponseEntity getStockasbiData() { List stockDatas = stockService.getStockasbiData(); return ResponseEntity.ok(stockDatas); } @ResponseBody - @GetMapping("/stockhour") - public ResponseEntity> getStockhourData() { - List stockDatas = stockService.getStockhourData(); + @GetMapping("/stockmin") + public ResponseEntity getStockMinData() { + List stockDatas = stockService.getStockMinData(); return ResponseEntity.ok(stockDatas); } } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput1.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput1.java new file mode 100644 index 00000000..fd64078c --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput1.java @@ -0,0 +1,38 @@ +package com.stockholm.main_project.stock.stockdata.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class StockAsBiOutput1 { + + private String aspr_acpt_hour; + + private String askp1; + private String askp2; + private String askp3; + private String askp4; + private String askp5; + + private String askp_rsqn1; + private String askp_rsqn2; + private String askp_rsqn3; + private String askp_rsqn4; + private String askp_rsqn5; + + private String bidp1; + private String bidp2; + private String bidp3; + private String bidp4; + private String bidp5; + + private String bidp_rsqn1; + private String bidp_rsqn2; + private String bidp_rsqn3; + private String bidp_rsqn4; + private String bidp_rsqn5; + +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput2.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput2.java new file mode 100644 index 00000000..fe3c8f18 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput2.java @@ -0,0 +1,16 @@ +package com.stockholm.main_project.stock.stockdata.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class StockAsBiOutput2 { + private String stck_prpr; + private String stck_oprc; + private String stck_hgpr; + private String stck_lwpr; + private String stck_sdpr; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinDto.java new file mode 100644 index 00000000..d2a53208 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinDto.java @@ -0,0 +1,13 @@ +package com.stockholm.main_project.stock.stockdata.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class StockMinDto { + private StockMinOutput1 output1; + private StockMinOutput2[] output2; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput1.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput1.java new file mode 100644 index 00000000..92e99657 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput1.java @@ -0,0 +1,13 @@ +package com.stockholm.main_project.stock.stockdata.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class StockMinOutput1 { + private String hts_kor_isnm; + private String stck_prpr; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput2.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput2.java new file mode 100644 index 00000000..99143dcc --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput2.java @@ -0,0 +1,16 @@ +package com.stockholm.main_project.stock.stockdata.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class StockMinOutput2 { + private String stck_cntg_hour; + private String stck_prpr; + private String stck_oprc; + private String stck_hgpr; + private String stck_lwpr; +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java index 4eacbeba..842dc09b 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java @@ -1,48 +1,48 @@ -package com.stockholm.main_project.stock.stockdata.dto; - -import java.util.Map; - -public class StockasbiDataConverter { - public StockasbiDataDto convertToStockasbiDataDto(Map apiResponse) { - StockasbiDataDto dto = new StockasbiDataDto(); - - Map output1 = (Map) apiResponse.get("output1"); - Map output2 = (Map) apiResponse.get("output2"); - - dto.setAskp1((String) output1.get("askp1")); - dto.setAskp2((String) output1.get("askp2")); - dto.setAskp1((String) output1.get("askp3")); - dto.setAskp1((String) output1.get("askp4")); - dto.setAskp1((String) output1.get("askp5")); - - dto.setBidp1((String) output1.get("bidp1")); - dto.setBidp2((String) output1.get("bidp2")); - dto.setBidp1((String) output1.get("bidp3")); - dto.setBidp1((String) output1.get("bidp4")); - dto.setBidp1((String) output1.get("bidp5")); - - - dto.setAskp_rsqn1((String) output1.get("askp_rsqn1")); - dto.setAskp_rsqn2((String) output1.get("askp_rsqn2")); - dto.setAskp_rsqn2((String) output1.get("askp_rsqn3")); - dto.setAskp_rsqn2((String) output1.get("askp_rsqn4")); - dto.setAskp_rsqn2((String) output1.get("askp_rsqn5")); - - dto.setBidp_rsqn1((String) output1.get("bidp_rsqn1")); - dto.setBidp_rsqn2((String) output1.get("bidp_rsqn2")); - dto.setBidp_rsqn1((String) output1.get("bidp_rsqn3")); - dto.setBidp_rsqn1((String) output1.get("bidp_rsqn4")); - dto.setBidp_rsqn1((String) output1.get("bidp_rsqn5")); - - - - dto.setAspr_acpt_hour((String) output2.get("aspr_acpt_hour")); - dto.setStck_prpr((String) output2.get("stck_prpr")); - dto.setStck_oprc((String) output2.get("stck_oprc")); - dto.setStck_hgpr((String) output2.get("stck_hgpr")); - dto.setStck_lwpr((String) output2.get("stck_lwpr")); - dto.setStck_sdpr((String) output2.get("stck_sdpr")); - - return dto; - } -} +//package com.stockholm.main_project.stock.stockdata.dto; +// +//import java.util.Map; +// +//public class StockasbiDataConverter { +// public StockasbiDataDto convertToStockasbiDataDto(Map apiResponse) { +// StockasbiDataDto dto = new StockasbiDataDto(); +// +// Map output1 = (Map) apiResponse.get("output1"); +// Map output2 = (Map) apiResponse.get("output2"); +// +// dto.setAskp1((String) output1.get("askp1")); +// dto.setAskp2((String) output1.get("askp2")); +// dto.setAskp1((String) output1.get("askp3")); +// dto.setAskp1((String) output1.get("askp4")); +// dto.setAskp1((String) output1.get("askp5")); +// +// dto.setBidp1((String) output1.get("bidp1")); +// dto.setBidp2((String) output1.get("bidp2")); +// dto.setBidp1((String) output1.get("bidp3")); +// dto.setBidp1((String) output1.get("bidp4")); +// dto.setBidp1((String) output1.get("bidp5")); +// +// +// dto.setAskp_rsqn1((String) output1.get("askp_rsqn1")); +// dto.setAskp_rsqn2((String) output1.get("askp_rsqn2")); +// dto.setAskp_rsqn2((String) output1.get("askp_rsqn3")); +// dto.setAskp_rsqn2((String) output1.get("askp_rsqn4")); +// dto.setAskp_rsqn2((String) output1.get("askp_rsqn5")); +// +// dto.setBidp_rsqn1((String) output1.get("bidp_rsqn1")); +// dto.setBidp_rsqn2((String) output1.get("bidp_rsqn2")); +// dto.setBidp_rsqn1((String) output1.get("bidp_rsqn3")); +// dto.setBidp_rsqn1((String) output1.get("bidp_rsqn4")); +// dto.setBidp_rsqn1((String) output1.get("bidp_rsqn5")); +// +// +// +// dto.setAspr_acpt_hour((String) output2.get("aspr_acpt_hour")); +// dto.setStck_prpr((String) output2.get("stck_prpr")); +// dto.setStck_oprc((String) output2.get("stck_oprc")); +// dto.setStck_hgpr((String) output2.get("stck_hgpr")); +// dto.setStck_lwpr((String) output2.get("stck_lwpr")); +// dto.setStck_sdpr((String) output2.get("stck_sdpr")); +// +// return dto; +// } +//} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java index a6b7edd8..e116fff2 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java @@ -2,21 +2,10 @@ import lombok.*; -import javax.persistence.Entity; - @Data @NoArgsConstructor -@AllArgsConstructor public class StockasbiDataDto { - private String askp1, askp2, askp3, askp4, askp5; - private String bidp1, bidp2, bidp3, bidp4, bidp5; - private String askp_rsqn1, askp_rsqn2, askp_rsqn3, askp_rsqn4, askp_rsqn5; - private String bidp_rsqn1, bidp_rsqn2, bidp_rsqn3, bidp_rsqn4, bidp_rsqn5; - private String aspr_acpt_hour; - private String stck_prpr; - private String stck_oprc; - private String stck_hgpr; - private String stck_lwpr; - private String stck_sdpr; + private StockAsBiOutput1 output1; + private StockAsBiOutput2 output2; } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java index 9fe81463..840f77c7 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java @@ -1,8 +1,11 @@ package com.stockholm.main_project.stock.stockdata.service; -import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataConverter; +//import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataConverter; import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataDto; +import com.stockholm.main_project.stock.stockdata.dto.StockMinDto; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Service; import org.springframework.http.*; import org.springframework.web.client.RestTemplate; @@ -11,20 +14,26 @@ @Service +@Slf4j public class StockService { - private final StockasbiDataConverter converter = new StockasbiDataConverter(); + //private final StockasbiDataConverter converter = new StockasbiDataConverter(); private final String APP_KEY = "PSjMh9iyz0EFvbpWkvuYHfLiFuHyNAtLoG9h"; private final String APP_SECRET = "vtzv7bG78qgtThPEujr1MWDJHKTawSoEDRfAJzB/lYvwj67HdzUsyUavVGD4kORIeGS5q6BJBwoICXy97h8d3RaSAvhK03Yu/seFm0t+22ZQBv4GKhxvU5jGwdMrsucyKuQ0EtXfkJxJoLFsqIO1UA1n3r4HX0D5RxIe8I8efwEYVbidAn4="; private final String TOKEN_URL = "https://openapi.koreainvestment.com:9443/oauth2/tokenP"; private final String STOCKASBI_URL = "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-asking-price-exp-ccn"; - private final String STOCKHOUR_URL = "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-time-itemconclusion"; - private final String START_TIME = "155000"; + private final String STOCKHOUR_URL = "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-time-itemchartprice"; + + private final String FID_ETC_CLS_CODE = ""; + + private final String FID_COND_MRKT_DIV_CODE = "J"; + + private final String FID_INPUT_HOUR_1 = "153000"; + + private final String FID_PW_DATA_INCU_YN = "Y"; private final List DEFAULT_STOCK_CODES = Arrays.asList( - "005930", "373220", "000660", "207940", "005490" -// "005935", "006400" -// "051910" -// "005380", "003670" + "005930", "373220"//, "000660", "207940", "005490", + //"005935"//, "006400"//, "051910", "005380", "003670" // "035420", "000270", "012330", "035720", "068270" ); @@ -46,7 +55,7 @@ public String getAccessToken() { return response.getBody().get("access_token").toString(); } - public List getStockasbiData() { + public List getStockasbiData(){ List stockDatas = new ArrayList<>(); for (String stockCode : DEFAULT_STOCK_CODES) { String token = getAccessToken(); @@ -61,15 +70,23 @@ public List getStockasbiData() { HttpEntity entity = new HttpEntity<>("parameters", headers); - ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, Map.class); - StockasbiDataDto dto = converter.convertToStockasbiDataDto(response.getBody()); + ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference() {}); + + if (response.getStatusCode().is2xxSuccessful()) { + StockasbiDataDto stockasbiDataDto = response.getBody(); + stockDatas.add(stockasbiDataDto); + // 응답 바디를 MyResponseClass 객체로 매핑하여 처리 + } else { + log.info("error"); + } + + - stockDatas.add(dto); } return stockDatas; } - public List getStockhourData() { - List stockDatas = new ArrayList<>(); + public List getStockMinData() { + List stockDatas = new ArrayList<>(); for (String stockCode : DEFAULT_STOCK_CODES) { String token = getAccessToken(); @@ -77,17 +94,22 @@ public List getStockhourData() { headers.add("Authorization", "Bearer " + token); headers.add("appkey", APP_KEY); headers.add("appsecret", APP_SECRET); - headers.add("tr_id", "FHPST01060000"); + headers.add("tr_id", "FHKST03010200"); - String uri = STOCKHOUR_URL - + "?FID_COND_MRKT_DIV_CODE=J&FID_INPUT_ISCD=" + stockCode - + "&FID_INPUT_HOUR_1=" + START_TIME; + String uri = STOCKHOUR_URL + "?FID_COND_MRKT_DIV_CODE=" + FID_COND_MRKT_DIV_CODE + "&FID_INPUT_ISCD=" + stockCode + "&FID_ETC_CLS_CODE=" + FID_ETC_CLS_CODE + + "&FID_INPUT_HOUR_1=" + FID_INPUT_HOUR_1 + "&FID_PW_DATA_INCU_YN=" + FID_PW_DATA_INCU_YN; HttpEntity entity = new HttpEntity<>("parameters", headers); - ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class); + ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference() {}); - stockDatas.add(response.getBody()); + if (response.getStatusCode().is2xxSuccessful()) { + StockMinDto stockMinDto = response.getBody(); + stockDatas.add(stockMinDto); + // 응답 바디를 MyResponseClass 객체로 매핑하여 처리 + } else { + log.info("error"); + } } return stockDatas; } From 12abf8a06911f10faa5193ca0f56ea1d2ffb5800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=A4=80=EC=84=9D?= Date: Wed, 30 Aug 2023 14:02:03 +0900 Subject: [PATCH 10/83] =?UTF-8?q?Feat=20:=20=EA=B2=8C=EC=8B=9C=ED=8C=90=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 ++ .idea/compiler.xml | 15 +++ .idea/gradle.xml | 17 +++ .idea/jarRepositories.xml | 20 +++ .idea/misc.xml | 10 ++ .idea/modules.xml | 8 ++ .idea/seb45_main_008.iml | 9 ++ .idea/uiDesigner.xml | 124 ++++++++++++++++++ .idea/vcs.xml | 6 + .../board/Controller/BoardController.java | 82 ++++++++++++ .../board/Repository/BoardRepository.java | 11 ++ .../board/Service/BoardService.java | 69 ++++++++++ .../main_project/board/dto/BoardDto.java | 11 ++ .../main_project/board/dto/BoardPostDto.java | 23 ++++ .../main_project/board/entity/Board.java | 2 +- 15 files changed, 414 insertions(+), 1 deletion(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/seb45_main_008.iml create mode 100644 .idea/uiDesigner.xml create mode 100644 .idea/vcs.xml create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/board/Controller/BoardController.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/board/Repository/BoardRepository.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/board/Service/BoardService.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/board/dto/BoardDto.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/board/dto/BoardPostDto.java diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..13566b81 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 00000000..a43a0b2e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 00000000..e1895728 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 00000000..fdc392fe --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..3b49fb15 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..53b0c837 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/seb45_main_008.iml b/.idea/seb45_main_008.iml new file mode 100644 index 00000000..d6ebd480 --- /dev/null +++ b/.idea/seb45_main_008.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 00000000..2b63946d --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/Controller/BoardController.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/Controller/BoardController.java new file mode 100644 index 00000000..2c1f4cf6 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/Controller/BoardController.java @@ -0,0 +1,82 @@ +package com.stockholm.main_project.board.Controller; + +import com.stockholm.main_project.board.Service.BoardService; +import com.stockholm.main_project.board.entity.Board; // Board 클래스를 참조하도록 수정 +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/boards") +public class BoardController { + + @Autowired + private BoardService boardService; + + // 게시물 생성 + @PostMapping + public ResponseEntity createPost(@RequestBody @Valid Board board) { + Board createdBoard = boardService.createBoard(board); + return new ResponseEntity<>(createdBoard, HttpStatus.CREATED); + } + + // 모든 게시물 조회 + @GetMapping + public ResponseEntity> getAllBoards() { + List boards = boardService.getAllBoards(); + return new ResponseEntity<>(boards, HttpStatus.OK); + } + + // 특정 게시물 조회 + @GetMapping("/{boardId}") + public ResponseEntity getBoardById(@PathVariable Long boardId) { + Board board = boardService.getBoardById(boardId); + if (board != null) { + return new ResponseEntity<>(board, HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + + // 게시물 업데이트 + @PutMapping("/{boardId}") + public ResponseEntity updateBoard(@PathVariable Long boardId, @RequestBody @Valid Board board) { + Board updatedBoard = boardService.updateBoard(boardId, board); + if (updatedBoard != null) { + return new ResponseEntity<>(updatedBoard, HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + //게시물 수정 + @PatchMapping("/{boardId}") + public ResponseEntity patchBoard( + @PathVariable Long boardId, + @RequestBody Map updates) { + + Board updatedBoard = boardService.patchBoard(boardId, updates); + + if (updatedBoard != null) { + return new ResponseEntity<>(updatedBoard, HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + + + // 게시물 삭제 + @DeleteMapping("/{boardId}") // 변수 이름도 수정 + public ResponseEntity deleteBoard(@PathVariable Long boardId) { // 변수 이름도 수정 + boolean deleted = boardService.deleteBoard(boardId); // 서비스 메서드도 수정 + if (deleted) { + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/Repository/BoardRepository.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/Repository/BoardRepository.java new file mode 100644 index 00000000..a5d447b7 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/Repository/BoardRepository.java @@ -0,0 +1,11 @@ +package com.stockholm.main_project.board.Repository; + +import com.stockholm.main_project.board.entity.Board; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository + +public interface BoardRepository extends JpaRepository { + // 추가적인 쿼리 메서드를 정의할 수 있음 +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/Service/BoardService.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/Service/BoardService.java new file mode 100644 index 00000000..f4eb03cc --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/Service/BoardService.java @@ -0,0 +1,69 @@ +package com.stockholm.main_project.board.Service; + +import com.stockholm.main_project.board.Repository.BoardRepository; +import com.stockholm.main_project.board.entity.Board; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@Service +public class BoardService { + + @Autowired + private BoardRepository boardRepository; + + public Board createBoard(Board board) { + // 게시물 생성 로직 구현 + return boardRepository.save(board); + } + + public List getAllBoards() { + // 모든 게시물 조회 로직 구현 + return boardRepository.findAll(); + } + + public Board getBoardById(Long boardId) { + // 특정 게시물 조회 로직 구현 + return boardRepository.findById(boardId).orElse(null); + } + + public Board updateBoard(Long boardId, Board board) { + // 게시물 업데이트 로직 구현 + board.setBoardId(boardId); + return boardRepository.save(board); + } + + public boolean deleteBoard(Long boardId) { + // 게시물 삭제 로직 구현 + if (boardRepository.existsById(boardId)) { + boardRepository.deleteById(boardId); + return true; + } + return false; + } + + // 게시물 일부 업데이트를 처리하는 메서드 추가 + public Board patchBoard(Long boardId, Map updates) { + Optional existingBoardOptional = boardRepository.findById(boardId); + + if (existingBoardOptional.isPresent()) { + Board existingBoard = existingBoardOptional.get(); + + // 'updates' 맵의 값을 기반으로 필드 업데이트 + if (updates.containsKey("title")) { + existingBoard.setTitle((String) updates.get("title")); + } + if (updates.containsKey("content")) { + existingBoard.setContent((String) updates.get("content")); + } + // 필요한 경우 업데이트할 필드를 추가합니다. + + return boardRepository.save(existingBoard); + } else { + return null; // 게시물을 찾을 수 없음 + } + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/BoardDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/BoardDto.java new file mode 100644 index 00000000..dee4549e --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/BoardDto.java @@ -0,0 +1,11 @@ +package com.stockholm.main_project.board.dto; + +public class BoardDto { + private long id; + private String title; + private String body; + private String img; + private long memberId; + private long commentId; + +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/BoardPostDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/BoardPostDto.java new file mode 100644 index 00000000..ef81b48c --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/dto/BoardPostDto.java @@ -0,0 +1,23 @@ +package com.stockholm.main_project.board.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +@Getter +@Setter +@NoArgsConstructor +public class BoardPostDto { + @NotBlank(message = "제목을 입력해 주세요") + @Size(max = 30, message = "제목의 길이는 30자를 넘을 수 없습니다") + private String title; + + @NotBlank(message = "내용을 입력해 주세요") + @Size(max = 100, message = "내용은 100자를 넘을 수 없습니다") + private String content; + + // 게터, 세터, 생성자 등 필요한 메서드 추가 가능 +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Board.java b/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Board.java index 2aab95de..a9024694 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Board.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/board/entity/Board.java @@ -22,7 +22,7 @@ public class Board extends Auditable { private String title; @Column - private String body; + private String content; @ManyToOne @JoinColumn(name = "MEMBER_ID") From f18a81c0614fd25b7b0e8e23a2e03dc85b90d255 Mon Sep 17 00:00:00 2001 From: JaeYong Date: Wed, 30 Aug 2023 18:11:15 +0900 Subject: [PATCH 11/83] =?UTF-8?q?[Feat]=20AccessToken=20=EB=B0=9B=EC=95=84?= =?UTF-8?q?=EC=98=A4=EA=B8=B0=20=EC=84=A4=EC=A0=95,?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -AccessToken 설정 추가 Issues #5 --- .../scheduler/StockScheduler.java | 60 ++++++--- .../stock/controller/StockController.java | 34 +++++ .../{stockdata => }/dto/StockAsBiOutput1.java | 7 +- .../{stockdata => }/dto/StockAsBiOutput2.java | 8 +- .../{stockdata => }/dto/StockMinDto.java | 2 +- .../{stockdata => }/dto/StockMinOutput1.java | 4 +- .../{stockdata => }/dto/StockMinOutput2.java | 7 +- .../dto/StockasbiDataConverter.java | 0 .../{stockdata => }/dto/StockasbiDataDto.java | 2 +- .../dto/StockminConverter.java | 0 .../main_project/stock/entity/Company.java | 2 +- .../stock/entity/StockAsBiData.java | 44 +++++++ .../stock/entity/StockMinData.java | 14 ++ .../main_project/stock/entity/Token.java | 26 ++++ .../stock/repository/CompanyRepository.java | 7 + .../stock/repository/StarRepository.java | 7 + .../repository/StockOrderRepository.java | 7 + .../stock/repository/TokenRepository.java | 7 + .../stock/service/StockService.java | 121 ++++++++++++++++++ .../stock/service/TokenService.java | 99 ++++++++++++++ .../stockdata/controller/StockController.java | 34 ----- .../stock/stockdata/service/StockService.java | 116 ----------------- .../src/main/resources/application.yml | 28 ++-- 23 files changed, 451 insertions(+), 185 deletions(-) create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/controller/StockController.java rename server/008main_project/src/main/java/com/stockholm/main_project/stock/{stockdata => }/dto/StockAsBiOutput1.java (83%) rename server/008main_project/src/main/java/com/stockholm/main_project/stock/{stockdata => }/dto/StockAsBiOutput2.java (65%) rename server/008main_project/src/main/java/com/stockholm/main_project/stock/{stockdata => }/dto/StockMinDto.java (79%) rename server/008main_project/src/main/java/com/stockholm/main_project/stock/{stockdata => }/dto/StockMinOutput1.java (69%) rename server/008main_project/src/main/java/com/stockholm/main_project/stock/{stockdata => }/dto/StockMinOutput2.java (65%) rename server/008main_project/src/main/java/com/stockholm/main_project/stock/{stockdata => }/dto/StockasbiDataConverter.java (100%) rename server/008main_project/src/main/java/com/stockholm/main_project/stock/{stockdata => }/dto/StockasbiDataDto.java (73%) rename server/008main_project/src/main/java/com/stockholm/main_project/stock/{stockdata => }/dto/StockminConverter.java (100%) create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockAsBiData.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockMinData.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Token.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/CompanyRepository.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/StarRepository.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/StockOrderRepository.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/TokenRepository.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/service/StockService.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/service/TokenService.java delete mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java delete mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/scheduler/StockScheduler.java b/server/008main_project/src/main/java/com/stockholm/main_project/scheduler/StockScheduler.java index 28dec214..d299f260 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/scheduler/StockScheduler.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/scheduler/StockScheduler.java @@ -1,22 +1,44 @@ -//package com.stockholm.main_project.scheduler; -// -//import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataDto; -//import com.stockholm.main_project.stock.stockdata.service.StockService; -//import lombok.extern.slf4j.Slf4j; -//import org.springframework.scheduling.annotation.Scheduled; -//import org.springframework.stereotype.Service; -// -//import java.util.List; -// -//@Slf4j -//@Service -//public class StockScheduler { -// private StockService stockService; -// -// public StockScheduler(StockService stockService) { -// this.stockService = stockService; +package com.stockholm.main_project.scheduler; + +import com.stockholm.main_project.stock.dto.StockasbiDataDto; +import com.stockholm.main_project.stock.entity.Company; +import com.stockholm.main_project.stock.service.StockService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +public class StockScheduler { + private StockService stockService; + + public StockScheduler(StockService stockService) { + this.stockService = stockService; + } + + //@Scheduled(cron = "5 0 9 * * MON-FRI") + @Scheduled(fixedRate = 10000000) + public void firstSchedule() throws InterruptedException { + List companyList = stockService.getCompanies(); + + for(int i = 0; i < companyList.size(); i++) { + StockasbiDataDto stockasbiDataDto = stockService.getStockasbiData(companyList.get(i).getCode()); + + + + Thread.sleep(100); + } + } + +// @Scheduled(fixedRate = 1000) +// public void run() { +// System.out.println("Hi"); // } -// +} + + // @Scheduled(fixedRate = 60000) // public void run() { // List stockasbiDataDtos = stockService.getStockasbiData(); @@ -121,4 +143,4 @@ // log.info(stockasbiDataDto.getOutput1().getAskp5()); // } // } -//} + diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/controller/StockController.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/controller/StockController.java new file mode 100644 index 00000000..d179b7e5 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/controller/StockController.java @@ -0,0 +1,34 @@ +package com.stockholm.main_project.stock.controller; + + +import com.stockholm.main_project.stock.dto.StockasbiDataDto; +import com.stockholm.main_project.stock.dto.StockMinDto; +import com.stockholm.main_project.stock.service.StockService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Controller +public class StockController { + + @Autowired + private StockService stockService; + + +// @ResponseBody +// @GetMapping("/stockasbi") +// public ResponseEntity getStockasbiData() { +// List stockDatas = stockService.getStockasbiData(); +// return ResponseEntity.ok(stockDatas); +// } +// @ResponseBody +// @GetMapping("/stockmin") +// public ResponseEntity getStockMinData() { +// List stockDatas = stockService.getStockMinData(); +// return ResponseEntity.ok(stockDatas); +// } +} + diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput1.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockAsBiOutput1.java similarity index 83% rename from server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput1.java rename to server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockAsBiOutput1.java index fd64078c..6445a982 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput1.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockAsBiOutput1.java @@ -1,4 +1,4 @@ -package com.stockholm.main_project.stock.stockdata.dto; +package com.stockholm.main_project.stock.dto; import lombok.Getter; import lombok.NoArgsConstructor; @@ -9,26 +9,31 @@ @NoArgsConstructor public class StockAsBiOutput1 { + // 호가 접수 시간 private String aspr_acpt_hour; + //매도 호가 private String askp1; private String askp2; private String askp3; private String askp4; private String askp5; + //매도 잔량 private String askp_rsqn1; private String askp_rsqn2; private String askp_rsqn3; private String askp_rsqn4; private String askp_rsqn5; + //매수 호가 private String bidp1; private String bidp2; private String bidp3; private String bidp4; private String bidp5; + //매수 잔량 private String bidp_rsqn1; private String bidp_rsqn2; private String bidp_rsqn3; diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput2.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockAsBiOutput2.java similarity index 65% rename from server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput2.java rename to server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockAsBiOutput2.java index fe3c8f18..669f1ed4 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockAsBiOutput2.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockAsBiOutput2.java @@ -1,4 +1,4 @@ -package com.stockholm.main_project.stock.stockdata.dto; +package com.stockholm.main_project.stock.dto; import lombok.Getter; import lombok.NoArgsConstructor; @@ -8,9 +8,15 @@ @Setter @NoArgsConstructor public class StockAsBiOutput2 { + + //주식 현재가 private String stck_prpr; + //주식 시가 private String stck_oprc; + //주식 최고가 private String stck_hgpr; + //주식 최저가 private String stck_lwpr; + //주식 기준가 private String stck_sdpr; } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockMinDto.java similarity index 79% rename from server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinDto.java rename to server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockMinDto.java index d2a53208..cb859fc7 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinDto.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockMinDto.java @@ -1,4 +1,4 @@ -package com.stockholm.main_project.stock.stockdata.dto; +package com.stockholm.main_project.stock.dto; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput1.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockMinOutput1.java similarity index 69% rename from server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput1.java rename to server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockMinOutput1.java index 92e99657..81cc3851 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput1.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockMinOutput1.java @@ -1,4 +1,4 @@ -package com.stockholm.main_project.stock.stockdata.dto; +package com.stockholm.main_project.stock.dto; import lombok.Getter; import lombok.NoArgsConstructor; @@ -8,6 +8,8 @@ @Setter @NoArgsConstructor public class StockMinOutput1 { + //한글 종목 명 private String hts_kor_isnm; + //주식 현재가 private String stck_prpr; } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput2.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockMinOutput2.java similarity index 65% rename from server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput2.java rename to server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockMinOutput2.java index 99143dcc..b22eb78f 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockMinOutput2.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockMinOutput2.java @@ -1,4 +1,4 @@ -package com.stockholm.main_project.stock.stockdata.dto; +package com.stockholm.main_project.stock.dto; import lombok.Getter; import lombok.NoArgsConstructor; @@ -8,9 +8,14 @@ @Setter @NoArgsConstructor public class StockMinOutput2 { + //주식 체결 시간 private String stck_cntg_hour; + //주식 현재가 private String stck_prpr; + //주식 시가 private String stck_oprc; + //주식 최고가 private String stck_hgpr; + //주식 최저가 private String stck_lwpr; } diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockasbiDataConverter.java similarity index 100% rename from server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataConverter.java rename to server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockasbiDataConverter.java diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockasbiDataDto.java similarity index 73% rename from server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java rename to server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockasbiDataDto.java index e116fff2..e4be38c9 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockasbiDataDto.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockasbiDataDto.java @@ -1,4 +1,4 @@ -package com.stockholm.main_project.stock.stockdata.dto; +package com.stockholm.main_project.stock.dto; import lombok.*; diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockminConverter.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockminConverter.java similarity index 100% rename from server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/dto/StockminConverter.java rename to server/008main_project/src/main/java/com/stockholm/main_project/stock/dto/StockminConverter.java diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java index 1b6bc8fc..327a588f 100644 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Company.java @@ -17,7 +17,7 @@ public class Company extends Auditable { private long companyId; @Column - private int code; + private String code; @Column private String korName; diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockAsBiData.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockAsBiData.java new file mode 100644 index 00000000..e87be328 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockAsBiData.java @@ -0,0 +1,44 @@ +//package com.stockholm.main_project.stock.entity; +// +//import lombok.Getter; +//import lombok.NoArgsConstructor; +//import lombok.Setter; +// +//import javax.persistence.Entity; +// +//@Entity +//@Getter +//@Setter +//@NoArgsConstructor +//public class StockAsBiData { +// // 호가 접수 시간 +// private String aspr_acpt_hour; +// +// //매도 호가 +// private String askp1; +// private String askp2; +// private String askp3; +// private String askp4; +// private String askp5; +// +// //매도 잔량 +// private String askp_rsqn1; +// private String askp_rsqn2; +// private String askp_rsqn3; +// private String askp_rsqn4; +// private String askp_rsqn5; +// +// //매수 호가 +// private String bidp1; +// private String bidp2; +// private String bidp3; +// private String bidp4; +// private String bidp5; +// +// //매수 잔량 +// private String bidp_rsqn1; +// private String bidp_rsqn2; +// private String bidp_rsqn3; +// private String bidp_rsqn4; +// private String bidp_rsqn5; +//} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockMinData.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockMinData.java new file mode 100644 index 00000000..47da1a0c --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/StockMinData.java @@ -0,0 +1,14 @@ +//package com.stockholm.main_project.stock.entity; +// +//import lombok.Getter; +//import lombok.NoArgsConstructor; +//import lombok.Setter; +// +//import javax.persistence.Entity; +// +//@Entity +//@Getter +//@Setter +//@NoArgsConstructor +//public class StockMinData { +//} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Token.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Token.java new file mode 100644 index 00000000..25b56b28 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/entity/Token.java @@ -0,0 +1,26 @@ +package com.stockholm.main_project.stock.entity; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import javax.persistence.*; +import java.time.LocalDateTime; + +@Entity +@Getter +@Setter +@NoArgsConstructor +public class Token { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + long tokenId; + + @Column(length = 500) + private String token; + + @Column + private LocalDateTime expired; + + +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/CompanyRepository.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/CompanyRepository.java new file mode 100644 index 00000000..9288ca20 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/CompanyRepository.java @@ -0,0 +1,7 @@ +package com.stockholm.main_project.stock.repository; + +import com.stockholm.main_project.stock.entity.Company; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CompanyRepository extends JpaRepository { +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/StarRepository.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/StarRepository.java new file mode 100644 index 00000000..4ac1fbe7 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/StarRepository.java @@ -0,0 +1,7 @@ +package com.stockholm.main_project.stock.repository; + +import com.stockholm.main_project.stock.entity.Star; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface StarRepository extends JpaRepository { +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/StockOrderRepository.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/StockOrderRepository.java new file mode 100644 index 00000000..ba2b36f0 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/StockOrderRepository.java @@ -0,0 +1,7 @@ +package com.stockholm.main_project.stock.repository; + +import com.stockholm.main_project.stock.entity.StockOrder; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface StockOrderRepository extends JpaRepository { +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/TokenRepository.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/TokenRepository.java new file mode 100644 index 00000000..9f071ef6 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/repository/TokenRepository.java @@ -0,0 +1,7 @@ +package com.stockholm.main_project.stock.repository; + +import com.stockholm.main_project.stock.entity.Token; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TokenRepository extends JpaRepository { +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/StockService.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/StockService.java new file mode 100644 index 00000000..28d1f6db --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/StockService.java @@ -0,0 +1,121 @@ +package com.stockholm.main_project.stock.service; + + +//import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataConverter; +import com.stockholm.main_project.stock.dto.StockasbiDataDto; +import com.stockholm.main_project.stock.dto.StockMinDto; +import com.stockholm.main_project.stock.entity.Company; +import com.stockholm.main_project.stock.repository.CompanyRepository; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.stereotype.Service; +import org.springframework.http.*; +import org.springframework.web.client.RestTemplate; + +import java.util.*; + + +@Service +@Slf4j +public class StockService { + @Getter + @Value("${token.app-key}") + private String APP_KEY; + + @Getter + @Value("${token.app-secret}") + private String APP_SECRET; + + @Getter + @Value("${stock-url.token}") + private String TOKEN_URL; + + @Getter + @Value("${stock-url.stockasbi}") + private String STOCKASBI_URL; + + @Getter + @Value("${stock-url.stockhour}") + private String STOCKHOUR_URL; + + + private final String FID_ETC_CLS_CODE = ""; + private final String FID_COND_MRKT_DIV_CODE = "J"; + private final String FID_INPUT_HOUR_1 = "153000"; + private final String FID_PW_DATA_INCU_YN = "Y"; + + private RestTemplate restTemplate = new RestTemplate(); + + public StockService(TokenService tokenService, CompanyRepository companyRepository) { + this.tokenService = tokenService; + this.companyRepository = companyRepository; + } + + private final TokenService tokenService; + + private final CompanyRepository companyRepository; + + public StockasbiDataDto getStockasbiData(String stockCode){ + String token = tokenService.getAccessToken(); + + HttpHeaders headers = new HttpHeaders(); + headers.add("Authorization", "Bearer " + token); + headers.add("appkey", APP_KEY); + headers.add("appsecret", APP_SECRET); + headers.add("tr_id", "FHKST01010200"); + + String uri = STOCKASBI_URL + "?FID_COND_MRKT_DIV_CODE=J&FID_INPUT_ISCD=" + stockCode; + + HttpEntity entity = new HttpEntity<>("parameters", headers); + + ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference() {}); + + if (response.getStatusCode().is2xxSuccessful()) { + StockasbiDataDto stockasbiDataDto = response.getBody(); + return stockasbiDataDto; + // 응답 바디를 MyResponseClass 객체로 매핑하여 처리 + } else { + log.info("error"); + return null; + } + + } + +// public List getStockMinData() { +// List stockDatas = new ArrayList<>(); +// for (String stockCode : DEFAULT_STOCK_CODES) { +// String token = tokenService.getAccessToken(); +// +// HttpHeaders headers = new HttpHeaders(); +// headers.add("Authorization", "Bearer " + token); +// headers.add("appkey", APP_KEY); +// headers.add("appsecret", APP_SECRET); +// headers.add("tr_id", "FHKST03010200"); +// +// String uri = STOCKHOUR_URL + "?FID_COND_MRKT_DIV_CODE=" + FID_COND_MRKT_DIV_CODE + "&FID_INPUT_ISCD=" + stockCode + "&FID_ETC_CLS_CODE=" + FID_ETC_CLS_CODE +// + "&FID_INPUT_HOUR_1=" + FID_INPUT_HOUR_1 + "&FID_PW_DATA_INCU_YN=" + FID_PW_DATA_INCU_YN; +// +// HttpEntity entity = new HttpEntity<>("parameters", headers); +// +// ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference() {}); +// +// if (response.getStatusCode().is2xxSuccessful()) { +// StockMinDto stockMinDto = response.getBody(); +// stockDatas.add(stockMinDto); +// // 응답 바디를 MyResponseClass 객체로 매핑하여 처리 +// } else { +// log.info("error"); +// } +// } +// return stockDatas; +// } + + // 모든 회사 리턴 + public List getCompanies() { + List companies = companyRepository.findAll(); + + return companies; + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/TokenService.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/TokenService.java new file mode 100644 index 00000000..a2a5a8e9 --- /dev/null +++ b/server/008main_project/src/main/java/com/stockholm/main_project/stock/service/TokenService.java @@ -0,0 +1,99 @@ +package com.stockholm.main_project.stock.service; + +import com.stockholm.main_project.stock.repository.TokenRepository; +import com.stockholm.main_project.stock.entity.Token; +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Service +public class TokenService { + + public TokenService(TokenRepository tokenRepository) { + this.tokenRepository = tokenRepository; + } + + private final TokenRepository tokenRepository; + + @Getter + @Value("${token.app-key}") + private String APP_KEY; + + @Getter + @Value("${token.app-secret}") + private String APP_SECRET; + + @Getter + @Value("${stock-url.token}") + private String TOKEN_URL; + + private RestTemplate restTemplate = new RestTemplate(); + + public String getAccessToken() { + + // 만료 되지 않았을 경우 + if(tokenVerification()) { + Optional token = tokenRepository.findById(1L); + + return token.get().getToken(); + + } + // 만료 되었을 경우 + else { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + Map body = new HashMap<>(); + body.put("grant_type", "client_credentials"); + body.put("appkey", APP_KEY); + body.put("appsecret", APP_SECRET); + + HttpEntity> request = new HttpEntity<>(body, headers); + + ResponseEntity response = restTemplate.postForEntity(TOKEN_URL, request, Map.class); + + Optional token = tokenRepository.findById(1L); + + if(token.isEmpty()) { + Token newToken = new Token(); + + newToken.setTokenId(1L); + newToken.setToken(response.getBody().get("access_token").toString()); + newToken.setExpired(LocalDateTime.now().plusDays(1)); + + tokenRepository.save(newToken); + + } + else { + token.get().setToken(response.getBody().get("access_token").toString()); + token.get().setExpired(LocalDateTime.now().plusDays(1)); + + tokenRepository.save(token.get()); + + } + + return response.getBody().get("access_token").toString(); + } + } + + public boolean tokenVerification() { + LocalDateTime currentDateTime = LocalDateTime.now(); + Optional token = tokenRepository.findById(1L); + + // 토큰이 비어있거나, 현재 시간이 토큰 유효간보다 뒤에 있을 때(만료 됨) + if( token.isEmpty() || currentDateTime.isAfter(token.get().getExpired())) + return false; + else + return true; + } +} diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java deleted file mode 100644 index b2b7b919..00000000 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/controller/StockController.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.stockholm.main_project.stock.stockdata.controller; - - -import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataDto; -import com.stockholm.main_project.stock.stockdata.dto.StockMinDto; -import com.stockholm.main_project.stock.stockdata.service.StockService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -@Controller -public class StockController { - - @Autowired - private StockService stockService; - - - @ResponseBody - @GetMapping("/stockasbi") - public ResponseEntity getStockasbiData() { - List stockDatas = stockService.getStockasbiData(); - return ResponseEntity.ok(stockDatas); - } - @ResponseBody - @GetMapping("/stockmin") - public ResponseEntity getStockMinData() { - List stockDatas = stockService.getStockMinData(); - return ResponseEntity.ok(stockDatas); - } -} - diff --git a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java b/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java deleted file mode 100644 index 840f77c7..00000000 --- a/server/008main_project/src/main/java/com/stockholm/main_project/stock/stockdata/service/StockService.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.stockholm.main_project.stock.stockdata.service; - - -//import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataConverter; -import com.stockholm.main_project.stock.stockdata.dto.StockasbiDataDto; -import com.stockholm.main_project.stock.stockdata.dto.StockMinDto; -import lombok.extern.slf4j.Slf4j; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.stereotype.Service; -import org.springframework.http.*; -import org.springframework.web.client.RestTemplate; - -import java.util.*; - - -@Service -@Slf4j -public class StockService { - //private final StockasbiDataConverter converter = new StockasbiDataConverter(); - private final String APP_KEY = "PSjMh9iyz0EFvbpWkvuYHfLiFuHyNAtLoG9h"; - private final String APP_SECRET = "vtzv7bG78qgtThPEujr1MWDJHKTawSoEDRfAJzB/lYvwj67HdzUsyUavVGD4kORIeGS5q6BJBwoICXy97h8d3RaSAvhK03Yu/seFm0t+22ZQBv4GKhxvU5jGwdMrsucyKuQ0EtXfkJxJoLFsqIO1UA1n3r4HX0D5RxIe8I8efwEYVbidAn4="; - private final String TOKEN_URL = "https://openapi.koreainvestment.com:9443/oauth2/tokenP"; - private final String STOCKASBI_URL = "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-asking-price-exp-ccn"; - private final String STOCKHOUR_URL = "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-time-itemchartprice"; - - private final String FID_ETC_CLS_CODE = ""; - - private final String FID_COND_MRKT_DIV_CODE = "J"; - - private final String FID_INPUT_HOUR_1 = "153000"; - - private final String FID_PW_DATA_INCU_YN = "Y"; - - private final List DEFAULT_STOCK_CODES = Arrays.asList( - "005930", "373220"//, "000660", "207940", "005490", - //"005935"//, "006400"//, "051910", "005380", "003670" -// "035420", "000270", "012330", "035720", "068270" - ); - - private RestTemplate restTemplate = new RestTemplate(); - - public String getAccessToken() { - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - - Map body = new HashMap<>(); - body.put("grant_type", "client_credentials"); - body.put("appkey", APP_KEY); - body.put("appsecret", APP_SECRET); - - HttpEntity> request = new HttpEntity<>(body, headers); - - ResponseEntity response = restTemplate.postForEntity(TOKEN_URL, request, Map.class); - - return response.getBody().get("access_token").toString(); - } - - public List getStockasbiData(){ - List stockDatas = new ArrayList<>(); - for (String stockCode : DEFAULT_STOCK_CODES) { - String token = getAccessToken(); - - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Bearer " + token); - headers.add("appkey", APP_KEY); - headers.add("appsecret", APP_SECRET); - headers.add("tr_id", "FHKST01010200"); - - String uri = STOCKASBI_URL + "?FID_COND_MRKT_DIV_CODE=J&FID_INPUT_ISCD=" + stockCode; - - HttpEntity entity = new HttpEntity<>("parameters", headers); - - ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference() {}); - - if (response.getStatusCode().is2xxSuccessful()) { - StockasbiDataDto stockasbiDataDto = response.getBody(); - stockDatas.add(stockasbiDataDto); - // 응답 바디를 MyResponseClass 객체로 매핑하여 처리 - } else { - log.info("error"); - } - - - - } - return stockDatas; - } - public List getStockMinData() { - List stockDatas = new ArrayList<>(); - for (String stockCode : DEFAULT_STOCK_CODES) { - String token = getAccessToken(); - - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", "Bearer " + token); - headers.add("appkey", APP_KEY); - headers.add("appsecret", APP_SECRET); - headers.add("tr_id", "FHKST03010200"); - - String uri = STOCKHOUR_URL + "?FID_COND_MRKT_DIV_CODE=" + FID_COND_MRKT_DIV_CODE + "&FID_INPUT_ISCD=" + stockCode + "&FID_ETC_CLS_CODE=" + FID_ETC_CLS_CODE - + "&FID_INPUT_HOUR_1=" + FID_INPUT_HOUR_1 + "&FID_PW_DATA_INCU_YN=" + FID_PW_DATA_INCU_YN; - - HttpEntity entity = new HttpEntity<>("parameters", headers); - - ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference() {}); - - if (response.getStatusCode().is2xxSuccessful()) { - StockMinDto stockMinDto = response.getBody(); - stockDatas.add(stockMinDto); - // 응답 바디를 MyResponseClass 객체로 매핑하여 처리 - } else { - log.info("error"); - } - } - return stockDatas; - } -} diff --git a/server/008main_project/src/main/resources/application.yml b/server/008main_project/src/main/resources/application.yml index c5ede541..da42f508 100644 --- a/server/008main_project/src/main/resources/application.yml +++ b/server/008main_project/src/main/resources/application.yml @@ -1,16 +1,17 @@ spring: - h2: - console: - enabled: true - path: /h2 - settings: - web-allow-others: true datasource: - url: jdbc:h2:mem:test + url: jdbc:mysql://stockholm.c9tdmcjx6fcv.ap-northeast-2.rds.amazonaws.com/stockholm?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8&serverTimezone=Asia/Seoul + username: admin + password: 1q2w3e4r + driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: - ddl-auto: create-drop + ddl-auto: update show-sql: true + properties: + hibernate: + dialect: org.hibernate.dialect.MySQL5InnoDBDialect + format_sql: true springdoc: swagger-ui: @@ -25,4 +26,13 @@ springdoc: default-consumes-media-type: application/json default-produces-media-type: application/json paths-to-match: - - /stockholm/** \ No newline at end of file + - /stockholm/** + +token: + app-key: "PSjMh9iyz0EFvbpWkvuYHfLiFuHyNAtLoG9h" + app-secret: "vtzv7bG78qgtThPEujr1MWDJHKTawSoEDRfAJzB/lYvwj67HdzUsyUavVGD4kORIeGS5q6BJBwoICXy97h8d3RaSAvhK03Yu/seFm0t+22ZQBv4GKhxvU5jGwdMrsucyKuQ0EtXfkJxJoLFsqIO1UA1n3r4HX0D5RxIe8I8efwEYVbidAn4=" + +stock-url: + token: "https://openapi.koreainvestment.com:9443/oauth2/tokenP" + stockasbi: "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-asking-price-exp-ccn" + stockhour: "https://openapi.koreainvestment.com:9443/uapi/domestic-stock/v1/quotations/inquire-time-itemchartprice" From a1a772e6bdbb2d0e364efb2975be689f2a8b8d2a Mon Sep 17 00:00:00 2001 From: rkddnr Date: Thu, 31 Aug 2023 16:36:26 +0900 Subject: [PATCH 12/83] =?UTF-8?q?Feat:=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issues #4 --- .idea/compiler.xml | 3 +- .idea/gradle.xml | 1 + server/008main_project/build.gradle | 10 ++- .../auth/mail/AccountController.java | 39 +++++++++ .../auth/mail/Dto/ConfirmPostDto.java | 11 +++ .../auth/mail/Dto/SendEmailPostDto.java | 19 +++++ .../main_project/auth/mail/EmailConfig.java | 55 ++++++++++++ .../main_project/auth/mail/EmailService.java | 5 ++ .../auth/mail/EmailServiceImpl.java | 85 +++++++++++++++++++ .../member/controller/MemberController.java | 5 +- .../member/dto/MemberPostDto.java | 21 ++++- .../main_project/member/entity/Member.java | 5 +- .../member/mapper/MemberMapper.java | 6 +- .../member/service/MemberService.java | 16 ++++ .../src/main/resources/application.yml | 11 +++ .../main/resources/stockholmMail.properties | 10 +++ 16 files changed, 287 insertions(+), 15 deletions(-) create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/mail/AccountController.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/mail/Dto/ConfirmPostDto.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/mail/Dto/SendEmailPostDto.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/mail/EmailConfig.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/mail/EmailService.java create mode 100644 server/008main_project/src/main/java/com/stockholm/main_project/auth/mail/EmailServiceImpl.java create mode 100644 server/008main_project/src/main/resources/stockholmMail.properties diff --git a/.idea/compiler.xml b/.idea/compiler.xml index ab2110df..ab5befe4 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -2,11 +2,12 @@ + - + diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 2a89c9f4..e1895728 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,5 +1,6 @@ +