Skip to content

Commit

Permalink
feat: support sync self and relations in SubjectSyncPlatformService f…
Browse files Browse the repository at this point in the history
…or plugin (#589)

* feat: support sync self and relations in SubjectSyncPlatformService for plugin.

* optimize: move utils class to api and update changelog
  • Loading branch information
ChiveHao authored Jun 18, 2024
1 parent 1a42ef4 commit 9021847
Show file tree
Hide file tree
Showing 18 changed files with 143 additions and 28 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

更新日志文档,版本顺序从新到旧,最新版本在最前(上)面。

# 0.12.5

## 插件

- 丰富条目同步和条目关系插件接口

# 0.12.4

## 优化
Expand Down
15 changes: 13 additions & 2 deletions api/src/main/java/run/ikaros/api/core/subject/SubjectOperate.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package run.ikaros.api.core.subject;

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotBlank;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import run.ikaros.api.plugin.AllowPluginOperate;
Expand All @@ -22,6 +24,15 @@ public interface SubjectOperate extends AllowPluginOperate {
Mono<Subject> syncByPlatform(@Nullable Long subjectId, SubjectSyncPlatform platform,
String platformId);

Mono<Subject> findByPlatform(@Nullable Long subjectId, SubjectSyncPlatform platform,
String keyword);

Mono<Subject> findBySubjectIdAndPlatformAndPlatformId(@Nonnull Long subjectId,
@Nonnull
SubjectSyncPlatform subjectSyncPlatform,
@NotBlank String platformId);

Flux<Subject> findByPlatformAndPlatformId(@Nonnull SubjectSyncPlatform subjectSyncPlatform,
@NotBlank String platformId);

Mono<Boolean> existsByPlatformAndPlatformId(@Nonnull SubjectSyncPlatform subjectSyncPlatform,
@NotBlank String platformId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public interface SubjectSynchronizer extends ExtensionPoint {

/**
* 根据对应API从对应的平台拉取数据并转化成Ikaros的条目格式.
* 插件只需要组装数据即可.
*
* @param platformId 对应平台的条目Id.
* @return 从平台拉取的数据,进行格式转化。
Expand All @@ -23,10 +24,20 @@ public interface SubjectSynchronizer extends ExtensionPoint {

/**
* 根据对应API从对应平台拉取数据并合并到Ikaros已经存在的条目.
* 插件只需要组装数据即可.
*
* @param subject 已经存在的条目
* @param platformId 三方平台的条目ID
* @return 更新后的条目对象
*/
Mono<Subject> merge(Subject subject, String platformId);

/**
* 同步对应平台ID条目及其所有的相关条目.
* 插件需要自己更新数据库相关表.
*
* @param platformId 平台ID
* @return 第一个(起点)条目
*/
Mono<Subject> pullSelfAndRelations(String platformId);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package run.ikaros.server.infra.utils;
package run.ikaros.api.infra.utils;

import java.util.Objects;
import org.springframework.beans.BeansException;
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=0.12.4
version=0.12.5
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package run.ikaros.server.core.attachment.service.impl;

import static run.ikaros.api.infra.utils.ReactiveBeanUtils.copyProperties;
import static run.ikaros.api.store.enums.AttachmentReferenceType.EPISODE;
import static run.ikaros.server.infra.utils.ReactiveBeanUtils.copyProperties;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package run.ikaros.server.core.attachment.service.impl;

import static run.ikaros.server.infra.utils.ReactiveBeanUtils.copyProperties;
import static run.ikaros.api.infra.utils.ReactiveBeanUtils.copyProperties;

import java.util.List;
import lombok.extern.slf4j.Slf4j;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import static run.ikaros.api.core.attachment.AttachmentConst.ROOT_DIRECTORY_ID;
import static run.ikaros.api.core.attachment.AttachmentConst.ROOT_DIRECTORY_PARENT_ID;
import static run.ikaros.api.infra.utils.ReactiveBeanUtils.copyProperties;
import static run.ikaros.api.store.enums.AttachmentType.Directory;
import static run.ikaros.server.infra.utils.ReactiveBeanUtils.copyProperties;

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package run.ikaros.server.core.collection;

import static run.ikaros.server.infra.utils.ReactiveBeanUtils.copyProperties;
import static run.ikaros.api.infra.utils.ReactiveBeanUtils.copyProperties;

import java.time.LocalDateTime;
import java.util.Objects;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package run.ikaros.server.core.collection;

import static run.ikaros.server.infra.utils.ReactiveBeanUtils.copyProperties;
import static run.ikaros.api.infra.utils.ReactiveBeanUtils.copyProperties;

import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package run.ikaros.server.core.episode;

import static run.ikaros.server.infra.utils.ReactiveBeanUtils.copyProperties;
import static run.ikaros.api.infra.utils.ReactiveBeanUtils.copyProperties;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package run.ikaros.server.core.subject;

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -61,8 +62,24 @@ public Mono<Subject> syncByPlatform(@Nullable Long subjectId, SubjectSyncPlatfor
}

@Override
public Mono<Subject> findByPlatform(@Nullable Long subjectId, SubjectSyncPlatform platform,
String keyword) {
return null;
public Mono<Subject> findBySubjectIdAndPlatformAndPlatformId(@Nonnull Long subjectId,
@Nonnull SubjectSyncPlatform
subjectSyncPlatform,
String platformId) {
return subjectService.findBySubjectIdAndPlatformAndPlatformId(
subjectId, subjectSyncPlatform, platformId);
}

@Override
public Flux<Subject> findByPlatformAndPlatformId(
@Nonnull SubjectSyncPlatform subjectSyncPlatform, String platformId) {
return subjectService.findByPlatformAndPlatformId(subjectSyncPlatform, platformId);
}

@Override
public Mono<Boolean> existsByPlatformAndPlatformId(
@Nonnull SubjectSyncPlatform subjectSyncPlatform, String platformId) {
return subjectService.existsByPlatformAndPlatformId(subjectSyncPlatform, platformId);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import jakarta.annotation.Nonnull;
import jakarta.validation.constraints.NotBlank;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import run.ikaros.api.core.subject.Subject;
import run.ikaros.api.core.subject.SubjectMeta;
Expand All @@ -15,10 +16,16 @@ public interface SubjectService {

Mono<Subject> findByBgmId(@Nonnull Long subjectId, Long bgmtvId);

Mono<Subject> findBySyncPlatform(@Nonnull Long subjectId,
Mono<Subject> findBySubjectIdAndPlatformAndPlatformId(@Nonnull Long subjectId,
@Nonnull SubjectSyncPlatform subjectSyncPlatform,
@NotBlank String platformId);

Flux<Subject> findByPlatformAndPlatformId(@Nonnull SubjectSyncPlatform subjectSyncPlatform,
@NotBlank String platformId);

Mono<Boolean> existsByPlatformAndPlatformId(@Nonnull SubjectSyncPlatform subjectSyncPlatform,
@NotBlank String platformId);

@Transactional
Mono<Subject> create(Subject subject);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ public interface SubjectSyncPlatformService {

Mono<Subject> sync(PostSubjectSyncCondition condition);

/**
* 同步对应平台ID条目及其所有的相关条目.
*
* @param platform 平台
* @param platformId 平台ID
* @return 第一个(起点)条目
*/
Mono<Subject> syncSelfAndRelations(SubjectSyncPlatform platform, String platformId);

@Transactional
Mono<SubjectSync> save(SubjectSync subjectSync);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package run.ikaros.server.core.subject.service.impl;

import static org.springframework.data.relational.core.query.Criteria.where;
import static run.ikaros.server.infra.utils.ReactiveBeanUtils.copyProperties;
import static run.ikaros.api.infra.utils.ReactiveBeanUtils.copyProperties;

import jakarta.annotation.Nonnull;
import jakarta.validation.constraints.NotBlank;
Expand Down Expand Up @@ -34,6 +34,7 @@
import run.ikaros.api.core.subject.SubjectSync;
import run.ikaros.api.core.subject.vo.FindSubjectCondition;
import run.ikaros.api.infra.exception.NotFoundException;
import run.ikaros.api.infra.utils.ReactiveBeanUtils;
import run.ikaros.api.infra.utils.StringUtils;
import run.ikaros.api.store.enums.AttachmentReferenceType;
import run.ikaros.api.store.enums.SubjectSyncPlatform;
Expand All @@ -42,7 +43,6 @@
import run.ikaros.server.core.subject.event.SubjectAddEvent;
import run.ikaros.server.core.subject.event.SubjectRemoveEvent;
import run.ikaros.server.core.subject.service.SubjectService;
import run.ikaros.server.infra.utils.ReactiveBeanUtils;
import run.ikaros.server.store.entity.AttachmentEntity;
import run.ikaros.server.store.entity.AttachmentReferenceEntity;
import run.ikaros.server.store.entity.BaseEntity;
Expand Down Expand Up @@ -175,22 +175,36 @@ public Mono<Subject> findByBgmId(@Nonnull Long subjectId, Long bgmtvId) {
}

@Override
public Mono<Subject> findBySyncPlatform(@Nonnull Long subjectId,
@Nonnull SubjectSyncPlatform subjectSyncPlatform,
@NotBlank String platformId) {
Assert.notNull(subjectSyncPlatform, "'subjectSyncPlatform' must not null.");
public Mono<Subject> findBySubjectIdAndPlatformAndPlatformId(@Nonnull Long subjectId,
@Nonnull SubjectSyncPlatform
platform,
@NotBlank String platformId) {
Assert.notNull(platform, "'platform' must not null.");
Assert.hasText(platformId, "'platformId' must has text.");
return subjectSyncRepository.findBySubjectIdAndPlatformAndPlatformId(subjectId,
subjectSyncPlatform, platformId)
platform, platformId)
.map(SubjectSyncEntity::getSubjectId)
.flatMap(this::findById)
.switchIfEmpty(
Mono.error(new NotFoundException(
"Not found subject by sync platform and platformId: "
+ subjectSyncPlatform + "-" + platformId)))
.flatMap(this::findById).flatMap(subjectEntity -> findById(subjectEntity.getId()));
}

@Override
public Flux<Subject> findByPlatformAndPlatformId(
@Nonnull SubjectSyncPlatform subjectSyncPlatform, String platformId) {
Assert.notNull(subjectSyncPlatform, "'subjectSyncPlatform' must not null.");
Assert.hasText(platformId, "'platformId' must has text.");
return subjectSyncRepository.findByPlatformAndPlatformId(subjectSyncPlatform, platformId)
.map(SubjectSyncEntity::getSubjectId).flatMap(this::findById)
.flatMap(subjectEntity -> findById(subjectEntity.getId()));
}

@Override
public Mono<Boolean> existsByPlatformAndPlatformId(
@Nonnull SubjectSyncPlatform subjectSyncPlatform, String platformId) {
Assert.notNull(subjectSyncPlatform, "'subjectSyncPlatform' must not null.");
Assert.hasText(platformId, "'platformId' must has text.");
return subjectSyncRepository.existsByPlatformAndPlatformId(subjectSyncPlatform, platformId);
}

@Override
public synchronized Mono<Subject> create(Subject subject) {
Assert.notNull(subject, "'subject' must not be null.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package run.ikaros.server.core.subject.service.impl;

import static run.ikaros.server.infra.utils.ReactiveBeanUtils.copyProperties;
import static run.ikaros.api.infra.utils.ReactiveBeanUtils.copyProperties;

import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotNull;
Expand Down Expand Up @@ -107,6 +107,44 @@ public Mono<Subject> sync(PostSubjectSyncCondition condition) {

}

@Override
public Mono<Subject> syncSelfAndRelations(SubjectSyncPlatform platform, String platformId) {
Assert.notNull(platform, "'platform' must not null.");
Assert.hasText(platformId, "'platformId' must has text.");
// 查询是否已经同步过了,如果已经同步过则返回对应的条目信息
return subjectSyncRepository.findByPlatformAndPlatformId(platform, platformId)
.collectList()
.filter(subjectSyncEntities -> !subjectSyncEntities.isEmpty())
.map(subjectSyncEntities -> subjectSyncEntities.get(0))
.map(SubjectSyncEntity::getSubjectId)
.flatMap(subjectService::findById)
.switchIfEmpty(doSyncSelfAndRelations(platform, platformId));
}

private Mono<Subject> doSyncSelfAndRelations(SubjectSyncPlatform platform, String platformId) {
Assert.notNull(platform, "'platform' must not null.");
Assert.hasText(platformId, "'platformId' must has text.");
return Flux.fromStream(extensionComponentsFinder.getExtensions(SubjectSynchronizer.class)
.stream())
.filter(subjectSynchronizer -> platform.equals(subjectSynchronizer.getSyncPlatform()))
.collectList()
.filter(subjectSynchronizes -> !subjectSynchronizes.isEmpty())
.switchIfEmpty(Mono.error(new NoAvailableSubjectPlatformSynchronizerException(
"No found available subject platform synchronizer for platform-id: "
+ platform.name() + "-" + platformId)))
.map(subjectSynchronizes -> subjectSynchronizes.get(0))
.flatMap(subjectSynchronizer -> subjectSynchronizer.pullSelfAndRelations(platformId))
.onErrorResume(Exception.class, e -> {
String msg =
"Operate has exception "
+ "for platform-id: "
+ platform.name() + "-" + platformId
+ ", plugin exception msg: " + e.getMessage();
log.error(msg, e);
return Mono.error(new NoAvailableSubjectPlatformSynchronizerException(msg));
}).subscribeOn(Schedulers.boundedElastic());
}

@Override
public Mono<SubjectSync> save(SubjectSync subjectSync) {
log.debug("save: {}", subjectSync);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package run.ikaros.server.core.tag;

import static run.ikaros.server.infra.utils.ReactiveBeanUtils.copyProperties;
import static run.ikaros.api.infra.utils.ReactiveBeanUtils.copyProperties;

import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Mono<SubjectSyncEntity> findBySubjectIdAndPlatformAndPlatformId(Long subjectId,
SubjectSyncPlatform platform,
String platformId);

Mono<Boolean> existsByPlatformAndPlatformId(SubjectSyncPlatform platform, String platformId);

Flux<SubjectSyncEntity> findAllBySubjectId(Long subjectId);

Mono<Long> deleteAllBySubjectId(Long subjectId);
Expand Down

0 comments on commit 9021847

Please sign in to comment.