mirror of https://github.com/halo-dev/halo
Merge remote-tracking branch 'origin/v1' into v1
commit
e6e880d20a
|
@ -85,7 +85,7 @@ public class HaloConfiguration {
|
|||
|
||||
logFilter.setOrder(Ordered.HIGHEST_PRECEDENCE + 9);
|
||||
logFilter.setFilter(new LogFilter());
|
||||
logFilter.addUrlPatterns("/api/*");
|
||||
logFilter.addUrlPatterns("/*");
|
||||
|
||||
return logFilter;
|
||||
}
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
package run.halo.app.event;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
/**
|
||||
* Event queue dispatcher.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 19-4-20
|
||||
*/
|
||||
@Slf4j
|
||||
@Deprecated
|
||||
public class ApplicationEventQueuePublisher {
|
||||
|
||||
private final BlockingQueue<Object> events = new LinkedBlockingQueue<>();
|
||||
|
||||
private final ApplicationListenerManager listenerManager;
|
||||
|
||||
private final ExecutorService executorService;
|
||||
|
||||
public ApplicationEventQueuePublisher(ApplicationListenerManager listenerManager) {
|
||||
this.listenerManager = listenerManager;
|
||||
this.executorService = Executors.newSingleThreadExecutor();
|
||||
|
||||
executorService.execute(new EventQueueConsumer());
|
||||
}
|
||||
|
||||
public void publishEvent(Object event) {
|
||||
try {
|
||||
events.put(event);
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("Failed to put event to the queue", e);
|
||||
// Ignore this error
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
protected void destroy() {
|
||||
log.info("Shutting down all event queue consumer");
|
||||
this.executorService.shutdownNow();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private class EventQueueConsumer implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
try {
|
||||
// Take an event
|
||||
Object event = events.take();
|
||||
|
||||
// Get listeners
|
||||
List<EventListener> listeners = listenerManager.getListeners(event);
|
||||
|
||||
// Handle the event
|
||||
listeners.forEach(listener -> {
|
||||
if (listener instanceof ApplicationListener && event instanceof ApplicationEvent) {
|
||||
ApplicationEvent applicationEvent = (ApplicationEvent) event;
|
||||
// Fire event
|
||||
((ApplicationListener) listener).onApplicationEvent(applicationEvent);
|
||||
}
|
||||
});
|
||||
|
||||
log.info("Event queue consumer has been shut down");
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("Failed to take event", e);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to handle event", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
package run.halo.app.event;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import run.halo.app.utils.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Application listener manager.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 19-4-21
|
||||
*/
|
||||
@Slf4j
|
||||
@Deprecated
|
||||
public class ApplicationListenerManager {
|
||||
|
||||
/**
|
||||
* Listener Map.
|
||||
*/
|
||||
private final Map<String, List<EventListener>> listenerMap = new ConcurrentHashMap<>();
|
||||
|
||||
public ApplicationListenerManager(ApplicationContext applicationContext) {
|
||||
// TODO Need to refactor
|
||||
// Register all listener on starting up
|
||||
applicationContext.getBeansOfType(ApplicationListener.class).values().forEach(this::register);
|
||||
|
||||
log.debug("Initialized event listeners");
|
||||
}
|
||||
|
||||
public List<EventListener> getListeners(@Nullable Object event) {
|
||||
if (event == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// Get listeners
|
||||
List<EventListener> listeners = listenerMap.get(event.getClass().getTypeName());
|
||||
// Clone the listeners
|
||||
return listeners == null ? Collections.emptyList() : new LinkedList<>(listeners);
|
||||
}
|
||||
|
||||
public synchronized void register(@NonNull ApplicationListener<?> listener) {
|
||||
// Get actual generic type
|
||||
Type actualType = resolveActualGenericType(listener);
|
||||
|
||||
if (actualType == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add this listener
|
||||
listenerMap.computeIfAbsent(actualType.getTypeName(), (key) -> new LinkedList<>()).add(listener);
|
||||
}
|
||||
|
||||
public synchronized void unRegister(@NonNull ApplicationListener<?> listener) {
|
||||
// Get actual generic type
|
||||
Type actualType = resolveActualGenericType(listener);
|
||||
|
||||
if (actualType == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove it from listener map
|
||||
listenerMap.getOrDefault(actualType.getTypeName(), Collections.emptyList()).remove(listener);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Type resolveActualGenericType(@NonNull ApplicationListener<?> listener) {
|
||||
Assert.notNull(listener, "Application listener must not be null");
|
||||
|
||||
log.debug("Attempting to resolve type of Application listener: [{}]", listener);
|
||||
|
||||
ParameterizedType parameterizedType = ReflectionUtils.getParameterizedType(ApplicationListener.class, ((ApplicationListener) listener).getClass());
|
||||
|
||||
return parameterizedType == null ? null : parameterizedType.getActualTypeArguments()[0];
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package run.halo.app.event;
|
||||
package run.halo.app.event.logger;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import run.halo.app.model.enums.LogType;
|
||||
|
@ -17,7 +17,7 @@ public class LogEvent extends ApplicationEvent {
|
|||
* Create a new ApplicationEvent.
|
||||
*
|
||||
* @param source the object on which the event initially occurred (never {@code null})
|
||||
* @param logParam
|
||||
* @param logParam login param
|
||||
*/
|
||||
public LogEvent(Object source, LogParam logParam) {
|
||||
super(source);
|
|
@ -1,4 +1,4 @@
|
|||
package run.halo.app.event;
|
||||
package run.halo.app.event.logger;
|
||||
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
|
@ -1,4 +1,4 @@
|
|||
package run.halo.app.event;
|
||||
package run.halo.app.event.post;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.lang.NonNull;
|
|
@ -1,4 +1,4 @@
|
|||
package run.halo.app.event;
|
||||
package run.halo.app.event.post;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
|
@ -4,6 +4,7 @@ import org.springframework.data.domain.Page;
|
|||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import run.halo.app.model.entity.Category;
|
||||
import run.halo.app.model.entity.Post;
|
||||
import run.halo.app.model.entity.PostCategory;
|
||||
|
@ -103,6 +104,7 @@ public interface PostCategoryService extends CrudService<PostCategory, Integer>
|
|||
* @return a list of post category deleted
|
||||
*/
|
||||
@NonNull
|
||||
@Transactional
|
||||
List<PostCategory> removeByPostId(@NonNull Integer postId);
|
||||
|
||||
/**
|
||||
|
@ -112,5 +114,6 @@ public interface PostCategoryService extends CrudService<PostCategory, Integer>
|
|||
* @return a list of post category deleted
|
||||
*/
|
||||
@NonNull
|
||||
@Transactional
|
||||
List<PostCategory> removeByCategoryId(@NonNull Integer categoryId);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package run.halo.app.service;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import run.halo.app.model.dto.TagWithCountOutputDTO;
|
||||
import run.halo.app.model.entity.Post;
|
||||
import run.halo.app.model.entity.PostTag;
|
||||
|
@ -113,6 +114,7 @@ public interface PostTagService extends CrudService<PostTag, Integer> {
|
|||
* @return a list of post tag
|
||||
*/
|
||||
@NonNull
|
||||
@Transactional
|
||||
List<PostTag> removeByPostId(@NonNull Integer postId);
|
||||
|
||||
/**
|
||||
|
@ -122,5 +124,6 @@ public interface PostTagService extends CrudService<PostTag, Integer> {
|
|||
* @return a list of post tag
|
||||
*/
|
||||
@NonNull
|
||||
@Transactional
|
||||
List<PostTag> removeByTagId(@NonNull Integer tagId);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public interface ThemeService {
|
|||
/**
|
||||
* The type of file that can be modified.
|
||||
*/
|
||||
String[] CAN_EDIT_SUFFIX = {"ftl", "css", "js"};
|
||||
String[] CAN_EDIT_SUFFIX = {".ftl", ".css", ".js", ".yaml", ".yml", ".properties"};
|
||||
|
||||
/**
|
||||
* These file names cannot be displayed.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package run.halo.app.service.base;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import run.halo.app.exception.NotFoundException;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
@ -124,6 +125,7 @@ public interface CrudService<DOMAIN, ID> {
|
|||
* @return DOMAIN
|
||||
*/
|
||||
@NonNull
|
||||
@Transactional
|
||||
DOMAIN create(@NonNull DOMAIN domain);
|
||||
|
||||
/**
|
||||
|
@ -133,6 +135,7 @@ public interface CrudService<DOMAIN, ID> {
|
|||
* @return List
|
||||
*/
|
||||
@NonNull
|
||||
@Transactional
|
||||
List<DOMAIN> createInBatch(@NonNull Collection<DOMAIN> domains);
|
||||
|
||||
/**
|
||||
|
@ -142,6 +145,7 @@ public interface CrudService<DOMAIN, ID> {
|
|||
* @return DOMAIN
|
||||
*/
|
||||
@NonNull
|
||||
@Transactional
|
||||
DOMAIN update(@NonNull DOMAIN domain);
|
||||
|
||||
/**
|
||||
|
@ -151,6 +155,7 @@ public interface CrudService<DOMAIN, ID> {
|
|||
* @return List
|
||||
*/
|
||||
@NonNull
|
||||
@Transactional
|
||||
List<DOMAIN> updateInBatch(@NonNull Collection<DOMAIN> domains);
|
||||
|
||||
/**
|
||||
|
@ -161,6 +166,7 @@ public interface CrudService<DOMAIN, ID> {
|
|||
* @throws NotFoundException If the specified id does not exist
|
||||
*/
|
||||
@NonNull
|
||||
@Transactional
|
||||
DOMAIN removeById(@NonNull ID id);
|
||||
|
||||
/**
|
||||
|
@ -170,6 +176,7 @@ public interface CrudService<DOMAIN, ID> {
|
|||
* @return DOMAIN
|
||||
*/
|
||||
@Nullable
|
||||
@Transactional
|
||||
DOMAIN removeByIdOfNullable(@NonNull ID id);
|
||||
|
||||
/**
|
||||
|
@ -177,6 +184,7 @@ public interface CrudService<DOMAIN, ID> {
|
|||
*
|
||||
* @param domain domain
|
||||
*/
|
||||
@Transactional
|
||||
void remove(@NonNull DOMAIN domain);
|
||||
|
||||
/**
|
||||
|
@ -184,6 +192,7 @@ public interface CrudService<DOMAIN, ID> {
|
|||
*
|
||||
* @param ids ids
|
||||
*/
|
||||
@Transactional
|
||||
void removeInBatch(@NonNull Collection<ID> ids);
|
||||
|
||||
/**
|
||||
|
@ -191,10 +200,12 @@ public interface CrudService<DOMAIN, ID> {
|
|||
*
|
||||
* @param domains domains
|
||||
*/
|
||||
@Transactional
|
||||
void removeAll(@NonNull Collection<DOMAIN> domains);
|
||||
|
||||
/**
|
||||
* Remove all
|
||||
*/
|
||||
@Transactional
|
||||
void removeAll();
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ public class PostCategoryServiceImpl extends AbstractCrudService<PostCategory, I
|
|||
|
||||
@Override
|
||||
public List<PostCategory> removeByPostId(Integer postId) {
|
||||
Assert.notNull(postId, "Post id must not be null");
|
||||
Assert.notNull(postId, "PoremoveByIdst id must not be null");
|
||||
|
||||
return postCategoryRepository.deleteByPostId(postId);
|
||||
}
|
||||
|
|
|
@ -11,14 +11,13 @@ import org.springframework.data.jpa.domain.Specification;
|
|||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import run.halo.app.event.LogEvent;
|
||||
import run.halo.app.event.VisitEvent;
|
||||
import run.halo.app.event.logger.LogEvent;
|
||||
import run.halo.app.event.post.VisitEvent;
|
||||
import run.halo.app.exception.AlreadyExistsException;
|
||||
import run.halo.app.exception.BadRequestException;
|
||||
import run.halo.app.exception.NotFoundException;
|
||||
import run.halo.app.exception.ServiceException;
|
||||
import run.halo.app.model.dto.CategoryOutputDTO;
|
||||
import run.halo.app.model.dto.TagOutputDTO;
|
||||
import run.halo.app.model.dto.post.PostMinimalOutputDTO;
|
||||
|
@ -348,7 +347,8 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
|
|||
long affectedRows = postRepository.updateVisit(visits, postId);
|
||||
|
||||
if (affectedRows != 1) {
|
||||
throw new ServiceException("Failed to increase visits " + visits + " for post with id " + postId);
|
||||
log.error("Post with id: [{}] may not be found", postId);
|
||||
throw new BadRequestException("Failed to increase visits " + visits + " for post with id " + postId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,7 +360,8 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
|
|||
long affectedRows = postRepository.updateLikes(likes, postId);
|
||||
|
||||
if (affectedRows != 1) {
|
||||
throw new ServiceException("Failed to increase likes " + likes + " for post with id " + postId);
|
||||
log.error("Post with id: [{}] may not be found", postId);
|
||||
throw new BadRequestException("Failed to increase likes " + likes + " for post with id " + postId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -440,7 +441,6 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Post removeById(Integer postId) {
|
||||
Assert.notNull(postId, "Post id must not be null");
|
||||
|
||||
|
@ -498,6 +498,7 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
|
|||
postListVO.setTags(Optional.ofNullable(tagListMap.get(post.getId()))
|
||||
.orElseGet(LinkedList::new)
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(tag -> new TagOutputDTO().<TagOutputDTO>convertFrom(tag))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
|
|
|
@ -573,7 +573,7 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
|
||||
// Check suffix
|
||||
for (String suffix : CAN_EDIT_SUFFIX) {
|
||||
if (path.endsWith(suffix)) {
|
||||
if (path.toString().endsWith(suffix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import run.halo.app.cache.StringCacheStore;
|
||||
import run.halo.app.event.LogEvent;
|
||||
import run.halo.app.event.logger.LogEvent;
|
||||
import run.halo.app.exception.BadRequestException;
|
||||
import run.halo.app.exception.NotFoundException;
|
||||
import run.halo.app.model.entity.User;
|
||||
|
|
|
@ -82,6 +82,12 @@ public class PostController {
|
|||
return postService.getDetailVoBy(postId);
|
||||
}
|
||||
|
||||
@PostMapping("{postId:\\d+}/likes")
|
||||
@ApiOperation("Likes a post")
|
||||
public void like(@PathVariable("postId") Integer postId) {
|
||||
postService.increaseLike(postId);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public PostDetailVO createBy(@Valid @RequestBody PostParam postParam) {
|
||||
// Convert to
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package run.halo.app.web.controller.admin.api;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import run.halo.app.handler.theme.config.support.Group;
|
||||
|
@ -52,8 +53,8 @@ public class ThemeController {
|
|||
}
|
||||
|
||||
@GetMapping("files/content")
|
||||
public String getContentBy(@RequestParam(name = "path") String path) {
|
||||
return themeService.getTemplateContent(path);
|
||||
public BaseResponse<String> getContentBy(@RequestParam(name = "path") String path) {
|
||||
return BaseResponse.ok(HttpStatus.OK.getReasonPhrase(), themeService.getTemplateContent(path));
|
||||
}
|
||||
|
||||
@PutMapping("files/content")
|
||||
|
|
|
@ -126,7 +126,6 @@ public class ContentArchiveController {
|
|||
model.addAttribute("comments", comments);
|
||||
model.addAttribute("pageRainbow", pageRainbow);
|
||||
|
||||
// Log it
|
||||
return themeService.render("post");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package run.halo.app.web.controller.content.api;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import run.halo.app.model.dto.CommentOutputDTO;
|
||||
import run.halo.app.model.entity.User;
|
||||
import run.halo.app.model.params.CommentParam;
|
||||
|
@ -43,6 +44,7 @@ public class CommentController {
|
|||
}
|
||||
|
||||
@PostMapping
|
||||
@ApiOperation("Comments a post")
|
||||
public CommentOutputDTO comment(@RequestBody CommentParam commentParam, HttpServletRequest request) {
|
||||
// Get authentication
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
|
|
@ -92,4 +92,10 @@ public class PostController {
|
|||
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
|
||||
return commentService.pageWithParentVoBy(postId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
|
||||
}
|
||||
|
||||
@PostMapping("{postId:\\d+}/likes")
|
||||
@ApiOperation("Likes a post")
|
||||
public void like(@PathVariable("postId") Integer postId) {
|
||||
postService.increaseLike(postId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import run.halo.app.event.LogEvent;
|
||||
import run.halo.app.event.logger.LogEvent;
|
||||
import run.halo.app.exception.BadRequestException;
|
||||
import run.halo.app.model.entity.*;
|
||||
import run.halo.app.model.enums.AttachmentType;
|
||||
|
|
|
@ -3,6 +3,8 @@ package run.halo.app.event;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import run.halo.app.event.logger.LogEvent;
|
||||
import run.halo.app.event.logger.LogEventListener;
|
||||
import run.halo.app.utils.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
|
Loading…
Reference in New Issue