Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Develop #119

Merged
merged 8 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions jenkins/Jenkinsfile-dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
pipeline {
agent any

tools {
jdk 'JDK21'
}

environment {
DOCKERHUB_CREDENTIALS = credentials('dockerhub-credentials-id')
DOCKER_IMAGE = credentials('docker-image-dev')
K8S_URL = credentials('k8s-url')
K8S_NAMESPACE = credentials('k8s-namespace')
K8S_DEPLOY_NAME = credentials('k8s-deploy-name-dev')
JAVA_HOME = "${tool 'JDK21'}"
PATH = "${env.JAVA_HOME}/bin:${env.PATH}"
}

stages {
stage('Checkout') {
steps {
checkout scm
}
}

stage('Build & Test') {
steps {
script {
sh 'mkdir -p $WORKSPACE/src/main/resources/static/docs && touch $WORKSPACE/src/main/resources/static/docs/open-api-3.0.1.json'
sh './gradlew clean build -x test'
sh './gradlew openapi3'
}
}
post {
failure {
error 'Deployment failed!'
}
}
}

stage('Login'){
steps{
sh 'echo $DOCKERHUB_CREDENTIALS_PSW | docker login -u $DOCKERHUB_CREDENTIALS_USR --password-stdin' // docker hub 둜그인
}
}

stage('Build & Push Docker Image') {
steps {
script {
sh 'docker buildx build --push --platform linux/amd64 --build-arg PROFILE=dev -t $DOCKER_IMAGE .'
}
}
}

stage('ssh-test') {
steps{
script{
sshagent (credentials: ['ncp-key']) {
sh """
ssh -o StrictHostKeyChecking=no ${K8S_URL} << EOF
microk8s kubectl rollout restart deploy ${K8S_DEPLOY_NAME} -n=${K8S_NAMESPACE}
"""
}
}
}
}

}

post {
success {
echo 'Deployment was successful!'
}
failure {
error 'Deployment failed!'
}
}
}
6 changes: 3 additions & 3 deletions Jenkinsfile β†’ jenkins/Jenkinsfile-prod
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ pipeline {

environment {
DOCKERHUB_CREDENTIALS = credentials('dockerhub-credentials-id')
DOCKER_IMAGE = credentials('docker-image')
DOCKER_IMAGE = credentials('docker-image-prod')
K8S_URL = credentials('k8s-url')
K8S_NAMESPACE = credentials('k8s-namespace')
K8S_DEPLOY_NAME = credentials('k8s-deploy-name')
K8S_DEPLOY_NAME = credentials('k8s-deploy-name-prod')
JAVA_HOME = "${tool 'JDK21'}"
PATH = "${env.JAVA_HOME}/bin:${env.PATH}"
}
Expand All @@ -26,7 +26,7 @@ pipeline {
steps {
script {
sh 'mkdir -p $WORKSPACE/src/main/resources/static/docs && touch $WORKSPACE/src/main/resources/static/docs/open-api-3.0.1.json'
sh './gradlew clean build'
sh './gradlew clean build -x test'
sh './gradlew openapi3'
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.server.bbo_gak.domain.card.controller;

import com.server.bbo_gak.domain.card.dto.response.CardSearchByTagListResponse;
import com.server.bbo_gak.domain.card.dto.response.TagGetResponse;
import com.server.bbo_gak.domain.card.service.CardSearchService;
import com.server.bbo_gak.domain.user.entity.User;
import com.server.bbo_gak.global.annotation.AuthUser;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1")
@RequiredArgsConstructor
public class CardSearchController {

private final CardSearchService cardSearchService;

@GetMapping("/search/cards")
public ResponseEntity<List<CardSearchByTagListResponse>> searchCardByTagList(
@AuthUser User user,
@RequestParam(value = "card-type-value-group", required = false) String cardTypeValueGroup,
@RequestParam(value = "tag-ids") List<Long> tagIdList) {
return ResponseEntity.ok(cardSearchService.searchCardByTagList(user, cardTypeValueGroup, tagIdList));
}

@GetMapping("/search/card-tag-history")
public ResponseEntity<List<TagGetResponse>> getCardTagSearchHistory(@AuthUser User user) {
return ResponseEntity.ok(cardSearchService.getCardTagSearchHistoryList(user));
}
}
17 changes: 3 additions & 14 deletions src/main/java/com/server/bbo_gak/domain/card/dao/CardDao.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.server.bbo_gak.domain.card.dao;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.server.bbo_gak.domain.card.entity.Card;
import com.server.bbo_gak.domain.card.entity.CardTypeValue;
Expand Down Expand Up @@ -28,8 +27,9 @@ public List<Card> findAllByUserIdAndCardTypeValueList(User user, CardTypeValue[]
return query.selectFrom(qCard)
.leftJoin(qCard.cardTypeList, qCardType).fetchJoin()
.where(qCard.user.id.eq(user.getId())
.and(cardTypeValueList.length == 0 ? null : qCardType.cardTypeValue.in(cardTypeValueList))
.and(qCardType.cardTypeValue.in(cardTypeValueList))
.and(createRecruitBooleanBuilder(qCard, recruitId)))
.and(recruitId == null ? null : qCard.recruit.id.eq(recruitId)))
.distinct()
.fetch();
}
Expand All @@ -43,20 +43,9 @@ public List<Card> findAllByUserIdAndCardTypeValue(User user, CardTypeValue cardT
.leftJoin(qCard.cardTypeList, qCardType).fetchJoin()
.where(qCard.user.id.eq(user.getId())
.and(qCardType.cardTypeValue.eq(cardTypeValue))
.and(createRecruitBooleanBuilder(qCard, recruitId))
.and(recruitId == null ? null : qCard.recruit.id.eq(recruitId))
)
.distinct()
.fetch();
}

private BooleanBuilder createRecruitBooleanBuilder(QCard qCard, Long recruitId) {

BooleanBuilder builder = new BooleanBuilder();

if (recruitId == null) {
return null;
}

return builder.and(qCard.recruit.id.eq(recruitId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.server.bbo_gak.domain.card.dao;

import com.server.bbo_gak.domain.card.entity.CardTagSearchHistory;
import com.server.bbo_gak.domain.user.entity.User;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CardTagSearchHistoryRepository extends JpaRepository<CardTagSearchHistory, Long> {

List<CardTagSearchHistory> findTop10ByUserOrderByCreatedDate(User user);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.server.bbo_gak.domain.card.dto.request;

import com.server.bbo_gak.domain.card.entity.CardTypeValue;
import com.server.bbo_gak.domain.card.entity.CardTypeValueGroup;
import jakarta.annotation.Nullable;
import jakarta.validation.constraints.Size;
import java.util.List;
import java.util.Optional;

public record CardSearchByTagListRequest(

@Size(min = 1)
List<Long> tagIdList,

@Nullable
String cardTypeValueGroup
) {

public CardTypeValue[] getCardTypeValueList() {
return Optional.ofNullable(cardTypeValueGroup)
.map(cardTypeValueGroup -> CardTypeValueGroup.findByValue(cardTypeValueGroup).getCardTypeValueList())
.orElseGet(() -> new CardTypeValue[0]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.server.bbo_gak.domain.card.dto.response;

import com.server.bbo_gak.domain.card.entity.Card;
import com.server.bbo_gak.domain.card.entity.CardTypeValue;
import com.server.bbo_gak.domain.card.entity.CardTypeValueGroup;
import com.server.bbo_gak.domain.recruit.entity.Recruit;
import com.server.bbo_gak.global.utils.BaseDateTimeFormatter;
import java.util.List;
import java.util.Optional;
import lombok.AccessLevel;
import lombok.Builder;

@Builder(access = AccessLevel.PRIVATE)
public record CardSearchByTagListResponse(
Long id,
String title,
String updatedDate,
List<TagGetResponse> tagList,
String cardTypeValueGroup,
String cardTypeValue,
String recruitTitle,
String content
) {

public static CardSearchByTagListResponse from(Card card) {

CardTypeValue cardTypeValue = card.getCardTypeList().getFirst().getCardTypeValue();

return CardSearchByTagListResponse.builder()
.id(card.getId())
.title(card.getTitle())
.updatedDate(card.getUpdatedDate().format(BaseDateTimeFormatter.getLocalDateTimeFormatter()))
.tagList(
card.getCardTagList().stream()
.map(cardTag -> TagGetResponse.from(cardTag.getTag()))
.toList()
)
.cardTypeValueGroup(CardTypeValueGroup.findByCardTypeValue(cardTypeValue).getValue())
.recruitTitle(Optional.ofNullable(card.getRecruit()).map(Recruit::getTitle).orElse(null))
.cardTypeValue(cardTypeValue.getValue())
.content(card.getContent())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.server.bbo_gak.domain.card.entity;

import com.server.bbo_gak.domain.user.entity.User;
import com.server.bbo_gak.global.common.BaseEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLRestriction;

@Getter
@Entity
@SQLRestriction("deleted = false")
@SQLDelete(sql = "UPDATE card_tag_search_history SET deleted = true WHERE card_tag_search_history_id = ?")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class CardTagSearchHistory extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "card_tag_search_history_id")
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "tag_id")
private Tag tag;

public CardTagSearchHistory(User user, Tag tag) {
this.user = user;
this.tag = tag;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.server.bbo_gak.domain.card.service;

import com.server.bbo_gak.domain.card.dao.CardDao;
import com.server.bbo_gak.domain.card.dao.CardTagSearchHistoryRepository;
import com.server.bbo_gak.domain.card.dao.TagRepository;
import com.server.bbo_gak.domain.card.dto.response.CardSearchByTagListResponse;
import com.server.bbo_gak.domain.card.dto.response.TagGetResponse;
import com.server.bbo_gak.domain.card.entity.Card;
import com.server.bbo_gak.domain.card.entity.CardTagSearchHistory;
import com.server.bbo_gak.domain.card.entity.CardTypeValue;
import com.server.bbo_gak.domain.card.entity.CardTypeValueGroup;
import com.server.bbo_gak.domain.card.entity.Tag;
import com.server.bbo_gak.domain.user.entity.User;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class CardSearchService {

private final CardTagSearchHistoryRepository cardTagSearchHistoryRepository;
private final TagRepository tagRepository;
private final CardDao cardDao;

@Transactional
public List<CardSearchByTagListResponse> searchCardByTagList(User user, String cardTypeValueGroup,
List<Long> tagIdList) {

List<Tag> tagList = tagRepository.findAllById(tagIdList);

List<Card> cards = cardDao.findAllByUserIdAndCardTypeValueList(user, getCardTypeValueList(cardTypeValueGroup),
null);

cardTagSearchHistoryRepository.saveAll(tagList.stream()
.map(tag -> new CardTagSearchHistory(user, tag))
.toList());

// TODO 필터링 둜직 λ””λΉ„λ‘œ κ°€κ²Œ ν•˜κΈ°
return cards.stream()
.filter(card -> tagList.isEmpty() || card.isTagListContain(tagList))
.sorted(Comparator.comparing(Card::getUpdatedDate).reversed())
.map(CardSearchByTagListResponse::from)
.collect(Collectors.toList());
}

@Transactional(readOnly = true)
public List<TagGetResponse> getCardTagSearchHistoryList(User user) {
return cardTagSearchHistoryRepository.findTop10ByUserOrderByCreatedDate(user).stream()
.map(cardTagSearchHistory -> TagGetResponse.from(cardTagSearchHistory.getTag()))
.toList();
}

private CardTypeValue[] getCardTypeValueList(String cardTypeValueGroupInput) {
return Optional.ofNullable(cardTypeValueGroupInput)
.map(cardTypeValueGroup -> CardTypeValueGroup.findByValue(cardTypeValueGroup).getCardTypeValueList())
.orElseGet(() -> new CardTypeValue[0]);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,9 @@ public List<CardListGetResponse> getCardList(User user, String cardTypeValue, Li
List<Card> cards = cardDao.findAllByUserIdAndCardTypeValue(user, CardTypeValue.findByValue(cardTypeValue),
null);

// TODO 필터링 둜직 λ””λΉ„λ‘œ κ°€κ²Œ ν•˜κΈ°
return cards.stream()
.filter(card -> {

if (tagList.isEmpty()) {
return true;
}

return card.isTagListContain(tagList);
})
.filter(card -> tagList.isEmpty() || card.isTagListContain(tagList))
.sorted(Comparator.comparing(Card::getUpdatedDate).reversed())
.map(card -> CardListGetResponse.of(card, card.getCardTagList()))
.collect(Collectors.toList());
Expand Down
Loading
Loading