Skip to content

Meta api for database objects #1551

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

Merged
merged 5 commits into from
Mar 3, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class Application extends HasIdAndAuditing {
private Integer applicationType;
private ApplicationStatus applicationStatus;

@Setter
private Map<String, Object> editingApplicationDSL;

@Setter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
public interface BundleRepository extends ReactiveMongoRepository<Bundle, String> {
Mono<Void> deleteAllByGid(Collection<String> gids);
Flux<Bundle> findByGid(@Nonnull String gid);
Flux<Bundle> findAllByGid(Collection<String> gids);

Flux<Bundle> findByCreatedBy(String userId);
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public interface BundleService {
Mono<Boolean> updateById(String id, Bundle resource);

Mono<Bundle> findById(String id);
Flux<Bundle> findByIdIn(Collection<String> ids);

Mono<Bundle> findByIdWithoutDsl(String id);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -56,6 +57,15 @@ public Mono<Bundle> findById(String id) {
.switchIfEmpty(Mono.error(new BizException(BizError.NO_RESOURCE_FOUND, "BUNDLE_NOT_FOUND", id)));
}

@Override
public Flux<Bundle> findByIdIn(Collection<String> ids) {
Optional<String> first = ids.stream().findFirst();
if(first.isPresent() && FieldName.isGID(first.get()))
return repository.findAllByGid(ids);

return repository.findAllById(ids);
}

@Override
public Mono<Bundle> findByIdWithoutDsl(String id) {
if (id == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ public Mono<Datasource> findById(String datasourceId) {
.flatMap(this::convertToDomainObjectAndDecrypt);
}

public Flux<Datasource> findByIds(Collection<String> datasourceIds) {
Optional<String> first = datasourceIds.stream().findAny();
if(first.isPresent() && FieldName.isGID(first.get()))
return repository.findAllByGidIn(datasourceIds)
.flatMap(this::convertToDomainObjectAndDecrypt);
return repository.findAllById(datasourceIds)
.flatMap(this::convertToDomainObjectAndDecrypt);
}

public Mono<Datasource> findWorkspacePredefinedDatasourceByOrgIdAndType(String organizationId, String type) {
return repository.findByOrganizationIdAndTypeAndCreationSource(organizationId, type,
DatasourceCreationSource.LEGACY_WORKSPACE_PREDEFINED.getValue())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public interface DatasourceService {
Mono<Datasource> update(String id, Datasource resource);

Mono<Datasource> getById(String id);
Flux<Datasource> getByIds(Collection<String> ids);

Mono<Boolean> delete(String id);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,32 @@ public Mono<Datasource> getById(String id) {
return repository.findById(id);
}

@Override
public Flux<Datasource> getByIds(Collection<String> ids) {
Flux<Datasource> builtDatasourceFlux = Flux.fromStream(ids.stream().filter(id-> StringUtils.equals(id, Datasource.QUICK_REST_API_ID)
|| StringUtils.equals(id, Datasource.QUICK_GRAPHQL_ID)
|| StringUtils.equals(id, Datasource.LOWCODER_API_ID)
).map(id-> {
if (StringUtils.equals(id, Datasource.QUICK_REST_API_ID)) {
return Datasource.QUICK_REST_API;
}

if (StringUtils.equals(id, Datasource.QUICK_GRAPHQL_ID)) {
return Datasource.QUICK_GRAPHQL_API;
}

if (StringUtils.equals(id, Datasource.LOWCODER_API_ID)) {
return Datasource.LOWCODER_API;
}
return Datasource.LOWCODER_API;
}));

return Flux.concat(builtDatasourceFlux, repository.findByIds(ids.stream().filter(id-> !(StringUtils.equals(id, Datasource.QUICK_REST_API_ID)
|| StringUtils.equals(id, Datasource.QUICK_GRAPHQL_ID)
|| StringUtils.equals(id, Datasource.LOWCODER_API_ID))
).toList()));
}

private Mono<Datasource> validateDatasource(Datasource datasource) {

if (datasource.getOrganizationId() == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ public interface FolderRepository extends ReactiveMongoRepository<Folder, String

Flux<Folder> findByOrganizationId(String organizationId);
Flux<Folder> findByGid(String organizationGid);
Flux<Folder> findByGidIn(Collection<String> ids);
Mono<Void> deleteAllByGid(Collection<String> gids);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public interface FolderService {

Mono<Folder> findById(String id);

Flux<Folder> findByIds(Collection<String> ids);

Mono<Folder> create(Folder folder);

Flux<Folder> findByOrganizationId(String organizationId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.lowcoder.domain.folder.service;

import static org.lowcoder.domain.organization.model.OrganizationState.ACTIVE;
import static org.lowcoder.sdk.exception.BizError.NO_RESOURCE_FOUND;

import java.util.Collection;
Expand Down Expand Up @@ -46,6 +47,13 @@ public Mono<Folder> findById(String id) {
.switchIfEmpty(Mono.error(new BizException(BizError.NO_RESOURCE_FOUND, "FOLDER_NOT_FOUND", id)));
}

@Override
public Flux<Folder> findByIds(Collection<String> ids) {
if(!ids.isEmpty() && FieldName.isGID(ids.stream().findFirst().get()))
return repository.findByGidIn(ids);
return repository.findAllById(ids);
}

@Override
public Mono<Folder> create(Folder folder) {
return repository.save(folder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Collection;

@Repository
public interface LibraryQueryRepository extends ReactiveMongoRepository<LibraryQuery, String> {

Expand All @@ -14,4 +16,5 @@ public interface LibraryQueryRepository extends ReactiveMongoRepository<LibraryQ
Mono<LibraryQuery> findByName(String name);
Mono<Void> deleteByGid(String gid);
Flux<LibraryQuery> findByGid(String gid);
Flux<LibraryQuery> findByGidIn(Collection<String> gids);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Collection;
import java.util.Map;

public interface LibraryQueryService {
Mono<LibraryQuery> getById(String libraryQueryId);
Flux<LibraryQuery> getByIds(Collection<String> libraryQueryIds);

Mono<LibraryQuery> getByName(String libraryQueryName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Collection;
import java.util.Map;
import java.util.Optional;

import static org.lowcoder.sdk.exception.BizError.LIBRARY_QUERY_NOT_FOUND;
import static org.lowcoder.sdk.util.ExceptionUtils.deferredError;
Expand All @@ -35,6 +37,14 @@ public Mono<LibraryQuery> getById(String libraryQueryId) {
.switchIfEmpty(deferredError(LIBRARY_QUERY_NOT_FOUND, "LIBRARY_QUERY_NOT_FOUND"));
}

@Override
public Flux<LibraryQuery> getByIds(Collection<String> libraryQueryIds) {
Optional<String> first = libraryQueryIds.stream().findFirst();
if(first.isPresent() && FieldName.isGID(first.get()))
return libraryQueryRepository.findByGidIn(libraryQueryIds);
return libraryQueryRepository.findAllById(libraryQueryIds);
}

@Override
public Mono<LibraryQuery> getByName(String libraryQueryName) {
return libraryQueryRepository.findByName(libraryQueryName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ private NewUrl() {
public static final String NPM_REGISTRY = PREFIX + "/npm";

public static final String PLUGINS_URL = PREFIX + "/plugins";
public static final String META_URL = PREFIX + "/meta";
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ public final class Url {
public static final String APPLICATION_URL = BASE_URL + VERSION + "/applications";
public static final String QUERY_URL = BASE_URL + VERSION + "/query";
public static final String STATE_URL = BASE_URL + VERSION + "/state";
public static final String META_URL = BASE_URL + VERSION + "/meta";

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package org.lowcoder.api.meta;

import lombok.RequiredArgsConstructor;
import org.lowcoder.api.application.ApplicationApiService;
import org.lowcoder.api.framework.view.ResponseView;
import org.lowcoder.api.meta.view.*;
import org.lowcoder.domain.application.model.Application;
import org.lowcoder.domain.application.service.ApplicationRecordService;
import org.lowcoder.domain.application.service.ApplicationServiceImpl;
import org.lowcoder.domain.bundle.model.Bundle;
import org.lowcoder.domain.bundle.service.BundleServiceImpl;
import org.lowcoder.domain.datasource.model.Datasource;
import org.lowcoder.domain.datasource.service.impl.DatasourceServiceImpl;
import org.lowcoder.domain.folder.model.Folder;
import org.lowcoder.domain.folder.service.FolderServiceImpl;
import org.lowcoder.domain.group.model.Group;
import org.lowcoder.domain.group.service.GroupServiceImpl;
import org.lowcoder.domain.organization.model.Organization;
import org.lowcoder.domain.organization.service.OrganizationServiceImpl;
import org.lowcoder.domain.query.model.LibraryQuery;
import org.lowcoder.domain.query.service.LibraryQueryServiceImpl;
import org.lowcoder.domain.user.model.User;
import org.lowcoder.domain.user.service.UserServiceImpl;
import org.lowcoder.sdk.util.LocaleUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RequiredArgsConstructor
@RestController
public class MetaController implements MetaEndpoints {
private final ApplicationApiService applicationApiService;
private final ApplicationServiceImpl applicationServiceImpl;
private final UserServiceImpl userServiceImpl;
private final OrganizationServiceImpl organizationServiceImpl;
private final FolderServiceImpl folderServiceImpl;
private final DatasourceServiceImpl datasourceServiceImpl;
private final BundleServiceImpl bundleServiceImpl;
private final GroupServiceImpl groupServiceImpl;
private final LibraryQueryServiceImpl libraryQueryServiceImpl;
private final ApplicationRecordService applicationRecordService;

@Override
public Mono<ResponseView<MetaView>> getMetaData(@RequestBody GetMetaDataRequest param) {
Flux<ApplicationMetaView> appsFlux = applicationServiceImpl.findByIdIn(param.appIds()).flatMap(app -> ApplicationMetaView.of(app, applicationRecordService));
Flux<UserMetaView> usersFlux = userServiceImpl.getByIds(param.userIds()).flatMapMany(map -> Flux.fromIterable(map.values())).map(UserMetaView::of);
Flux<OrgMetaView> orgsFlux = organizationServiceImpl.getByIds(param.orgIds()).map(OrgMetaView::of);
Flux<FolderMetaView> foldersFlux = folderServiceImpl.findByIds(param.folderIds()).map(FolderMetaView::of);
Flux<DatasourceMetaView> datasourcesFlux = datasourceServiceImpl.getByIds(param.datasourceIds()).map(DatasourceMetaView::of);
Flux<BundleMetaView> bundlesFlux = bundleServiceImpl.findByIdIn(param.bundleIds()).map(BundleMetaView::of);
Flux<GroupMetaView> groupsFlux = Flux.deferContextual(contextView -> groupServiceImpl.getByIds(param.groupIds()).map(group -> GroupMetaView.of(group, LocaleUtils.getLocale(contextView))));
Flux<LibraryQueryMetaView> queriesFlux = libraryQueryServiceImpl.getByIds(param.libraryQueryIds()).map(LibraryQueryMetaView::of);
return Mono.zip(
appsFlux.collectList(),
usersFlux.collectList(),
orgsFlux.collectList(),
foldersFlux.collectList(),
datasourcesFlux.collectList(),
bundlesFlux.collectList(),
groupsFlux.collectList(),
queriesFlux.collectList()
).map(tuple -> MetaView.builder()
.apps(tuple.getT1())
.users(tuple.getT2())
.orgs(tuple.getT3())
.folders(tuple.getT4())
.datasources(tuple.getT5())
.bundles(tuple.getT6())
.groups(tuple.getT7())
.queries(tuple.getT8())
.build())
.map(ResponseView::success);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.lowcoder.api.meta;

import io.swagger.v3.oas.annotations.Operation;
import org.lowcoder.api.framework.view.ResponseView;
import org.lowcoder.api.meta.view.MetaView;
import org.lowcoder.infra.constant.NewUrl;
import org.lowcoder.infra.constant.Url;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.util.List;

@RestController
@RequestMapping(value = {Url.META_URL, NewUrl.META_URL})
public interface MetaEndpoints
{
public static final String TAG_META_MANAGEMENT = "Meta APIs";

@Operation(
tags = TAG_META_MANAGEMENT,
operationId = "getMetaData",
summary = "Get metadata by ids",
description = "Get all metadatas by ids"
)
@PostMapping("/")
public Mono<ResponseView<MetaView>> getMetaData(@RequestBody GetMetaDataRequest param);

public record GetMetaDataRequest(List<String> appIds,
List<String> orgIds,
List<String> userIds,
List<String> groupIds,
List<String> bundleIds,
List<String> datasourceIds,
List<String> folderIds,
List<String> libraryQueryIds) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.lowcoder.api.meta.view;

import lombok.Getter;
import lombok.experimental.SuperBuilder;
import org.lowcoder.domain.application.model.Application;
import org.lowcoder.domain.application.service.ApplicationRecordService;
import reactor.core.publisher.Mono;

@SuperBuilder
@Getter
public class ApplicationMetaView {
private String id;
private String name;
private String title;
private String description;
private String category;
private String icon;

public static Mono<ApplicationMetaView> of(Application app, ApplicationRecordService applicationRecordService) {
return Mono.zip(app.getTitle(applicationRecordService),
app.getDescription(applicationRecordService),
app.getCategory(applicationRecordService),
app.getIcon(applicationRecordService)).map(tuple ->
ApplicationMetaView.builder()
.id(app.getId())
.name(app.getName())
.title(tuple.getT1())
.description(tuple.getT2())
.category(tuple.getT3())
.icon(tuple.getT4())
.build());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.lowcoder.api.meta.view;

import lombok.Getter;
import lombok.experimental.SuperBuilder;
import org.lowcoder.domain.bundle.model.Bundle;

@SuperBuilder
@Getter
public class BundleMetaView {
private String id;
private String name;

public static BundleMetaView of(Bundle bundle) {
return BundleMetaView.builder()
.id(bundle.getId())
.name(bundle.getName())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.lowcoder.api.meta.view;

import lombok.Getter;
import lombok.experimental.SuperBuilder;
import org.lowcoder.domain.datasource.model.Datasource;

@SuperBuilder
@Getter
public class DatasourceMetaView {
private String id;
private String name;

public static DatasourceMetaView of(Datasource datasource) {
return DatasourceMetaView.builder()
.id(datasource.getId())
.name(datasource.getName())
.build();
}
}
Loading
Loading