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

✨ API 수정 및 Continuous Deployment script 추가 #88

Merged
merged 21 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4de123c
hotfix: #86 모든 일정 조회에 참여 반려동물 리스트 정보 추가
psychology50 Jan 24, 2024
84aacd4
feat: Continuous Deployment script 추가
psychology50 Jan 25, 2024
3e84298
feat: Server SSH 연결 설정 추가
psychology50 Jan 25, 2024
db357a9
feat: appleboy 버전 수정
psychology50 Jan 25, 2024
17efda6
fix: gradlew 권한 수정
psychology50 Jan 25, 2024
360a569
fix: ncp directory path 생성
psychology50 Jan 25, 2024
767686a
fix: ncloud 명령 실행 전에 디렉토리 이동
psychology50 Jan 25, 2024
0cd9357
test: 실행 경로 추적
psychology50 Jan 25, 2024
546c44e
fix: 이동 경로 수정
psychology50 Jan 25, 2024
60d83b0
fix: ncloud 실행 권한 변경
psychology50 Jan 25, 2024
d7ca2de
fix: ncloud 하위 디렉토리 모두 실행권한 수정
psychology50 Jan 25, 2024
9b315ac
fix: ncloud 하위 디렉토리 모든 권한 허용
psychology50 Jan 25, 2024
0507196
fix: 권한 설정 디렉토리 변경
psychology50 Jan 25, 2024
6daf835
fix: ncloud config 경로 수정
psychology50 Jan 25, 2024
8d79e5f
test: home 경로 찾기
psychology50 Jan 25, 2024
db72158
fix: ip block subnet mask 추가
psychology50 Jan 25, 2024
e2cc7c5
fix: ssh 접속 시 password 제거 -> pem key로 인증
psychology50 Jan 25, 2024
174d87b
fix: ssh action 변경
psychology50 Jan 25, 2024
d35d1e6
fix: server openssh 인증 허용
psychology50 Jan 25, 2024
23eea6d
fix: pem key 인증 이슈로 인해 임시 pw 인증 방식으로 변경
psychology50 Jan 25, 2024
64fb272
fix: dev 브랜치 병합 전, hotfix 브랜치 trigger 제거
psychology50 Jan 25, 2024
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
85 changes: 85 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Continuous Deployment

on:
push:
branches: ["develop"]
workflow_dispatch:
inputs:
logLevel:
description: "Log level"
required: true
default: "warning"
type: choice
options:
- info
- warning
- error
environment:
description: "Environment"
required: false
type: environment

permissions:
contents: read

jobs:
continuous-deployment:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'adopt'
cache: 'gradle'

- name: Build Gradle
run: |
chmod +x ./gradlew
./gradlew -version
./gradlew bootJar
shell: bash

- name: docker image build & push
run: |
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
docker build -t ${{ secrets.DOCKER_NICKNAME }}/fitapet:latest .
docker push ${{ secrets.DOCKER_NICKNAME }}/fitapet:latest

- name: Get Github Actions IP
id: ip
uses: haythem/[email protected]

- name: Setting NCP CLI & Credentials
run: |
cd ~
wget https://www.ncloud.com/api/support/download/5/65
unzip 65
mkdir ~/.ncloud
echo -e "[DEFAULT]\nncloud_access_key_id = ${{ secrets.NCP_ACCESS_KEY }}\nncloud_secret_access_key = ${{ secrets.NCP_SECRET_KEY }}\nncloud_api_url = ${{ secrets.NCP_API_URL }}" >> ~/.ncloud/configure

- name: Add Github Action Ip to Security group
run: |
chmod -R 777 ~/cli_linux
cd ~/cli_linux
./ncloud vserver addAccessControlGroupInboundRule --regionCode KR --vpcNo ${{ secrets.NCP_VPC_NO }} --accessControlGroupNo ${{ secrets.NCP_AGC_NO }} --accessControlGroupRuleList "protocolTypeCode='TCP', ipBlock='${{ steps.ip.outputs.ipv4 }}/32', portRange='${{ secrets.SSH_PORT }}'"

