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

Feature 150/short url logging #152

Merged
merged 3 commits into from
Dec 9, 2021
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
2 changes: 2 additions & 0 deletions src/main/java/com/daangn/survey/SurveyApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@EnableAsync
@RestController
@SpringBootApplication
@EnableJpaAuditing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.daangn.survey.common.util.shorturl.component.UrlConvertService;
import com.daangn.survey.common.util.shorturl.model.dto.ShortUrlResponse;
import com.daangn.survey.common.util.shorturl.model.dto.ShortUrlResult;
import com.daangn.survey.core.log.annotation.UserLogging;
import com.daangn.survey.core.log.model.LogType;
import com.daangn.survey.third.karrot.KarrotApiUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
Expand All @@ -13,13 +15,17 @@
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

@Tag(name = "단축 URL")
@Slf4j
@Controller
@RequiredArgsConstructor
public class UrlController {
Expand All @@ -33,15 +39,9 @@ public class UrlController {
@Value("${mudda.short-url}")
private String shortUrl;

// 이거 안 사용할 거 같은데 아닌가?
@GetMapping("/daangn/short-url/convert")
@ResponseBody
public ShortUrlResult convertShortUrl(@RequestParam(defaultValue = "") String urlStr) {
return urlConverter.getShortenUrl(urlStr.trim(), null);
}

@UserLogging(type = LogType.SHORT_URL)
@GetMapping("/scheme/redirect")
public String redirectToOriginUrl(@RequestParam String url) {
public String redirectToOriginUrl(@RequestParam String url, HttpServletRequest request) {

return "redirect:" + urlConverter.getShortenUrl(url.trim(), null).getShortUrl().getSchemeUrl();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,11 @@ public void addReqCount(){
public void setShortUrl(String url){
this.shortUrl = url;
}

public Long resolveSurveyId(){
int startIndex = this.originUrl.lastIndexOf('/');
int lastIndex = this.originUrl.lastIndexOf('?');

return Long.parseLong(this.originUrl.substring(startIndex + 1, lastIndex));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
public interface UrlRepository extends JpaRepository<ShortUrl, Long> {
ShortUrl findFirstByShortUrlOrOriginUrlOrderByCreatedAt(String shortUrl, String originUrl);
boolean existsByShortUrlOrOriginUrl(String shortUrl, String originUrl);
ShortUrl findShortUrlByShortUrl(String shortUrl);
}
56 changes: 56 additions & 0 deletions src/main/java/com/daangn/survey/core/aop/LogEventAspect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.daangn.survey.core.aop;

import com.daangn.survey.core.log.annotation.UserLogging;
import com.daangn.survey.core.log.model.LogEvent;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@Component
@Aspect
public class LogEventAspect implements ApplicationEventPublisherAware {
private ApplicationEventPublisher eventPublisher;

@Pointcut("@annotation(userLogging)")
public void pointcut(UserLogging userLogging) {
}

@AfterReturning(pointcut = "pointcut(userLogging)")
public void afterReturning(JoinPoint joinPoint, UserLogging userLogging){

switch (userLogging.type()){
case SHORT_URL:
String referer = null;
String userAgent = null;
String url = null;

for(Object arg : joinPoint.getArgs()){
if(arg instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) arg;
referer = request.getHeader("referer");
userAgent = request.getHeader("user-agent");
}
if(arg instanceof String){
url = (String) arg;
}
}

eventPublisher.publishEvent(new LogEvent(url, userAgent, referer));
break;

}
}

@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.eventPublisher = applicationEventPublisher;
}
}
15 changes: 15 additions & 0 deletions src/main/java/com/daangn/survey/core/log/LogRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.daangn.survey.core.log;

import lombok.RequiredArgsConstructor;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;

@RequiredArgsConstructor
@Repository
public class LogRepository {
private final MongoTemplate mongoTemplate;

public void saveUserLog(Object log){
mongoTemplate.save(log);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.daangn.survey.core.log.annotation;

import com.daangn.survey.core.log.model.LogType;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLogging {
LogType type();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.daangn.survey.core.log.component;

import com.daangn.survey.common.util.shorturl.model.entity.ShortUrl;
import com.daangn.survey.common.util.shorturl.repository.UrlRepository;
import com.daangn.survey.core.log.LogRepository;
import com.daangn.survey.core.log.model.LogEvent;
import com.daangn.survey.core.log.model.ShortUrlLog;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

@RequiredArgsConstructor
@Component
public class LogEventHandler {

private final LogRepository logRepository;
private final UrlRepository urlRepository;

@Async
@EventListener
public void log(LogEvent event) {
ShortUrl shortUrl = urlRepository.findShortUrlByShortUrl(event.getUrl());

logRepository.saveUserLog(new ShortUrlLog(
shortUrl.resolveSurveyId(),
event.getUrl(),
event.getUserAgent(),
event.getReferer()
));
}
}
12 changes: 12 additions & 0 deletions src/main/java/com/daangn/survey/core/log/model/LogEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.daangn.survey.core.log.model;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class LogEvent {
private String url;
private String userAgent;
private String referer;
}
13 changes: 13 additions & 0 deletions src/main/java/com/daangn/survey/core/log/model/LogType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.daangn.survey.core.log.model;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public enum LogType {
SHORT_URL("ShortUrl"),
;

private String type;
}
29 changes: 29 additions & 0 deletions src/main/java/com/daangn/survey/core/log/model/ShortUrlLog.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.daangn.survey.core.log.model;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.mongodb.core.mapping.Document;

import javax.persistence.EnumType;
import javax.persistence.Enumerated;

@AllArgsConstructor
@Getter @Setter
@Document(collection = "userLogs")
public class ShortUrlLog {
@Enumerated(EnumType.STRING)
private LogType logType;
private Long surveyId;
private String url;
private String userAgent;
private String referer;

public ShortUrlLog(Long surveyId, String url, String userAgent, String referer) {
this.logType = LogType.SHORT_URL;
this.surveyId = surveyId;
this.url = url;
this.userAgent = userAgent;
this.referer = referer;
}
}
3 changes: 1 addition & 2 deletions src/main/java/com/daangn/survey/mongo/MongoRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import com.daangn.survey.mongo.aggregate.AggregationAnswerMongo;
import com.daangn.survey.mongo.aggregate.AggregationQuestionMongo;
import com.daangn.survey.mongo.aggregate.SurveyResponseCountMongo;
import com.daangn.survey.mongo.aggregate.AggregationResponseSetMongo;
import com.daangn.survey.mongo.aggregate.SurveyResponseCountMongo;
import com.daangn.survey.mongo.aggregate.individual.IndividualResponseMongo;
import com.daangn.survey.mongo.response.ResponseMongo;
import com.daangn.survey.mongo.survey.SurveyMongo;
Expand All @@ -18,7 +18,6 @@
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Repository;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
Expand Down