-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #261 from ASAP-as-soon-as-possible/develop
release 1.0.4
- Loading branch information
Showing
19 changed files
with
394 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,25 +16,34 @@ permissions: | |
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
node-version: [18.x, 20.x] | ||
redis-version: [6, 7] | ||
|
||
steps: | ||
- name: Setup MySQL | ||
uses: samin/mysql-action@v1 | ||
uses: mirromutth/mysql-action@v1 | ||
with: | ||
character set server: 'utf8' | ||
mysql database: 'asap_dev' | ||
mysql user: 'asap_dev_admin' | ||
mysql password: ${{ secrets.DatabasePassword }} | ||
|
||
mysql root password: 'asap' | ||
mysql user: 'asap' | ||
mysql password: 'asap' | ||
host port: 3306 | ||
container port: 3306 | ||
|
||
- name: Set up redis | ||
uses: supercharge/[email protected] | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
|
||
- uses: actions/checkout@v3 | ||
- name: Set up JDK 17 | ||
uses: actions/setup-java@v3 | ||
with: | ||
java-version: '17' | ||
distribution: 'temurin' | ||
|
||
- name: make application.properties 파일 생성 | ||
run: | | ||
## create application.yml | ||
|
@@ -51,10 +60,16 @@ jobs: | |
# application.yml 파일 확인 | ||
cat ./application.yml | ||
shell: bash | ||
|
||
# 이 워크플로우는 gradle build | ||
- name: Grant execute permission for gradlew | ||
run: chmod +x gradlew | ||
|
||
|
||
- name: Wait for MySQL | ||
run: | | ||
while ! mysqladmin ping --host=127.0.0.1 --password='asap' --silent; do | ||
sleep 1 | ||
done | ||
- name: Build with Gradle # 실제 application build | ||
run: ./gradlew build -PactiveProfiles=local | ||
run: ./gradlew clean --stacktrace --info build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,4 +36,6 @@ output/ | |
*.log | ||
*.log.gz | ||
*.log-*.gz | ||
logs/ | ||
logs/ | ||
|
||
/src/main/resources/application.yml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
src/main/java/com/asap/server/common/filter/CustomHttpServletRequestWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package com.asap.server.common.filter; | ||
|
||
import jakarta.servlet.ReadListener; | ||
import jakarta.servlet.ServletInputStream; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletRequestWrapper; | ||
import lombok.Getter; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.ByteArrayInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStreamReader; | ||
import java.nio.charset.StandardCharsets; | ||
|
||
@Getter | ||
public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper { | ||
private final String body; | ||
|
||
public CustomHttpServletRequestWrapper(HttpServletRequest request) throws IOException { | ||
super(request); | ||
this.body = readBody(request); | ||
} | ||
|
||
@Override | ||
public ServletInputStream getInputStream() { | ||
ByteArrayInputStream byteInputStream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)); | ||
return new ServletInputStream() { | ||
@Override | ||
public boolean isFinished() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public boolean isReady() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public void setReadListener(ReadListener readListener) { | ||
|
||
} | ||
|
||
@Override | ||
public int read() throws IOException { | ||
return byteInputStream.read(); | ||
} | ||
}; | ||
} | ||
|
||
private String readBody(HttpServletRequest request) throws IOException { | ||
BufferedReader input = new BufferedReader(new InputStreamReader(request.getInputStream())); | ||
StringBuilder sb = new StringBuilder(); | ||
|
||
var line = input.readLine(); | ||
while (line != null) { | ||
sb.append(line.trim()); | ||
line = input.readLine(); | ||
} | ||
return sb.toString(); | ||
} | ||
} |
26 changes: 9 additions & 17 deletions
26
src/main/java/com/asap/server/common/filter/CustomServletWrappingFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,19 @@ | ||
package com.asap.server.common.filter; | ||
|
||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.filter.OncePerRequestFilter; | ||
import org.springframework.web.util.ContentCachingRequestWrapper; | ||
import org.springframework.web.util.ContentCachingResponseWrapper; | ||
|
||
import jakarta.servlet.Filter; | ||
import jakarta.servlet.FilterChain; | ||
import jakarta.servlet.ServletException; | ||
import jakarta.servlet.ServletRequest; | ||
import jakarta.servlet.ServletResponse; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
|
||
@Component | ||
public class CustomServletWrappingFilter extends OncePerRequestFilter { | ||
@Override | ||
protected void doFilterInternal(final HttpServletRequest request, | ||
final HttpServletResponse response, | ||
final FilterChain chain) throws ServletException, IOException { | ||
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request); | ||
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response); | ||
import java.io.IOException; | ||
|
||
chain.doFilter(requestWrapper, responseWrapper); | ||
public class CustomServletWrappingFilter implements Filter { | ||
|
||
responseWrapper.copyBodyToResponse(); | ||
@Override | ||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { | ||
HttpServletRequest request = new CustomHttpServletRequestWrapper((HttpServletRequest) servletRequest); | ||
filterChain.doFilter(request, servletResponse); | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
src/main/java/com/asap/server/common/interceptor/DuplicatedInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package com.asap.server.common.interceptor; | ||
|
||
|
||
import com.asap.server.common.filter.CustomHttpServletRequestWrapper; | ||
import com.asap.server.exception.Error; | ||
import com.asap.server.exception.model.TooManyRequestException; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import lombok.RequiredArgsConstructor; | ||
import org.redisson.api.RMap; | ||
import org.redisson.api.RedissonClient; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.servlet.HandlerInterceptor; | ||
import org.springframework.web.servlet.ModelAndView; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class DuplicatedInterceptor implements HandlerInterceptor { | ||
private static final String REDIS_KEY = "ASAP_REDIS"; | ||
private static final String RMAP_VALUE = "ASAP"; | ||
private static final String RMAP_KEY_FORMAT = "LOCK [ ip : %s , body : %s ]"; | ||
private static final String USER_IP_HEADER = "x-real-ip"; | ||
private final RedissonClient redissonClient; | ||
|
||
@Override | ||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { | ||
if (lock(request)) return true; | ||
throw new TooManyRequestException(Error.TOO_MANY_REQUEST_EXCEPTION); | ||
} | ||
|
||
@Override | ||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { | ||
unLock(request); | ||
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); | ||
} | ||
|
||
@Override | ||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { | ||
unLock(request); | ||
HandlerInterceptor.super.afterCompletion(request, response, handler, ex); | ||
} | ||
|
||
private String getRmapKey(HttpServletRequest request) { | ||
final String body = ((CustomHttpServletRequestWrapper) request).getBody(); | ||
final String userIp = request.getHeader(USER_IP_HEADER); | ||
return String.format(RMAP_KEY_FORMAT, userIp, body); | ||
} | ||
|
||
private boolean lock(HttpServletRequest request) { | ||
final String rmapKey = getRmapKey(request); | ||
RMap<String, String> redissonClientMap = redissonClient.getMap(REDIS_KEY); | ||
return redissonClientMap.putIfAbsent(rmapKey, RMAP_VALUE) == null; | ||
} | ||
|
||
private void unLock(HttpServletRequest request) { | ||
final String rmapKey = getRmapKey(request); | ||
RMap<String, String> redissonClientMap = redissonClient.getMap(REDIS_KEY); | ||
redissonClientMap.remove(rmapKey); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.