- name: deploy
uses: appleboy/[email protected]
with:
host: ${{ secrets.SSH_HOST }}
port: ${{ secrets.SSH_PORT }}
password: ${{ secrets.SSH_PASSWORD }}
username: ${{ secrets.SSH_USERNAME }}
script: |
./start.sh

- name: Remove Github Action Ip to Security group
run: |
chmod -R 777 ~/cli_linux
cd ~/cli_linux
./ncloud vserver removeAccessControlGroupInboundRule --regionCode KR --vpcNo ${{ secrets.NCP_VPC_NO }} --accessControlGroupNo ${{ secrets.NCP_AGC_NO }} --accessControlGroupRuleList "protocolTypeCode='TCP', ipBlock='${{ steps.ip.outputs.ipv4 }}/32', portRange='${{ secrets.SSH_PORT }}'"
2 changes: 1 addition & 1 deletion .github/workflows/kakao_ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: BE CI
name: BE Kakao Chat CI
run-name: Deploy by @${{ github.actor }}

on:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public ResponseEntity<?> saveSchedule(
public ResponseEntity<?> getPetSchedules(
@PathVariable("user_id") Long userId,
@PathVariable("pet_id") Long petId,
@RequestParam(value = "count", required = false) Integer count
@RequestParam(value = "count", required = false, defaultValue = "-1") int count
) {
return ResponseEntity.ok(SuccessResponse.from("schedules", scheduleManageService.findPetSchedules(petId, count).getSchedules()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
package com.kcy.fitapet.domain.schedule.dao;

import com.kcy.fitapet.domain.schedule.domain.Schedule;
import com.kcy.fitapet.domain.schedule.dto.ScheduleInfoDto;

import java.time.LocalDateTime;
import java.util.List;

public interface ScheduleQueryRepository {
List<Schedule> findScheduleByPetIdOnDate(Long petId, LocalDateTime date);
List<Schedule> findTopCountSchedulesByIdOnDate(Long id, LocalDateTime scheduleDate, Integer count);
/**
* pet_id로 반려동물이 등록된 해당 날짜의 schedule_id 리스트 조회
* @param petId
* @param date : 탐색할 날짜, 만약 지금 시간 이후의 스케줄을 조회하고 싶다면 LocalDateTime.now()를 넣어주면 된다. (전체라면 LocalDate.startOf())
*/
List<Long> findScheduleIds(Long petId, LocalDateTime date);

/**
* pet_id로 반려동물이 등록된 해당 날짜의 schedule_id 리스트를 count 만큼 조회 <br/>
*/
List<Long> findScheduleIds(Long petId, LocalDateTime date, int count);

/**
* schedule_id로 스케줄 및 참여 반려동물 리스트 조회
*/
List<ScheduleInfoDto.ScheduleInfo> findSchedulesByIds(List<Long> scheduleIds);

/**
* 해당 날짜의 스케줄 및 참여 반려동물들 리스트 조회
*/
List<ScheduleInfoDto.ScheduleInfo> findSchedulesByCalender(LocalDateTime date, List<Long> petIds);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
import com.kcy.fitapet.domain.schedule.domain.QSchedule;
import com.kcy.fitapet.domain.schedule.domain.Schedule;
import com.kcy.fitapet.domain.schedule.dto.ScheduleInfoDto;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.ResultTransformer;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

Expand All @@ -28,35 +29,49 @@ public class ScheduleQueryRepositoryImpl implements ScheduleQueryRepository {
private final QPet pet = QPet.pet;

@Override
public List<Schedule> findScheduleByPetIdOnDate(Long petId, LocalDateTime date) {
return queryFactory.selectFrom(schedule)
.innerJoin(petSchedule).on(schedule.id.eq(petSchedule.schedule.id))
public List<Long> findScheduleIds(Long petId, LocalDateTime date) {
return queryFactory.select(schedule.id)
.from(petSchedule)
.innerJoin(schedule).on(schedule.id.eq(petSchedule.schedule.id))
.where(petSchedule.pet.id.eq(petId)
.and(schedule.reservationDt.between(
Expressions.asDateTime(date.withHour(0).withMinute(0).withSecond(0)),
Expressions.asDateTime(date),
Expressions.asDateTime(date.withHour(23).withMinute(59).withSecond(59))
)))
.orderBy(schedule.reservationDt.asc()).fetch();
.fetch();
}

@Override
public List<Schedule> findTopCountSchedulesByIdOnDate(Long petId, LocalDateTime scheduleDate, Integer count) {
return queryFactory.selectFrom(schedule)
.innerJoin(petSchedule).on(schedule.id.eq(petSchedule.schedule.id))
public List<Long> findScheduleIds(Long petId, LocalDateTime date, int count) {
return queryFactory.select(schedule.id)
.from(petSchedule)
.innerJoin(schedule).on(schedule.id.eq(petSchedule.schedule.id))
.where(petSchedule.pet.id.eq(petId)
.and(schedule.reservationDt.between(
Expressions.asDateTime(scheduleDate),
Expressions.asDateTime(scheduleDate.withHour(23).withMinute(59).withSecond(59))
Expressions.asDateTime(date),
Expressions.asDateTime(date.withHour(23).withMinute(59).withSecond(59))
)))
.orderBy(schedule.reservationDt.asc())
.limit(count)
.fetch();
}

@Override
public List<ScheduleInfoDto.ScheduleInfo> findSchedulesByIds(List<Long> scheduleIds) {
return queryFactory
.select(schedule.id, schedule.scheduleName, schedule.location, schedule.reservationDt, pet.id, pet.petProfileImg)
.from(schedule)
.innerJoin(petSchedule).on(schedule.id.eq(petSchedule.schedule.id))
.innerJoin(pet).on(pet.id.eq(petSchedule.pet.id))
.where(schedule.id.in(scheduleIds))
.orderBy(schedule.reservationDt.asc())
.transform(scheduleInfoResultTransformer());
}

@Override
public List<ScheduleInfoDto.ScheduleInfo> findSchedulesByCalender(LocalDateTime date, List<Long> petIds) {
return queryFactory
.select(schedule.id, schedule.scheduleName, schedule.location, schedule.reservationDt, pet.id)
.select(schedule.id, schedule.scheduleName, schedule.location, schedule.reservationDt, pet.id, pet.petProfileImg)
.from(petSchedule)
.innerJoin(schedule).on(schedule.id.eq(petSchedule.schedule.id))
.innerJoin(petSchedule.pet).on(pet.id.in(petIds))
Expand All @@ -68,23 +83,25 @@ public List<ScheduleInfoDto.ScheduleInfo> findSchedulesByCalender(LocalDateTime
))
)
.orderBy(schedule.reservationDt.asc())
.transform(
groupBy(schedule.id).list(
Projections.constructor(
ScheduleInfoDto.ScheduleInfo.class,
schedule.id,
schedule.scheduleName,
schedule.location,
schedule.reservationDt,
list(
Projections.constructor(
ScheduleInfoDto.ParticipantPetInfo.class,
pet.id,
pet.petProfileImg
)
)
.transform(scheduleInfoResultTransformer());
}

private ResultTransformer<List<ScheduleInfoDto.ScheduleInfo>> scheduleInfoResultTransformer() {
return groupBy(schedule.id).list(
Projections.constructor(
ScheduleInfoDto.ScheduleInfo.class,
schedule.id,
schedule.scheduleName,
schedule.location,
schedule.reservationDt,
list(
Projections.constructor(
ScheduleInfoDto.ParticipantPetInfo.class,
pet.id,
pet.petProfileImg
)
)
)
);
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ public class Schedule extends AuthorAuditable {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "schedule_name")
private String scheduleName;
private String location;

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "reservation_dt")
private LocalDateTime reservationDt;

@Column(name = "schedule_name")
private String scheduleName;
private String location;

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "notify_dt")
private LocalDateTime notifyDt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
Expand All @@ -43,16 +43,13 @@ public void saveSchedule(Long petId, ScheduleSaveDto.Request request) {
}

@Transactional(readOnly = true)
public ScheduleInfoDto findPetSchedules(Long petId, Integer count) {
LocalDateTime now = LocalDateTime.now();
public ScheduleInfoDto findPetSchedules(Long petId, int count) {
LocalDateTime now = (count != -1) ? LocalDateTime.now() : LocalDate.now().atStartOfDay();

List<Schedule> schedules = (count != null)
? scheduleSearchService.findSchedulesAfterNowOnDay(petId, now, count)
: scheduleSearchService.findScheduleByPetIdOnDate(petId, now);
List<Long> scheduleIds = scheduleSearchService.findScheduleIdsByPetIdAfterDateTime(petId, now, count);
log.info("scheduleIds: {}", scheduleIds);

List<ScheduleInfoDto.ScheduleInfo> scheduleInfo = schedules.stream()
.map(schedule -> ScheduleInfoDto.ScheduleInfo.from(schedule, new ArrayList<>())).toList();
return ScheduleInfoDto.of(scheduleInfo);
return ScheduleInfoDto.of(scheduleSearchService.findTopCountSchedulesByIds(scheduleIds));
}

@Transactional(readOnly = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.kcy.fitapet.domain.schedule.dao.ScheduleQueryRepository;
import com.kcy.fitapet.domain.schedule.dao.ScheduleRepository;
import com.kcy.fitapet.domain.schedule.domain.Schedule;
import com.kcy.fitapet.domain.schedule.dto.ScheduleInfoDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -19,22 +18,24 @@ public class ScheduleSearchService {
private final ScheduleRepository scheduleRepository;
private final ScheduleQueryRepository scheduleQueryRepository;

/**
* pet_id로 반려동물이 등록된 해당 날짜의 schedule_id 리스트 조회
* @param petId 반려동물 id
* @param date : 탐색할 날짜, 만약 지금 시간 이후의 스케줄을 조회하고 싶다면 LocalDateTime.now()를 넣어주면 된다. (전체라면 LocalDate.startOf())
* @param count : 조회할 스케줄 개수, -1이면 전체 조회
*/
@Transactional(readOnly = true)
public List<Schedule> findScheduleByPetIdOnDate(Long petId, LocalDateTime date) {
return scheduleQueryRepository.findScheduleByPetIdOnDate(petId, date);
public List<Long> findScheduleIdsByPetIdAfterDateTime(Long petId, LocalDateTime date, int count) {
return (count != -1) ? scheduleQueryRepository.findScheduleIds(petId, date, count)
: scheduleQueryRepository.findScheduleIds(petId, date);
}

/**
* 오늘 날짜의 현재 시간 이후에 해당하는 스케줄 조회
* @param petId 반려동물 id
* @param scheduleDate 조회할 날짜
* @param count 조회할 스케줄 개수
* @return 조회된 스케줄 리스트
* schedule_id로 스케줄 및 참여 반려동물 리스트 조회
*/
// TODO: 현재 시간까지 고려
@Transactional(readOnly = true)
public List<Schedule> findSchedulesAfterNowOnDay(Long petId, LocalDateTime scheduleDate, Integer count) {
return scheduleQueryRepository.findTopCountSchedulesByIdOnDate(petId, scheduleDate, count);
public List<ScheduleInfoDto.ScheduleInfo> findTopCountSchedulesByIds(List<Long> scheduleIds) {
return scheduleQueryRepository.findSchedulesByIds(scheduleIds);
}

@Transactional(readOnly = true)
Expand Down
Loading