Skip to content

Commit

Permalink
feat(perf) add ignore patterns for system/known pathes to prevent url…
Browse files Browse the repository at this point in the history
…map lookup (#26265)

* feat(perf) add ignore patterns for system/known pathes to prevent urlmap lookup

ref: #26263

* feat(perf) add ignore patterns for system/known pathes to prevent urlmap lookup

ref: #26263

* feat(perf) add ignore patterns for system/known pathes to prevent urlmap lookup

ref: #26263

* feat(perf) add ignore patterns for system/known pathes to prevent urlmap lookup

ref: #26263

* feat(perf) add ignore patterns for system/known pathes to prevent urlmap lookup
fixed glob pattern
ref: #26263

---------

Co-authored-by: Jose Castro <[email protected]>
  • Loading branch information
wezell and jcastro-dotcms authored Oct 3, 2023
1 parent 177fe24 commit 288ecb0
Showing 1 changed file with 43 additions and 49 deletions.
92 changes: 43 additions & 49 deletions dotCMS/src/main/java/com/dotmarketing/cms/urlmap/URLMapAPIImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@
import com.dotcms.variant.business.web.VariantWebAPI.RenderContext;
import com.dotmarketing.beans.Host;
import com.dotmarketing.beans.Identifier;
import com.dotmarketing.business.APILocator;
import com.dotmarketing.business.CacheLocator;
import com.dotmarketing.business.DotCacheException;
import com.dotmarketing.business.IdentifierAPI;
import com.dotmarketing.business.PermissionAPI;
import com.dotmarketing.business.PermissionLevel;
import com.dotmarketing.business.*;
import com.dotmarketing.business.web.UserWebAPI;
import com.dotmarketing.business.web.WebAPILocator;
import com.dotmarketing.exception.DotDataException;
Expand All @@ -27,38 +22,42 @@
import com.dotmarketing.portlets.contentlet.transform.DotTransformerBuilder;
import com.dotmarketing.portlets.structure.StructureUtil;
import com.dotmarketing.portlets.structure.model.SimpleStructureURLMap;
import com.dotmarketing.util.Logger;
import com.dotmarketing.util.PageMode;
import com.dotmarketing.util.RegEX;
import com.dotmarketing.util.RegExMatch;
import com.dotmarketing.util.UtilMethods;
import com.dotmarketing.util.*;
import com.liferay.util.StringPool;
import io.vavr.API;
import io.vavr.Lazy;
import io.vavr.control.Try;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.util.*;

/**
* Implementation for the {@link URLMapAPI}.
*
*/
public class URLMapAPIImpl implements URLMapAPI {

private final Collection<ContentTypeURLPattern> patternsCache= new ArrayList<>();
private final Collection<ContentTypeURLPattern> patternsCache = new ArrayList<>();
private final UserWebAPI wuserAPI = WebAPILocator.getUserWebAPI();
private final PermissionAPI permissionAPI = APILocator.getPermissionAPI();
private final IdentifierAPI identifierAPI = APILocator.getIdentifierAPI();
private final ContentTypeAPI typeAPI = APILocator.getContentTypeAPI(APILocator.systemUser());
private static final Lazy<PathMatcher[]> ignorePaths = Lazy.of(() -> {
String[] patterns = Config.getStringArrayProperty("urlmap.ignore.glob.patterns", new String[]{"/application/**", "/api/**", "/dA/**", "/dotAdmin/**", "/html/**"});
PathMatcher[] paths = new PathMatcher[patterns.length];
for (int i = 0; i < paths.length; i++) {
paths[i] = FileSystems.getDefault().getPathMatcher("glob:" + patterns[i]);
}
return paths;
});

@Override
public boolean isUrlPattern(final UrlMapContext urlMapContext)
throws DotDataException, DotSecurityException {
if (Arrays.stream(ignorePaths.get()).anyMatch(p -> p.matches(Path.of(urlMapContext.getUri())))) {
return false;
}
return getContentlet(urlMapContext) != null;
}

Expand All @@ -74,7 +73,7 @@ public Optional<URLMapInfo> processURLMap(final UrlMapContext context)
final ContentType contentType = contentlet.getContentType();
final Optional<Identifier> optDetailIdentifier = this.getDetailPageUri(contentType, context.getHost());

if(optDetailIdentifier.isEmpty()) {
if (optDetailIdentifier.isEmpty()) {
return Optional.empty();
}
return Optional.of(new URLMapInfo(contentlet, optDetailIdentifier.get(), context.getUri()));
Expand All @@ -84,7 +83,6 @@ public Optional<URLMapInfo> processURLMap(final UrlMapContext context)
* Returns the {@link Contentlet} object that matches the {@link UrlMapContext#getUri()} of a specific URL Map.
*
* @param urlMapContext The instance of the URL Map Context.
*
* @return The Contentlet matching the URL Map. If no match is found, a {@code null} object is returned.
*/
private Contentlet getContentlet(final UrlMapContext urlMapContext) throws DotSecurityException {
Expand Down Expand Up @@ -121,7 +119,7 @@ private Optional<Identifier> getDetailPageUri(final ContentType contentType, Hos
if (contentType == null || UtilMethods.isEmpty(contentType.detailPage())) {
return Optional.empty();
}

try {
final Identifier identifier = this.identifierAPI.find(contentType.detailPage());
if (identifier == null || !UtilMethods.isSet(identifier.getId())) {
Expand All @@ -131,12 +129,12 @@ private Optional<Identifier> getDetailPageUri(final ContentType contentType, Hos
.detailPage());
return Optional.empty();
}

//if the detail page is on this host, send it!
if(identifier.getHostId().equals(currentHost.getIdentifier())) {
if (identifier.getHostId().equals(currentHost.getIdentifier())) {
return Optional.of(identifier);
}

// look for it on the current host
final Identifier myHostIdentifier = this.identifierAPI.find(currentHost, identifier.getPath());
if (myHostIdentifier == null || !UtilMethods.isSet(myHostIdentifier.getId())) {
Expand All @@ -151,8 +149,8 @@ private Optional<Identifier> getDetailPageUri(final ContentType contentType, Hos
Logger.warnAndDebug(this.getClass(), e);
return Optional.empty();
}
}
}


/**
* Return all the matches related to a given URI, multiple content types could use the URLMap
Expand Down Expand Up @@ -209,11 +207,10 @@ private List<Matches> findMatch(final String uri) throws DotDataException {
*
* @param contentType The Content Type that the URL Map belongs to.
* @param matches The fields that are referenced byt the URL Map.
*
* @return The fields from the Content Type that match the fields referenced in the URL Map.
*/
private String buildFields(final ContentType contentType,
final Matches matches) {
final Matches matches) {

final StringBuilder query = new StringBuilder();
final List<RegExMatch> groups = matches.getMatches().get(0).getGroups();
Expand All @@ -236,14 +233,14 @@ private String buildFields(final ContentType contentType,
// The field in the URL Map doesn't belong to any field in the Content Type. Just move on
continue;
}
if (field.dataType().equals(DataTypes.INTEGER) || field.dataType().equals(DataTypes.FLOAT)){
if (field.dataType().equals(DataTypes.INTEGER) || field.dataType().equals(DataTypes.FLOAT)) {
query.append(variableName);
} else {
query.append(variableName).append("_dotRaw");
}

query.append(':')
.append(ESUtils.escapeExcludingSlashIncludingSpace(value)).append(' ');
.append(ESUtils.escapeExcludingSlashIncludingSpace(value)).append(' ');
counter++;
}

Expand All @@ -257,23 +254,21 @@ private String buildFields(final ContentType contentType,
* @param matches
* @param contentType The Content Type that the URL Map belongs to.
* @param context The instance of the URL Map Context.
*
* @return The Contentlet that matches the URL Map.
*
* @throws DotDataException An error occurred when interacting with the data source.
* @throws DotSecurityException
*/
private Contentlet getContentlet(
final Matches matches,
final ContentType contentType,
final UrlMapContext context)
throws DotDataException, DotSecurityException {
throws DotDataException, DotSecurityException {

Contentlet contentlet = null;

final String query = this.buildContentQuery(matches, contentType, context);
final List<Contentlet> contentletSearches =
ContentUtils.pull(query, 0, 2, "score",this.wuserAPI.getSystemUser(), true);
ContentUtils.pull(query, 0, 2, "score", this.wuserAPI.getSystemUser(), true);

if (!contentletSearches.isEmpty()) {

Expand Down Expand Up @@ -311,9 +306,9 @@ private Contentlet getContentlet(
}
}

final Contentlet finalContentlet = contentlet;
final Contentlet finalContentlet = contentlet;

if(context.isGraphQL()) {
if (context.isGraphQL()) {
return Try.of(() -> new DotTransformerBuilder().
graphQLDataFetchOptions().content(finalContentlet).build().hydrate().get(0)).getOrNull();
} else {
Expand All @@ -340,7 +335,6 @@ private void checkContentPermission(final UrlMapContext context, final Contentle
* @param matches The set of URL Maps that match a specific Content Type.
* @param contentType The Content Type that matches the URL Map.
* @param context The instance of the URL Map Context.
*
* @return The Lucene query that will return a potential match for the URL Map.
*/
private String buildContentQuery(
Expand All @@ -351,23 +345,23 @@ private String buildContentQuery(
final StringBuilder query = new StringBuilder();

query.append("+contentType:")
.append(contentType.variable())
.append(" +" + ESMappingConstants.VARIANT + ":")
.append(VariantAPI.DEFAULT_VARIANT.name())
.append(" +deleted:false ")
.append(" +(conhost:")
.append(contentType.variable())
.append(" +" + ESMappingConstants.VARIANT + ":")
.append(VariantAPI.DEFAULT_VARIANT.name())
.append(" +deleted:false ")
.append(" +(conhost:")
.append(context.getHost().getIdentifier())
.append(" OR conhost:")
.append(Host.SYSTEM_HOST)
.append(")");
.append(")");
if (context.getMode().showLive) {
query.append(" +live:true ");
} else {
query.append(" +working:true ");
}
query.append(" ");
query.append(this.buildFields(contentType, matches));

// score the current language higher
query.append(" languageId:").append(context.getLanguageId());

Expand Down Expand Up @@ -406,11 +400,11 @@ private boolean shouldLoadPatterns() {
* @throws DotDataException An error occurred when retrieving information from the database.
*/
private synchronized void loadPatterns() throws DotDataException {
if(!shouldLoadPatterns()) {

if (!shouldLoadPatterns()) {
return;
}

patternsCache.clear();

final List<SimpleStructureURLMap> urlMaps = typeAPI.findStructureURLMapPatterns();
Expand Down

0 comments on commit 288ecb0

Please sign in to comment.