diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/ApplicationCommonEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/ApplicationCommonEvent.java index a53879bfee..fcc874b3cf 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/ApplicationCommonEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/ApplicationCommonEvent.java @@ -16,6 +16,11 @@ public class ApplicationCommonEvent extends AbstractEvent { private final String applicationName; private final String applicationCategory; private final String applicationDescription; + private final String applicationTitle; + private final String oldApplicationName; + private final String oldApplicationCategory; + private final String oldApplicationDescription; + private final String oldApplicationTitle; private final EventType type; @Nullable private final String folderId; diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/DatasourceResourcePermissionEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/DatasourceResourcePermissionEvent.java new file mode 100644 index 0000000000..efa8acc3da --- /dev/null +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/DatasourceResourcePermissionEvent.java @@ -0,0 +1,18 @@ +package org.lowcoder.infra.event; + +import lombok.Getter; +import lombok.experimental.SuperBuilder; + +@Getter +@SuperBuilder +public class DatasourceResourcePermissionEvent extends AbstractEvent { + + private final String datasourceId; + private final String name; + private final String type; + + private final Object oldPermission; + private final Object newPermission; + + private final EventType eventType; +} diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/FolderCommonEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/FolderCommonEvent.java index 23a4b8d0ed..603ca21a5a 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/FolderCommonEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/FolderCommonEvent.java @@ -9,6 +9,7 @@ public class FolderCommonEvent extends AbstractEvent { private final String id; private final String name; + private final String fromName; private final EventType type; @Override diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/LibraryQueryEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/LibraryQueryEvent.java index 13b048246b..f6459eb2d5 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/LibraryQueryEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/LibraryQueryEvent.java @@ -10,6 +10,7 @@ public class LibraryQueryEvent extends AbstractEvent { private String id; private String name; private EventType eventType; + private String oldName; @Override public EventType getEventType() { diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/LibraryQueryPublishEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/LibraryQueryPublishEvent.java new file mode 100644 index 0000000000..06b748b580 --- /dev/null +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/LibraryQueryPublishEvent.java @@ -0,0 +1,19 @@ +package org.lowcoder.infra.event; + +import lombok.Getter; +import lombok.experimental.SuperBuilder; + +@Getter +@SuperBuilder +public class LibraryQueryPublishEvent extends AbstractEvent { + + private String id; + private String oldVersion; + private String newVersion; + private EventType eventType; + + @Override + public EventType getEventType() { + return eventType; + } +} diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/datasource/DatasourceEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/datasource/DatasourceEvent.java index 2332806efc..8e1d7c6ec9 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/datasource/DatasourceEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/datasource/DatasourceEvent.java @@ -11,6 +11,7 @@ public class DatasourceEvent extends AbstractEvent { private final String datasourceId; private final String name; private final String type; + private final String oldName; private final EventType eventType; } diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/datasource/DatasourcePermissionEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/datasource/DatasourcePermissionEvent.java index d7dfd563bd..0d9b1899ad 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/datasource/DatasourcePermissionEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/datasource/DatasourcePermissionEvent.java @@ -5,6 +5,7 @@ import org.lowcoder.infra.event.AbstractEvent; import java.util.Collection; +import java.util.List; @Getter @SuperBuilder @@ -18,5 +19,8 @@ public class DatasourcePermissionEvent extends AbstractEvent { private final Collection groupIds; private final String role; + private final List oldPermissions; + private final List newPermissions; + private final EventType eventType; } diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/BaseGroupEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/BaseGroupEvent.java index 7ffd5e087a..c603518e55 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/BaseGroupEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/BaseGroupEvent.java @@ -9,5 +9,4 @@ public abstract class BaseGroupEvent extends AbstractEvent { private final String groupId; - private final String groupName; } diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/GroupCreateEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/GroupCreateEvent.java index ab80e0cc09..5044617d78 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/GroupCreateEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/GroupCreateEvent.java @@ -5,6 +5,9 @@ @SuperBuilder public class GroupCreateEvent extends BaseGroupEvent { + private final String groupName; + private final String oldGroupName; + @Override public EventType getEventType() { return EventType.GROUP_CREATE; diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/GroupDeleteEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/GroupDeleteEvent.java index 2d7caa4956..b2e00a1995 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/GroupDeleteEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/GroupDeleteEvent.java @@ -5,6 +5,9 @@ @SuperBuilder public class GroupDeleteEvent extends BaseGroupEvent { + private final String groupName; + private final String oldGroupName; + @Override public EventType getEventType() { return EventType.GROUP_DELETE; diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/GroupUpdateEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/GroupUpdateEvent.java index 9d06c459ac..6742e07906 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/GroupUpdateEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/group/GroupUpdateEvent.java @@ -5,6 +5,9 @@ @SuperBuilder public class GroupUpdateEvent extends BaseGroupEvent { + private final String groupName; + private final String oldGroupName; + @Override public EventType getEventType() { return EventType.GROUP_UPDATE; diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/BaseGroupMemberEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/BaseGroupMemberEvent.java index 26c5f1c52a..64d71354c3 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/BaseGroupMemberEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/BaseGroupMemberEvent.java @@ -8,9 +8,4 @@ @SuperBuilder public abstract class BaseGroupMemberEvent extends AbstractEvent { - private final String groupId; - private final String groupName; - private final String memberId; - private final String memberName; - private final String memberRole; } diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberAddEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberAddEvent.java index 52c17df485..57816f39b1 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberAddEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberAddEvent.java @@ -5,6 +5,12 @@ @SuperBuilder public class GroupMemberAddEvent extends BaseGroupMemberEvent { + private final String groupId; + private final String groupName; + private final String memberId; + private final String memberName; + private final String memberRole; + @Override public EventType getEventType() { return EventType.GROUP_MEMBER_ADD; diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberLeaveEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberLeaveEvent.java index d35db51988..3074ad5e7b 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberLeaveEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberLeaveEvent.java @@ -5,6 +5,12 @@ @SuperBuilder public class GroupMemberLeaveEvent extends BaseGroupMemberEvent { + private final String groupId; + private final String groupName; + private final String memberId; + private final String memberName; + private final String memberRole; + @Override public EventType getEventType() { return EventType.GROUP_MEMBER_LEAVE; diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberRemoveEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberRemoveEvent.java index 6b4fef1d2e..f7b9fd4efb 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberRemoveEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberRemoveEvent.java @@ -5,6 +5,12 @@ @SuperBuilder public class GroupMemberRemoveEvent extends BaseGroupMemberEvent { + private final String groupId; + private final String groupName; + private final String memberId; + private final String memberName; + private final String memberRole; + @Override public EventType getEventType() { return EventType.GROUP_MEMBER_REMOVE; diff --git a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberRoleUpdateEvent.java b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberRoleUpdateEvent.java index 785a28fc59..bbfc85d062 100644 --- a/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberRoleUpdateEvent.java +++ b/server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/groupmember/GroupMemberRoleUpdateEvent.java @@ -5,6 +5,13 @@ @SuperBuilder public class GroupMemberRoleUpdateEvent extends BaseGroupMemberEvent { + private final String groupId; + private final String groupName; + private final String memberId; + private final String memberName; + private final String memberRole; + private final String oldMemberRole; + @Override public EventType getEventType() { return EventType.GROUP_MEMBER_ROLE_UPDATE; diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiServiceImpl.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiServiceImpl.java index 23b7bc150d..89ff852d8c 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiServiceImpl.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationApiServiceImpl.java @@ -136,10 +136,11 @@ public Mono create(CreateApplicationRequest createApplicationRe .delayUntil(created -> autoGrantPermissionsByFolderDefault(created.getId(), createApplicationRequest.folderId())) .delayUntil(created -> folderApiService.move(created.getId(), createApplicationRequest.folderId())) - .map(applicationCreated -> ApplicationView.builder() - .applicationInfoView(buildView(applicationCreated, "", createApplicationRequest.folderId())) + .flatMap(applicationCreated -> buildView(applicationCreated, "", createApplicationRequest.folderId()) + .map(infoViewMono -> ApplicationView.builder() + .applicationInfoView(infoViewMono) .applicationDSL(applicationCreated.getEditingApplicationDSL()) - .build()); + .build())); } private Mono autoGrantPermissionsByFolderDefault(String applicationId, @Nullable String folderId) { @@ -556,7 +557,7 @@ public Mono checkApplicationPermissionWithReadableErrorMsg(S private Mono buildView(Application application, String role) { - return Mono.just(buildView(application, role, null)).delayUntil(applicationInfoView -> { + return buildView(application, role, null).delayUntil(applicationInfoView -> { String applicationId = applicationInfoView.getApplicationId(); return folderElementRelationService.getByElementIds(List.of(applicationId)) .doOnNext(folderElement -> { @@ -565,25 +566,33 @@ private Mono buildView(Application application, String role }); } - private ApplicationInfoView buildView(Application application, String role, @Nullable String folderId) { - return ApplicationInfoView.builder() - .applicationId(application.getId()) - .applicationGid(application.getGid()) - .orgId(application.getOrganizationId()) - .name(application.getName()) - .createBy(application.getCreatedBy()) - .createAt(application.getCreatedAt().toEpochMilli()) - .role(role) - .applicationType(application.getApplicationType()) - .applicationStatus(application.getApplicationStatus()) - .folderId(folderId) - .publicToAll(application.isPublicToAll()) - .publicToMarketplace(application.isPublicToMarketplace()) - .agencyProfile(application.agencyProfile()) - .editingUserId(application.getEditingUserId()) - .lastModifyTime(application.getUpdatedAt()) - .lastEditedAt(application.getLastEditedAt()) - .build(); + private Mono buildView(Application application, String role, @Nullable String folderId) { + return application.getCategory(applicationRecordService) + .zipWith(application.getDescription(applicationRecordService)) + .zipWith(application.getTitle(applicationRecordService), TupleUtils::merge) + .map(tuple -> + ApplicationInfoView.builder() + .applicationId(application.getId()) + .applicationGid(application.getGid()) + .orgId(application.getOrganizationId()) + .name(application.getName()) + .createBy(application.getCreatedBy()) + .createAt(application.getCreatedAt().toEpochMilli()) + .role(role) + .applicationType(application.getApplicationType()) + .applicationStatus(application.getApplicationStatus()) + .folderId(folderId) + .publicToAll(application.isPublicToAll()) + .publicToMarketplace(application.isPublicToMarketplace()) + .agencyProfile(application.agencyProfile()) + .editingUserId(application.getEditingUserId()) + .lastModifyTime(application.getUpdatedAt()) + .lastEditedAt(application.getLastEditedAt()) + .category(tuple.getT1()) + .description(tuple.getT2()) + .title(tuple.getT3()) + .build() + ); } private Mono buildView(Application application) { diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java index d1c6402f00..bff1fff990 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/application/ApplicationController.java @@ -41,31 +41,33 @@ public class ApplicationController implements ApplicationEndpoints { @Override public Mono> create(@RequestBody CreateApplicationRequest createApplicationRequest) { return applicationApiService.create(createApplicationRequest) - .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, APPLICATION_CREATE)) + .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(null, applicationView, APPLICATION_CREATE)) .map(ResponseView::success); } @Override public Mono> createFromTemplate(@RequestParam String templateId) { return applicationApiService.createFromTemplate(templateId) - .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, APPLICATION_CREATE)) + .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(null, applicationView, APPLICATION_CREATE)) .map(ResponseView::success); } @Override public Mono> recycle(@PathVariable String applicationId) { return gidService.convertApplicationIdToObjectId(applicationId).flatMap(appId -> - applicationApiService.recycle(appId) - .delayUntil(__ -> businessEventPublisher.publishApplicationCommonEvent(applicationId, null, null, APPLICATION_RECYCLED)) - .map(ResponseView::success)); + applicationApiService.getEditingApplication(appId, true).flatMap(originalApplicationView -> + applicationApiService.recycle(appId) + .delayUntil(__ -> businessEventPublisher.publishApplicationCommonEvent(originalApplicationView, applicationId, originalApplicationView.getApplicationInfoView().getFolderId(), null, APPLICATION_RECYCLED)) + .map(ResponseView::success))); } @Override public Mono> restore(@PathVariable String applicationId) { return gidService.convertApplicationIdToObjectId(applicationId).flatMap(appId -> - applicationApiService.restore(appId) - .delayUntil(__ -> businessEventPublisher.publishApplicationCommonEvent(applicationId, null, null, APPLICATION_RESTORE)) - .map(ResponseView::success)); + applicationApiService.getEditingApplication(appId, true).flatMap(originalApplicationView -> + applicationApiService.restore(appId) + .delayUntil(__ -> businessEventPublisher.publishApplicationCommonEvent(originalApplicationView, applicationId, null, null, APPLICATION_RESTORE)) + .map(ResponseView::success))); } @Override @@ -78,9 +80,10 @@ public Mono>> getRecycledApplications(@Re @Override public Mono> delete(@PathVariable String applicationId) { return gidService.convertApplicationIdToObjectId(applicationId).flatMap(appId -> - applicationApiService.delete(appId) - .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, APPLICATION_DELETE)) - .map(ResponseView::success)); + applicationApiService.getEditingApplication(appId, true).flatMap(originalApplicationView -> + applicationApiService.delete(appId) + .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(originalApplicationView, applicationView, APPLICATION_DELETE)) + .map(ResponseView::success))); } @Override @@ -94,28 +97,31 @@ public Mono> getEditingApplication(@PathVariable S @Override public Mono> getPublishedApplication(@PathVariable String applicationId, @RequestParam(required = false) Boolean withDeleted) { return gidService.convertApplicationIdToObjectId(applicationId).flatMap(appId -> - applicationApiService.getPublishedApplication(appId, ApplicationRequestType.PUBLIC_TO_ALL, withDeleted) - .delayUntil(applicationView -> applicationApiService.updateUserApplicationLastViewTime(appId)) - .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, APPLICATION_VIEW)) - .map(ResponseView::success)); + applicationApiService.getEditingApplication(appId, true).flatMap(originalApplicationView -> + applicationApiService.getPublishedApplication(appId, ApplicationRequestType.PUBLIC_TO_ALL, withDeleted) + .delayUntil(applicationView -> applicationApiService.updateUserApplicationLastViewTime(appId)) + .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(originalApplicationView, applicationView, APPLICATION_VIEW)) + .map(ResponseView::success))); } @Override public Mono> getPublishedMarketPlaceApplication(@PathVariable String applicationId) { return gidService.convertApplicationIdToObjectId(applicationId).flatMap(appId -> - applicationApiService.getPublishedApplication(appId, ApplicationRequestType.PUBLIC_TO_MARKETPLACE, false) - .delayUntil(applicationView -> applicationApiService.updateUserApplicationLastViewTime(appId)) - .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, APPLICATION_VIEW)) - .map(ResponseView::success)); + applicationApiService.getEditingApplication(appId, true).flatMap(originalApplicationView -> + applicationApiService.getPublishedApplication(appId, ApplicationRequestType.PUBLIC_TO_MARKETPLACE, false) + .delayUntil(applicationView -> applicationApiService.updateUserApplicationLastViewTime(appId)) + .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(originalApplicationView, applicationView, APPLICATION_VIEW)) + .map(ResponseView::success))); } @Override public Mono> getAgencyProfileApplication(@PathVariable String applicationId) { return gidService.convertApplicationIdToObjectId(applicationId).flatMap(appId -> - applicationApiService.getPublishedApplication(appId, ApplicationRequestType.AGENCY_PROFILE, false) - .delayUntil(applicationView -> applicationApiService.updateUserApplicationLastViewTime(appId)) - .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, APPLICATION_VIEW)) - .map(ResponseView::success)); + applicationApiService.getEditingApplication(appId, true).flatMap(originalApplicationView -> + applicationApiService.getPublishedApplication(appId, ApplicationRequestType.AGENCY_PROFILE, false) + .delayUntil(applicationView -> applicationApiService.updateUserApplicationLastViewTime(appId)) + .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(originalApplicationView, applicationView, APPLICATION_VIEW)) + .map(ResponseView::success))); } @Override @@ -123,9 +129,10 @@ public Mono> update(@PathVariable String applicati @RequestBody Application newApplication, @RequestParam(required = false) Boolean updateStatus) { return gidService.convertApplicationIdToObjectId(applicationId).flatMap(appId -> - applicationApiService.update(appId, newApplication, updateStatus) - .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(applicationView, APPLICATION_UPDATE)) - .map(ResponseView::success)); + applicationApiService.getEditingApplication(appId, true).flatMap(originalApplicationView -> + applicationApiService.update(appId, newApplication, updateStatus) + .delayUntil(applicationView -> businessEventPublisher.publishApplicationCommonEvent(originalApplicationView, applicationView, APPLICATION_UPDATE)) + .map(ResponseView::success))); } @Override diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/datasource/DatasourceController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/datasource/DatasourceController.java index a87f5a78b2..ef41367063 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/datasource/DatasourceController.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/datasource/DatasourceController.java @@ -10,12 +10,14 @@ import org.lowcoder.api.framework.view.PageResponseView; import org.lowcoder.api.framework.view.ResponseView; import org.lowcoder.api.permission.view.CommonPermissionView; +import org.lowcoder.api.usermanagement.view.UpdateGroupRequest; import org.lowcoder.api.util.BusinessEventPublisher; import org.lowcoder.api.util.GidService; import org.lowcoder.domain.datasource.model.Datasource; import org.lowcoder.domain.datasource.service.DatasourceService; import org.lowcoder.domain.datasource.service.DatasourceStructureService; import org.lowcoder.domain.permission.model.ResourceRole; +import org.lowcoder.domain.permission.service.ResourcePermissionService; import org.lowcoder.domain.plugin.client.dto.GetPluginDynamicConfigRequestDTO; import org.lowcoder.sdk.exception.BizError; import org.lowcoder.sdk.models.DatasourceStructure; @@ -47,12 +49,13 @@ public class DatasourceController implements DatasourceEndpoints private final BusinessEventPublisher businessEventPublisher; private final DatasourceService datasourceService; private final GidService gidService; + private final ResourcePermissionService resourcePermissionService; @Override public Mono> create(@Valid @RequestBody UpsertDatasourceRequest request) { return datasourceApiService.create(upsertDatasourceRequestMapper.resolve(request)) .delayUntil(datasourceService::removePasswordTypeKeysFromJsDatasourcePluginConfig) - .delayUntil(datasource -> businessEventPublisher.publishDatasourceEvent(datasource, DATA_SOURCE_CREATE)) + .delayUntil(datasource -> businessEventPublisher.publishDatasourceEvent(datasource, DATA_SOURCE_CREATE, null)) .map(ResponseView::success); } @@ -69,23 +72,25 @@ public Mono> update(@PathVariable String id, @RequestBody UpsertDatasourceRequest request) { Datasource resolvedDatasource = upsertDatasourceRequestMapper.resolve(request); return gidService.convertDatasourceIdToObjectId(id).flatMap(objectId -> - datasourceApiService.update(objectId, resolvedDatasource) - .delayUntil(datasourceService::removePasswordTypeKeysFromJsDatasourcePluginConfig) - .delayUntil(datasource -> businessEventPublisher.publishDatasourceEvent(datasource, DATA_SOURCE_UPDATE)) - .map(ResponseView::success)); + datasourceService.getById(id).flatMap(orgDatasource -> + datasourceApiService.update(objectId, resolvedDatasource) + .delayUntil(datasourceService::removePasswordTypeKeysFromJsDatasourcePluginConfig) + .delayUntil(datasource -> businessEventPublisher.publishDatasourceEvent(datasource, DATA_SOURCE_UPDATE, orgDatasource.getName())) + .map(ResponseView::success))); } @Override public Mono> delete(@PathVariable String id) { return gidService.convertDatasourceIdToObjectId(id).flatMap(objectId -> - datasourceApiService.delete(objectId) - .delayUntil(result -> { - if (BooleanUtils.isTrue(result)) { - return businessEventPublisher.publishDatasourceEvent(objectId, DATA_SOURCE_DELETE); - } - return Mono.empty(); - }) - .map(ResponseView::success)); + datasourceService.getById(id).flatMap(orgDatasource -> + datasourceApiService.delete(objectId) + .delayUntil(result -> { + if (BooleanUtils.isTrue(result)) { + return businessEventPublisher.publishDatasourceEvent(objectId, DATA_SOURCE_DELETE, orgDatasource.getName()); + } + return Mono.empty(); + }) + .map(ResponseView::success))); } @Override @@ -177,15 +182,17 @@ public Mono> grantPermission(@PathVariable String datasour return ofError(INVALID_PARAMETER, "INVALID_PARAMETER", request.role()); } return gidService.convertDatasourceIdToObjectId(datasourceId).flatMap(objectId -> - datasourceApiService.grantPermission(objectId, request.userIds(), request.groupIds(), role) - .delayUntil(result -> { - if (BooleanUtils.isTrue(result)) { - return businessEventPublisher.publishDatasourcePermissionEvent(objectId, request.userIds(), - request.groupIds(), request.role(), DATA_SOURCE_PERMISSION_GRANT); - } - return Mono.empty(); - }) - .map(ResponseView::success)); + datasourceApiService.getPermissions(objectId).flatMap(oldPermissions -> + datasourceApiService.grantPermission(objectId, request.userIds(), request.groupIds(), role) + .delayUntil(result -> { + if (BooleanUtils.isTrue(result)) { + return datasourceApiService.getPermissions(objectId).flatMap(newPermissions -> + businessEventPublisher.publishDatasourcePermissionEvent(objectId, request.userIds(), + request.groupIds(), request.role(), DATA_SOURCE_PERMISSION_GRANT, oldPermissions, newPermissions)); + } + return Mono.empty(); + }) + .map(ResponseView::success))); } @Override @@ -194,21 +201,24 @@ public Mono> updatePermission(@PathVariable("permissionId" if (request.getResourceRole() == null) { return ofError(INVALID_PARAMETER, "INVALID_PARAMETER", request.role()); } - return datasourceApiService.updatePermission(permissionId, request.getResourceRole()) + return resourcePermissionService.getById(permissionId).flatMap(oldPermission -> + datasourceApiService.updatePermission(permissionId, request.getResourceRole()) .delayUntil(result -> { if (BooleanUtils.isTrue(result)) { - return businessEventPublisher.publishDatasourcePermissionEvent(permissionId, DATA_SOURCE_PERMISSION_UPDATE); + return resourcePermissionService.getById(permissionId).flatMap(newPermission -> + businessEventPublisher.publishDatasourceResourcePermissionEvent(DATA_SOURCE_PERMISSION_UPDATE, oldPermission, newPermission)); } return Mono.empty(); }) - .map(ResponseView::success); + .map(ResponseView::success)); } @Override public Mono> deletePermission(@PathVariable("permissionId") String permissionId) { - return businessEventPublisher.publishDatasourcePermissionEvent(permissionId, DATA_SOURCE_PERMISSION_DELETE) + return resourcePermissionService.getById(permissionId).flatMap(oldPermission -> + businessEventPublisher.publishDatasourceResourcePermissionEvent(DATA_SOURCE_PERMISSION_DELETE, oldPermission, null) .then(datasourceApiService.deletePermission(permissionId)) - .map(ResponseView::success); + .map(ResponseView::success)); } @Override diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/FolderController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/FolderController.java index e15cac1050..b4dd8dd75f 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/FolderController.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/FolderController.java @@ -1,6 +1,7 @@ package org.lowcoder.api.home; import lombok.RequiredArgsConstructor; +import org.lowcoder.api.application.ApplicationApiService; import org.lowcoder.api.application.view.ApplicationPermissionView; import org.lowcoder.api.framework.view.PageResponseView; import org.lowcoder.api.framework.view.ResponseView; @@ -35,12 +36,13 @@ public class FolderController implements FolderEndpoints private final BusinessEventPublisher businessEventPublisher; private final GidService gidService; private final FolderElementRelationService folderElementRelationService; + private final ApplicationApiService applicationApiService; @Override public Mono> create(@RequestBody Folder folder) { return folderApiService.create(folder) .delayUntil(folderInfoView -> folderApiService.upsertLastViewTime(folderInfoView.getFolderId())) - .delayUntil(f -> businessEventPublisher.publishFolderCommonEvent(f.getFolderId(), f.getName(), EventType.FOLDER_CREATE)) + .delayUntil(f -> businessEventPublisher.publishFolderCommonEvent(f.getFolderId(), f.getName(), null, EventType.FOLDER_CREATE)) .map(ResponseView::success); } @@ -48,7 +50,7 @@ public Mono> create(@RequestBody Folder folder) { public Mono> delete(@PathVariable("id") String folderId) { return gidService.convertFolderIdToObjectId(folderId).flatMap(objectId -> folderApiService.delete(objectId.orElse(null)) - .delayUntil(f -> businessEventPublisher.publishFolderCommonEvent(f.getId(), f.getName(), EventType.FOLDER_DELETE)) + .delayUntil(f -> businessEventPublisher.publishFolderCommonEvent(f.getId(), f.getName(), f.getName(), EventType.FOLDER_DELETE)) .then(Mono.fromSupplier(() -> ResponseView.success(null)))); } @@ -61,7 +63,7 @@ public Mono> update(@RequestBody Folder folder) { .zipWhen(__ -> folderApiService.update(folder)) .delayUntil(tuple2 -> { Folder old = tuple2.getT1(); - return businessEventPublisher.publishFolderCommonEvent(folder.getId(), old.getName() + " => " + folder.getName(), + return businessEventPublisher.publishFolderCommonEvent(folder.getId(), folder.getName(), old.getName(), EventType.FOLDER_UPDATE); }) .map(tuple2 -> ResponseView.success(tuple2.getT2())); @@ -95,9 +97,10 @@ public Mono> move(@PathVariable("id") String applicationLikeI @RequestParam(value = "targetFolderId", required = false) String targetFolderId) { return folderElementRelationService.getByElementIds(List.of(applicationLikeId)).next().defaultIfEmpty(new FolderElement(null, null)).flatMap(folderElement -> gidService.convertFolderIdToObjectId(targetFolderId).flatMap(objectId -> - folderApiService.move(applicationLikeId, objectId.orElse(null)) - .then(businessEventPublisher.publishApplicationCommonEvent(applicationLikeId, folderElement.folderId(), objectId.orElse(null), APPLICATION_MOVE)) - .then(Mono.fromSupplier(() -> ResponseView.success(null))))); + applicationApiService.getEditingApplication(applicationLikeId, true).flatMap(originalApplicationView -> + folderApiService.move(applicationLikeId, objectId.orElse(null)) + .then(businessEventPublisher.publishApplicationCommonEvent(originalApplicationView, applicationLikeId, folderElement.folderId(), objectId.orElse(null), APPLICATION_MOVE)) + .then(Mono.fromSupplier(() -> ResponseView.success(null)))))); } @Override diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/query/LibraryQueryController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/query/LibraryQueryController.java index 62e869a18a..d899506f7e 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/query/LibraryQueryController.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/query/LibraryQueryController.java @@ -2,6 +2,7 @@ import java.util.List; +import org.lowcoder.api.datasource.UpsertDatasourceRequest; import org.lowcoder.api.framework.view.PageResponseView; import org.lowcoder.api.framework.view.ResponseView; import org.lowcoder.api.query.view.LibraryQueryAggregateView; @@ -11,7 +12,10 @@ import org.lowcoder.api.query.view.UpsertLibraryQueryRequest; import org.lowcoder.api.util.BusinessEventPublisher; import org.lowcoder.api.util.GidService; +import org.lowcoder.domain.datasource.model.Datasource; import org.lowcoder.domain.query.model.LibraryQuery; +import org.lowcoder.domain.query.model.LibraryQueryRecord; +import org.lowcoder.domain.query.service.LibraryQueryRecordService; import org.lowcoder.domain.query.service.LibraryQueryService; import org.lowcoder.plugin.api.event.LowcoderEvent.EventType; import org.springframework.beans.factory.annotation.Autowired; @@ -22,8 +26,10 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import reactor.util.function.Tuple2; import static org.lowcoder.api.util.Pagination.fluxToPageResponseView; +import static org.lowcoder.plugin.api.event.LowcoderEvent.EventType.DATA_SOURCE_UPDATE; @RestController public class LibraryQueryController implements LibraryQueryEndpoints @@ -37,6 +43,8 @@ public class LibraryQueryController implements LibraryQueryEndpoints private BusinessEventPublisher businessEventPublisher; @Autowired private GidService gidService; + @Autowired + private LibraryQueryRecordService libraryQueryRecordService; @Override public Mono>> dropDownList(@RequestParam(required = false, defaultValue = "") String name) { @@ -64,16 +72,20 @@ public Mono> create(@RequestBody LibraryQuery lib return libraryQueryApiService.create(libraryQuery) .delayUntil(libraryQueryView -> businessEventPublisher.publishLibraryQueryEvent(libraryQueryView.id(), libraryQueryView.name(), - EventType.LIBRARY_QUERY_CREATE)) + EventType.LIBRARY_QUERY_CREATE, null)) .map(ResponseView::success); } @Override public Mono> update(@PathVariable String libraryQueryId, - @RequestBody UpsertLibraryQueryRequest upsertLibraryQueryRequest) { + @RequestBody UpsertLibraryQueryRequest request) { return gidService.convertLibraryQueryIdToObjectId(libraryQueryId).flatMap(objectId -> - libraryQueryApiService.update(objectId, upsertLibraryQueryRequest) - .map(ResponseView::success)); + libraryQueryService.getById(objectId).flatMap(orgLibraryQuery -> + libraryQueryApiService.update(objectId, request) + .zipWith( libraryQueryService.getById(objectId)) + .delayUntil(tuple -> businessEventPublisher.publishLibraryQueryEvent(tuple.getT2().getId(), tuple.getT2().getName(), EventType.LIBRARY_QUERY_UPDATE, orgLibraryQuery.getName())) + .map(Tuple2::getT1) + .map(ResponseView::success))); } @Override @@ -82,7 +94,7 @@ public Mono> delete(@PathVariable String libraryQueryId) { libraryQueryService.getById(objectId) .delayUntil(__ -> libraryQueryApiService.delete(objectId)) .delayUntil(libraryQuery -> businessEventPublisher.publishLibraryQueryEvent(libraryQuery.getId(), libraryQuery.getName(), - EventType.LIBRARY_QUERY_DELETE)) + EventType.LIBRARY_QUERY_DELETE, libraryQuery.getName())) .thenReturn(ResponseView.success(true))); } @@ -90,10 +102,11 @@ public Mono> delete(@PathVariable String libraryQueryId) { public Mono> publish(@PathVariable String libraryQueryId, @RequestBody LibraryQueryPublishRequest libraryQueryPublishRequest) { return gidService.convertLibraryQueryIdToObjectId(libraryQueryId).flatMap(objectId -> - libraryQueryApiService.publish(objectId, libraryQueryPublishRequest) - .delayUntil(__ -> libraryQueryService.getById(objectId) - .flatMap(libraryQuery -> businessEventPublisher.publishLibraryQuery(libraryQuery, EventType.LIBRARY_QUERY_PUBLISH))) - .map(ResponseView::success)); + libraryQueryRecordService.getLatestRecordByLibraryQueryId(objectId).map(LibraryQueryRecord::getTag).defaultIfEmpty("").flatMap(oldVersion -> + libraryQueryApiService.publish(objectId, libraryQueryPublishRequest) + .delayUntil(__ -> libraryQueryService.getById(objectId) + .flatMap(libraryQuery -> businessEventPublisher.publishLibraryQueryPublishEvent(libraryQueryId, oldVersion.isEmpty()?null:oldVersion, libraryQueryPublishRequest.tag(), EventType.LIBRARY_QUERY_PUBLISH))) + .map(ResponseView::success))); } } diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/util/BusinessEventPublisher.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/util/BusinessEventPublisher.java index 69af10325d..ee878ffe9a 100644 --- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/util/BusinessEventPublisher.java +++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/util/BusinessEventPublisher.java @@ -10,6 +10,7 @@ import org.lowcoder.api.application.view.ApplicationPublishRequest; import org.lowcoder.api.application.view.ApplicationView; import org.lowcoder.api.home.SessionUserService; +import org.lowcoder.api.permission.view.CommonPermissionView; import org.lowcoder.api.usermanagement.view.AddMemberRequest; import org.lowcoder.api.usermanagement.view.UpdateRoleRequest; import org.lowcoder.domain.application.model.Application; @@ -29,10 +30,7 @@ import org.lowcoder.domain.query.model.LibraryQuery; import org.lowcoder.domain.user.model.User; import org.lowcoder.domain.user.service.UserService; -import org.lowcoder.infra.event.ApplicationCommonEvent; -import org.lowcoder.infra.event.FolderCommonEvent; -import org.lowcoder.infra.event.LibraryQueryEvent; -import org.lowcoder.infra.event.QueryExecutionEvent; +import org.lowcoder.infra.event.*; import org.lowcoder.infra.event.datasource.DatasourceEvent; import org.lowcoder.infra.event.datasource.DatasourcePermissionEvent; import org.lowcoder.infra.event.group.GroupCreateEvent; @@ -49,8 +47,11 @@ import org.lowcoder.sdk.constants.Authentication; import org.lowcoder.sdk.util.LocaleUtils; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.data.redis.connection.zset.Tuple; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; +import reactor.util.function.Tuple3; +import reactor.util.function.Tuples; import java.nio.charset.StandardCharsets; import java.util.*; @@ -72,7 +73,7 @@ public class BusinessEventPublisher { private final ResourcePermissionService resourcePermissionService; private final ApplicationRecordServiceImpl applicationRecordServiceImpl; - public Mono publishFolderCommonEvent(String folderId, String folderName, EventType eventType) { + public Mono publishFolderCommonEvent(String folderId, String folderName, String fromName, EventType eventType) { return sessionUserService.getVisitorToken() .zipWith(sessionUserService.getVisitorOrgMemberCache()) @@ -86,6 +87,7 @@ public Mono publishFolderCommonEvent(String folderId, String folderName, E .userId(orgMember.getUserId()) .orgId(orgMember.getOrgId()) .type(eventType) + .fromName(fromName) .isAnonymous(Authentication.isAnonymousUser(orgMember.getUserId())) .sessionHash(Hashing.sha512().hashString(token, StandardCharsets.UTF_8).toString()) .build(); @@ -102,7 +104,7 @@ public Mono publishFolderCommonEvent(String folderId, String folderName, E }); } - public Mono publishApplicationCommonEvent(String applicationId, @Nullable String folderIdFrom, @Nullable String folderId, EventType eventType) { + public Mono publishApplicationCommonEvent(ApplicationView originalApplicationView, String applicationId, @Nullable String folderIdFrom, @Nullable String folderId, EventType eventType) { return applicationService.findByIdWithoutDsl(applicationId) .map(application -> { ApplicationInfoView applicationInfoView = ApplicationInfoView.builder() @@ -116,10 +118,10 @@ public Mono publishApplicationCommonEvent(String applicationId, @Nullable .build(); }) - .flatMap(applicationView -> publishApplicationCommonEvent(applicationView, eventType)); + .flatMap(applicationView -> publishApplicationCommonEvent(originalApplicationView, applicationView, eventType)); } - public Mono publishApplicationCommonEvent(ApplicationView applicationView, EventType eventType) { + public Mono publishApplicationCommonEvent(ApplicationView originalApplicationView, ApplicationView applicationView, EventType eventType) { return sessionUserService.isAnonymousUser() .flatMap(anonymous -> { if (anonymous) { @@ -150,10 +152,12 @@ public Mono publishApplicationCommonEvent(ApplicationView applicationView, return applicationService.findById(appId) .zipWhen(application -> application.getCategory(applicationRecordServiceImpl)) .zipWhen(application -> application.getT1().getDescription(applicationRecordServiceImpl)) + .zipWhen(application -> application.getT1().getT1().getTitle(applicationRecordServiceImpl)) .map(tuple -> { - String category = tuple.getT1().getT2(); - String description = tuple.getT2(); - return Pair.of(category, description); + String category = tuple.getT1().getT1().getT2(); + String description = tuple.getT1().getT2(); + String title = tuple.getT2(); + return new String[]{category, description, title}; }); }), TupleUtils::merge) .flatMap(tuple -> Mono.deferContextual(contextView -> { @@ -161,8 +165,9 @@ public Mono publishApplicationCommonEvent(ApplicationView applicationView, Optional optional = tuple.getT1().getT2(); Optional optionalFrom = tuple.getT1().getT3(); String token = tuple.getT2(); - String category = tuple.getT3().getLeft(); - String description = tuple.getT3().getRight(); + String category = tuple.getT3()[0]; + String description = tuple.getT3()[1]; + String title = tuple.getT3()[2]; ApplicationInfoView applicationInfoView = applicationView.getApplicationInfoView(); ApplicationCommonEvent event = ApplicationCommonEvent.builder() @@ -173,6 +178,11 @@ public Mono publishApplicationCommonEvent(ApplicationView applicationView, .applicationName(applicationInfoView.getName()) .applicationCategory(category) .applicationDescription(description) + .applicationTitle(title) + .oldApplicationName(originalApplicationView!=null ? originalApplicationView.getApplicationInfoView().getName() : null) + .oldApplicationCategory(originalApplicationView!=null ?originalApplicationView.getApplicationInfoView().getCategory() : null) + .oldApplicationDescription(originalApplicationView!=null ?originalApplicationView.getApplicationInfoView().getDescription() : null) + .oldApplicationTitle(originalApplicationView!=null ?originalApplicationView.getApplicationInfoView().getTitle() : null) .type(eventType) .folderId(optional.map(Folder::getId).orElse(null)) .folderName(optional.map(Folder::getName).orElse(null)) @@ -470,7 +480,8 @@ public Mono publishGroupUpdateEvent(boolean publish, Group previousGroup, .orgId(tuple.getT1().getOrgId()) .userId(tuple.getT1().getUserId()) .groupId(previousGroup.getId()) - .groupName(previousGroup.getName(locale) + " => " + newGroupName) + .groupName(newGroupName) + .oldGroupName(previousGroup.getName(locale)) .isAnonymous(Authentication.isAnonymousUser(tuple.getT1().getUserId())) .sessionHash(Hashing.sha512().hashString(tuple.getT2(), StandardCharsets.UTF_8).toString()) .build(); @@ -572,7 +583,8 @@ public Mono publishGroupMemberRoleUpdateEvent(boolean publish, String grou .groupName(group.getName(locale)) .memberId(member.getId()) .memberName(member.getName()) - .memberRole(previousGroupMember.getRole().getValue() + " => " + updateRoleRequest.getRole()) + .memberRole(updateRoleRequest.getRole()) + .oldMemberRole(previousGroupMember.getRole().getValue()) .isAnonymous(Authentication.isAnonymousUser(orgMember.getUserId())) .sessionHash(Hashing.sha512().hashString(tuple.getT4(), StandardCharsets.UTF_8).toString()) .build(); @@ -663,16 +675,16 @@ public void publishQueryExecutionEvent(QueryExecutionEvent queryExecutionEvent) applicationEventPublisher.publishEvent(queryExecutionEvent); } - public Mono publishDatasourceEvent(String id, EventType eventType) { + public Mono publishDatasourceEvent(String id, EventType eventType, String oldName) { return datasourceService.getById(id) - .flatMap(datasource -> publishDatasourceEvent(datasource, eventType)) + .flatMap(datasource -> publishDatasourceEvent(datasource, eventType, oldName)) .onErrorResume(throwable -> { log.error("publishDatasourceEvent error.", throwable); return Mono.empty(); }); } - public Mono publishDatasourceEvent(Datasource datasource, EventType eventType) { + public Mono publishDatasourceEvent(Datasource datasource, EventType eventType, String oldName) { return sessionUserService.getVisitorOrgMemberCache() .zipWith(sessionUserService.getVisitorToken()) .flatMap(tuple -> { @@ -680,6 +692,7 @@ public Mono publishDatasourceEvent(Datasource datasource, EventType eventT .datasourceId(datasource.getId()) .name(datasource.getName()) .type(datasource.getType()) + .oldName(oldName) .eventType(eventType) .userId(tuple.getT1().getUserId()) .orgId(tuple.getT1().getOrgId()) @@ -698,34 +711,16 @@ public Mono publishDatasourceEvent(Datasource datasource, EventType eventT }); } - public Mono publishDatasourcePermissionEvent(String permissionId, EventType eventType) { - return resourcePermissionService.getById(permissionId) - .zipWhen(resourcePermission -> datasourceService.getById(resourcePermission.getResourceId())) - .flatMap(tuple -> { - ResourcePermission resourcePermission = tuple.getT1(); - ResourceHolder holder = resourcePermission.getResourceHolder(); - Datasource datasource = tuple.getT2(); - return publishDatasourcePermissionEvent(datasource.getId(), - holder == USER ? List.of(resourcePermission.getResourceHolderId()) : Collections.emptyList(), - holder == USER ? Collections.emptyList() : List.of(resourcePermission.getResourceHolderId()), - resourcePermission.getResourceRole().getValue(), - eventType); - }) - .onErrorResume(throwable -> { - log.error("publishDatasourcePermissionEvent error.", throwable); - return Mono.empty(); - }); - } - public Mono publishDatasourcePermissionEvent(String datasourceId, Collection userIds, Collection groupIds, String role, - EventType eventType) { + EventType eventType, CommonPermissionView oldPermissions, CommonPermissionView newPermissions) { return Mono.zip(sessionUserService.getVisitorOrgMemberCache(), datasourceService.getById(datasourceId), sessionUserService.getVisitorToken()) .flatMap(tuple -> { OrgMember orgMember = tuple.getT1(); Datasource datasource = tuple.getT2(); + DatasourcePermissionEvent datasourcePermissionEvent = DatasourcePermissionEvent.builder() .datasourceId(datasourceId) .name(datasource.getName()) @@ -734,6 +729,8 @@ public Mono publishDatasourcePermissionEvent(String datasourceId, .orgId(orgMember.getOrgId()) .userIds(userIds) .groupIds(groupIds) + .newPermissions(newPermissions==null?null:newPermissions.getPermissions()) + .oldPermissions(oldPermissions==null?null:oldPermissions.getPermissions()) .role(role) .eventType(eventType) .isAnonymous(Authentication.isAnonymousUser(orgMember.getUserId())) @@ -751,11 +748,65 @@ public Mono publishDatasourcePermissionEvent(String datasourceId, }); } - public Mono publishLibraryQuery(LibraryQuery libraryQuery, EventType eventType) { - return publishLibraryQueryEvent(libraryQuery.getId(), libraryQuery.getName(), eventType); + public Mono publishDatasourceResourcePermissionEvent(EventType eventType, ResourcePermission oldPermission, ResourcePermission newPermission) { + return Mono.zip(sessionUserService.getVisitorOrgMemberCache(), + datasourceService.getById(oldPermission.getResourceId()), + sessionUserService.getVisitorToken()) + .flatMap(tuple -> { + OrgMember orgMember = tuple.getT1(); + Datasource datasource = tuple.getT2(); + + DatasourceResourcePermissionEvent datasourceResourcePermissionEvent = DatasourceResourcePermissionEvent.builder() + .name(datasource.getName()) + .type(datasource.getType()) + .userId(orgMember.getUserId()) + .orgId(orgMember.getOrgId()) + .newPermission(newPermission) + .oldPermission(oldPermission) + .eventType(eventType) + .isAnonymous(Authentication.isAnonymousUser(orgMember.getUserId())) + .sessionHash(Hashing.sha512().hashString(tuple.getT3(), StandardCharsets.UTF_8).toString()) + .build(); + return Mono.deferContextual(contextView -> { + datasourceResourcePermissionEvent.populateDetails(contextView); + applicationEventPublisher.publishEvent(datasourceResourcePermissionEvent); + return Mono.empty(); + }); + }) + .onErrorResume(throwable -> { + log.error("DatasourceResourcePermissionEvent error.", throwable); + return Mono.empty(); + }); + } + + public Mono publishLibraryQueryPublishEvent(String id, String oldVersion, String newVersion, EventType eventType) { + return sessionUserService.getVisitorOrgMemberCache() + .zipWith(sessionUserService.getVisitorToken()) + .flatMap(tuple -> { + LibraryQueryPublishEvent event = LibraryQueryPublishEvent.builder() + .id(id) + .oldVersion(oldVersion) + .newVersion(newVersion) + .eventType(eventType) + .userId(tuple.getT1().getUserId()) + .orgId(tuple.getT1().getOrgId()) + .isAnonymous(Authentication.isAnonymousUser(tuple.getT1().getUserId())) + .sessionHash(Hashing.sha512().hashString(tuple.getT2(), StandardCharsets.UTF_8).toString()) + .build(); + return Mono.deferContextual(contextView -> { + event.populateDetails(contextView); + applicationEventPublisher.publishEvent(event); + return Mono.empty(); + }); + }) + .then() + .onErrorResume(throwable -> { + log.error("publishLibraryQueryPublishEvent error.", throwable); + return Mono.empty(); + }); } - public Mono publishLibraryQueryEvent(String id, String name, EventType eventType) { + public Mono publishLibraryQueryEvent(String id, String name, EventType eventType, String oldName) { return sessionUserService.getVisitorOrgMemberCache() .zipWith(sessionUserService.getVisitorToken()) .flatMap(tuple -> { @@ -764,6 +815,7 @@ public Mono publishLibraryQueryEvent(String id, String name, EventType eve .orgId(tuple.getT1().getOrgId()) .id(id) .name(name) + .oldName(oldName) .eventType(eventType) .isAnonymous(Authentication.isAnonymousUser(tuple.getT1().getUserId())) .sessionHash(Hashing.sha512().hashString(tuple.getT2(), StandardCharsets.UTF_8).toString())