From 5ae882765b0e59714673b77c0d327a399c91ac64 Mon Sep 17 00:00:00 2001 From: Nidhi Date: Wed, 29 Nov 2023 18:39:56 +0530 Subject: [PATCH] chore: Split for custom js libs with local scope (#29216) --- .../external/models/CreatorContextType.java | 2 + .../appsmith/server/domains/CustomJSLib.java | 80 +------------- .../server/domains/ce/CustomJSLibCE.java | 103 ++++++++++++++++++ .../dtos/CustomJSLibApplicationDTO.java | 34 +----- .../dtos/ce/CustomJSLibApplicationCE_DTO.java | 40 +++++++ .../jslibs/base/CustomJSLibServiceCEImpl.java | 17 ++- .../ce/CustomJSLibRepositoryCE.java | 9 +- .../ce/CustomJSLibRepositoryCEImpl.java | 31 ++++-- 8 files changed, 188 insertions(+), 128 deletions(-) create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/CustomJSLibCE.java create mode 100644 app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/CustomJSLibApplicationCE_DTO.java diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/CreatorContextType.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/CreatorContextType.java index bb2dd48402..000cc9054d 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/CreatorContextType.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/models/CreatorContextType.java @@ -4,4 +4,6 @@ public enum CreatorContextType { PAGE, MODULE, WORKFLOW, + APPLICATION, + PACKAGE, } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/CustomJSLib.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/CustomJSLib.java index 2df2cb2435..dc21b7d3fe 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/CustomJSLib.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/CustomJSLib.java @@ -1,6 +1,6 @@ package com.appsmith.server.domains; -import com.appsmith.external.models.BranchAwareDomain; +import com.appsmith.server.domains.ce.CustomJSLibCE; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; @@ -9,9 +9,6 @@ import lombok.Setter; import lombok.ToString; import org.springframework.data.mongodb.core.mapping.Document; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import java.util.Set; @Getter @@ -19,34 +16,7 @@ import java.util.Set; @ToString @NoArgsConstructor @Document -public class CustomJSLib extends BranchAwareDomain { - /* Library name */ - String name; - - /** - * This string is used to uniquely identify a given library. We expect this to be universally unique for a given - * JS library - */ - String uidString; - - /** - * These are the namespaces under which the library functions reside. User would access lib methods like - * `accessor.method` - */ - Set accessor; - - /* Library UMD src url */ - String url; - - /* Library documentation page URL */ - String docsUrl; - - /* Library version */ - String version; - - /* `Tern` tool definitions - it defines the methods exposed by the library. It helps us with auto-complete - feature i.e. the function name showing up as suggestion when user has partially typed it. */ - String defs; +public class CustomJSLib extends CustomJSLibCE { @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) public CustomJSLib( @@ -56,50 +26,6 @@ public class CustomJSLib extends BranchAwareDomain { @JsonProperty("docsUrl") String docsUrl, @JsonProperty("version") String version, @JsonProperty("defs") String defs) { - this.name = name; - this.accessor = accessor; - this.url = url; - this.docsUrl = docsUrl; - this.defs = defs; - this.version = version; - setUidString(); - } - - public void setUidString() { - List accessorList = new ArrayList(this.accessor); - Collections.sort(accessorList); - this.uidString = String.join("_", accessorList) + "_" + this.url; - } - - /** - * The equality operator has been overridden here so that when two custom JS library objects are compared, they - * are compared based on their name and version as opposed to Java object reference. At the moment this check - * helps us to identify which JS library needs to be removed from the list of installed libraries when a user - * chooses to uninstall a library. It also helps us to identify if a library has already been added. - * Please note that this comment may have to be updated once the following issue is closed: - * https://github.com/appsmithorg/appsmith/issues/18226 - */ - @Override - public boolean equals(Object o) { - if (!(o instanceof CustomJSLib)) { - return false; - } - - /** - * We check the equality using the uidString since this is supposed to be unique for a given library. - */ - return ((CustomJSLib) o).getUidString().equals(this.uidString); - } - - @Override - public int hashCode() { - return this.uidString.hashCode(); - } - - @Override - public void sanitiseToExportDBObject() { - this.setId(null); - this.setCreatedAt(null); - this.setUpdatedAt(null); + super(name, accessor, url, docsUrl, version, defs); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/CustomJSLibCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/CustomJSLibCE.java new file mode 100644 index 0000000000..3f06f41b03 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/ce/CustomJSLibCE.java @@ -0,0 +1,103 @@ +package com.appsmith.server.domains.ce; + +import com.appsmith.external.models.BranchAwareDomain; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +@Getter +@Setter +@ToString +@NoArgsConstructor +public class CustomJSLibCE extends BranchAwareDomain { + /* Library name */ + String name; + + /** + * This string is used to uniquely identify a given library. We expect this to be universally unique for a given + * JS library + */ + String uidString; + + /** + * These are the namespaces under which the library functions reside. User would access lib methods like + * `accessor.method` + */ + Set accessor; + + /* Library UMD src url */ + String url; + + /* Library documentation page URL */ + String docsUrl; + + /* Library version */ + String version; + + /* `Tern` tool definitions - it defines the methods exposed by the library. It helps us with auto-complete + feature i.e. the function name showing up as suggestion when user has partially typed it. */ + String defs; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public CustomJSLibCE( + @JsonProperty("name") String name, + @JsonProperty("accessor") Set accessor, + @JsonProperty("url") String url, + @JsonProperty("docsUrl") String docsUrl, + @JsonProperty("version") String version, + @JsonProperty("defs") String defs) { + this.name = name; + this.accessor = accessor; + this.url = url; + this.docsUrl = docsUrl; + this.defs = defs; + this.version = version; + setUidString(); + } + + public void setUidString() { + List accessorList = new ArrayList(this.accessor); + Collections.sort(accessorList); + this.uidString = String.join("_", accessorList) + "_" + this.url; + } + + /** + * The equality operator has been overridden here so that when two custom JS library objects are compared, they + * are compared based on their name and version as opposed to Java object reference. At the moment this check + * helps us to identify which JS library needs to be removed from the list of installed libraries when a user + * chooses to uninstall a library. It also helps us to identify if a library has already been added. + * Please note that this comment may have to be updated once the following issue is closed: + * https://github.com/appsmithorg/appsmith/issues/18226 + */ + @Override + public boolean equals(Object o) { + if (!(o instanceof CustomJSLibCE)) { + return false; + } + + /** + * We check the equality using the uidString since this is supposed to be unique for a given library. + */ + return ((CustomJSLibCE) o).getUidString().equals(this.uidString); + } + + @Override + public int hashCode() { + return this.uidString.hashCode(); + } + + @Override + public void sanitiseToExportDBObject() { + this.setId(null); + this.setCreatedAt(null); + this.setUpdatedAt(null); + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/CustomJSLibApplicationDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/CustomJSLibApplicationDTO.java index da646c3d36..990517368e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/CustomJSLibApplicationDTO.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/CustomJSLibApplicationDTO.java @@ -1,39 +1,9 @@ package com.appsmith.server.dtos; -import com.appsmith.server.domains.CustomJSLib; +import com.appsmith.server.dtos.ce.CustomJSLibApplicationCE_DTO; import lombok.Getter; import lombok.Setter; @Getter @Setter -public class CustomJSLibApplicationDTO { - /** - * This string is used to uniquely identify a given library. We expect this to be universally unique for a given - * JS library - */ - String uidString; - - @Override - public boolean equals(Object o) { - if (!(o instanceof CustomJSLibApplicationDTO)) { - return false; - } - - /** - * We check the equality using the uidString since this is supposed to be unique for a given library. - */ - return ((CustomJSLibApplicationDTO) o).getUidString().equals(this.uidString); - } - - @Override - public int hashCode() { - return this.uidString.hashCode(); - } - - public static CustomJSLibApplicationDTO getDTOFromCustomJSLib(CustomJSLib jsLib) { - CustomJSLibApplicationDTO customJSLibApplicationDTO = new CustomJSLibApplicationDTO(); - customJSLibApplicationDTO.setUidString(jsLib.getUidString()); - - return customJSLibApplicationDTO; - } -} +public class CustomJSLibApplicationDTO extends CustomJSLibApplicationCE_DTO {} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/CustomJSLibApplicationCE_DTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/CustomJSLibApplicationCE_DTO.java new file mode 100644 index 0000000000..74bceb63ed --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/ce/CustomJSLibApplicationCE_DTO.java @@ -0,0 +1,40 @@ +package com.appsmith.server.dtos.ce; + +import com.appsmith.server.domains.CustomJSLib; +import com.appsmith.server.dtos.CustomJSLibApplicationDTO; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class CustomJSLibApplicationCE_DTO { + /** + * This string is used to uniquely identify a given library. We expect this to be universally unique for a given + * JS library + */ + String uidString; + + @Override + public boolean equals(Object o) { + if (!(o instanceof CustomJSLibApplicationCE_DTO)) { + return false; + } + + /** + * We check the equality using the uidString since this is supposed to be unique for a given library. + */ + return ((CustomJSLibApplicationCE_DTO) o).getUidString().equals(this.uidString); + } + + @Override + public int hashCode() { + return this.uidString.hashCode(); + } + + public static CustomJSLibApplicationDTO getDTOFromCustomJSLib(CustomJSLib jsLib) { + CustomJSLibApplicationDTO customJSLibApplicationDTO = new CustomJSLibApplicationDTO(); + customJSLibApplicationDTO.setUidString(jsLib.getUidString()); + + return customJSLibApplicationDTO; + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/base/CustomJSLibServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/base/CustomJSLibServiceCEImpl.java index f1e9252a82..a210c8afe1 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/base/CustomJSLibServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/jslibs/base/CustomJSLibServiceCEImpl.java @@ -1,5 +1,6 @@ package com.appsmith.server.jslibs.base; +import com.appsmith.external.models.CreatorContextType; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.CustomJSLib; import com.appsmith.server.dtos.CustomJSLibApplicationDTO; @@ -12,7 +13,6 @@ import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.data.mongodb.core.convert.MongoConverter; -import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.core.scheduler.Scheduler; @@ -74,7 +74,7 @@ public class CustomJSLibServiceCEImpl extends BaseService persistCustomJSLibMetaDataIfDoesNotExistAndGetDTO( CustomJSLib jsLib, Boolean isForceInstall) { return repository - .findByUidString(jsLib.getUidString()) + .findUniqueCustomJsLib(jsLib) .flatMap(foundJSLib -> { /* The first check is to make sure that we are able to detect any previously truncated data and overwrite it the next time we receive valid data. @@ -136,10 +136,9 @@ public class CustomJSLibServiceCEImpl extends BaseService> getAllCustomJSLibsFromApplication( String applicationId, String branchName, boolean isViewMode) { return getAllJSLibApplicationDTOFromApplication(applicationId, branchName, isViewMode) - .map(jsLibDTOSet -> - jsLibDTOSet.stream().map(dto -> dto.getUidString()).collect(Collectors.toList())) - .flatMapMany(Flux::fromIterable) - .flatMap(uidString -> repository.findByUidString(uidString)) + .map(this::filterAndMapGlobalUidStrings) + .flatMapMany(uidStrings -> + repository.findCustomJsLibsInContext(uidStrings, applicationId, CreatorContextType.APPLICATION)) .collectList() .map(jsLibList -> { Collections.sort(jsLibList, Comparator.comparing(CustomJSLib::getUidString)); @@ -147,6 +146,12 @@ public class CustomJSLibServiceCEImpl extends BaseService filterAndMapGlobalUidStrings(Set customJSLibApplicationDTOS) { + return customJSLibApplicationDTOS.stream() + .map(CustomJSLibApplicationDTO::getUidString) + .collect(Collectors.toSet()); + } + @Override public Mono> getAllJSLibApplicationDTOFromApplication( @NotNull String applicationId, String branchName, Boolean isViewMode) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomJSLibRepositoryCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomJSLibRepositoryCE.java index e79a56d958..c5fd916750 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomJSLibRepositoryCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomJSLibRepositoryCE.java @@ -1,9 +1,16 @@ package com.appsmith.server.repositories.ce; +import com.appsmith.external.models.CreatorContextType; import com.appsmith.server.domains.CustomJSLib; import com.appsmith.server.repositories.AppsmithRepository; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.util.Set; + public interface CustomJSLibRepositoryCE extends AppsmithRepository { - Mono findByUidString(String uidString); + Mono findUniqueCustomJsLib(CustomJSLib customJSLib); + + Flux findCustomJsLibsInContext( + Set uidStrings, String referenceId, CreatorContextType contextType); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomJSLibRepositoryCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomJSLibRepositoryCEImpl.java index 9d245ccdd2..e0d31c3af4 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomJSLibRepositoryCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/repositories/ce/CustomJSLibRepositoryCEImpl.java @@ -1,21 +1,24 @@ package com.appsmith.server.repositories.ce; +import com.appsmith.external.models.CreatorContextType; import com.appsmith.server.domains.CustomJSLib; +import com.appsmith.server.domains.QCustomJSLib; import com.appsmith.server.repositories.BaseAppsmithRepositoryImpl; import com.appsmith.server.repositories.CacheableRepositoryHelper; import org.springframework.data.mongodb.core.ReactiveMongoOperations; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.query.Criteria; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.Set; import static org.springframework.data.mongodb.core.query.Criteria.where; public class CustomJSLibRepositoryCEImpl extends BaseAppsmithRepositoryImpl implements CustomJSLibRepositoryCE { - private static final String UID_STRING_IDENTIFIER = "uidString"; public CustomJSLibRepositoryCEImpl( ReactiveMongoOperations mongoOperations, @@ -24,16 +27,20 @@ public class CustomJSLibRepositoryCEImpl extends BaseAppsmithRepositoryImpl findByUidString(String uidString) { - Criteria uidStringMatchCriteria = where(UID_STRING_IDENTIFIER).is(uidString); - ArrayList listOfCriteria = new ArrayList<>(); - listOfCriteria.add(uidStringMatchCriteria); - return queryOne(listOfCriteria, List.of()); + public Mono findUniqueCustomJsLib(CustomJSLib customJSLib) { + Criteria criteria = where(fieldName(QCustomJSLib.customJSLib.uidString)).is(customJSLib.getUidString()); + + return this.queryOne(List.of(criteria)); + } + + @Override + public Flux findCustomJsLibsInContext( + Set uidStrings, String contextId, CreatorContextType contextType) { + + Criteria criteria = + Criteria.where(fieldName(QCustomJSLib.customJSLib.uidString)).in(uidStrings); + + return this.queryAll(List.of(criteria), Optional.empty()); } }