Skip to content

Commit

Permalink
fix(hosts) : rettrie live version if a host has live and working vers…
Browse files Browse the repository at this point in the history
…ions
  • Loading branch information
dsolistorres committed Oct 22, 2024
1 parent 0bae3dc commit 978a2d0
Show file tree
Hide file tree
Showing 12 changed files with 1,038 additions and 395 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ public Map<String, Object> findHostsForDataStore(String filter, boolean showArch
public Map<String, Object> findHostsPaginated(final String filter, final boolean showArchived, int offset, int count) throws DotDataException, DotSecurityException, PortalException, SystemException {
final User user = this.getLoggedInUser();
final boolean respectFrontend = !this.userWebAPI.isLoggedToBackend(this.getHttpRequest());
final List<Host> sitesFromDb = this.hostAPI.findAllFromDB(user, false, respectFrontend);
final List<Host> sitesFromDb = this.hostAPI.findAllFromDB(user,
false, true, respectFrontend);
final List<Field> fields = FieldsCache.getFieldsByStructureVariableName(Host.HOST_VELOCITY_VAR_NAME);
final List<Field> searchableFields = fields.stream().filter(field -> field.isListed() && field
.getFieldType().startsWith("text")).collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public void remove(final String key){
Logger.debug(this, "Cache not able to be removed", e);
}

final Host host = CacheLocator.getHostCache().getById(key);
final Host host = CacheLocator.getHostCache().getById(key, false);
if(host != null){
CacheLocator.getHostCache().remove(host);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,24 @@ Host find(Contentlet contentlet,
*/
List<Host> findAllFromDB(final User user, final boolean includeSystemHost, final boolean respectFrontendRoles) throws DotDataException, DotSecurityException;

/**
* Returns the complete list of Sites in your dotCMS repository retrieved <b>directly from the data source</b>. This
* method allows you to <b>EXCLUDE</b> the System Host from the result list. Additionally, you can specify whether
* you want to retrieve the live version of the Site over its working version if available.
*
* @param user The {@link User} that is calling this method.
* @param includeSystemHost If the System Host must be included in the results, set to {@code true}.
* @param retrieveLiveVersion If the live version of the Site must be retrieved when it's available, set to {@code true}.
* @param respectFrontendRoles If the User's front-end roles need to be taken into account in order to perform this
* operation, set to {@code true}. Otherwise, set to {@code false}.
*
* @return The list of {@link Host} objects.
* @throws DotDataException An error occurred when accessing the data source.
* @throws DotSecurityException The specified User does not have the required permissions to perform this
* operation.
*/
List<Host> findAllFromDB(final User user, final boolean includeSystemHost, final boolean retrieveLiveVersion, final boolean respectFrontendRoles) throws DotDataException, DotSecurityException;

/**
* Returns the complete list of Sites in your dotCMS repository retrieved from the cache. If no data is currently
* available, it will be retrieved from the data source, and put into the respective cache region.
Expand Down Expand Up @@ -415,7 +433,7 @@ List<Host> getHostsWithPermission(final int permissionType, final boolean includ
*
* @param host
*/
public void updateCache(Host host);
public void updateCache(Host host) throws DotDataException, DotSecurityException;

/**
* Updates the MenuLinks of the host with the new hostname
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import io.vavr.control.Try;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
Expand Down Expand Up @@ -101,7 +102,8 @@ public Host findDefaultHost(User user, boolean respectFrontendRoles) throws DotS

Host site;
try{
site = (this.hostCache.getDefaultHost()!=null) ? this.hostCache.getDefaultHost() : getOrCreateDefaultHost();
site = (this.hostCache.getDefaultHost(respectFrontendRoles)!=null) ?
this.hostCache.getDefaultHost(respectFrontendRoles) : getOrCreateDefaultHost(respectFrontendRoles);

APILocator.getPermissionAPI().checkPermission(site, PermissionLevel.READ, user);
return site;
Expand Down Expand Up @@ -140,7 +142,7 @@ public Host resolveHostName(String serverName, User user, boolean respectFronten
public Optional<Host> resolveHostNameWithoutDefault(String serverName, User user, boolean respectFrontendRoles) throws DotDataException, DotSecurityException {

Host host;
final Host cachedHostByAlias = hostCache.getHostByAlias(serverName);
final Host cachedHostByAlias = hostCache.getHostByAlias(serverName, respectFrontendRoles);
if (UtilMethods.isSet(() -> cachedHostByAlias.getIdentifier())) {
if (HostCache.CACHE_404_HOST.equals(cachedHostByAlias.getIdentifier())) {
return Optional.empty();
Expand Down Expand Up @@ -220,7 +222,7 @@ public Host findByName(final String siteName,
* @return The {@link Host} object that matches the specified name.
*/
private Host findByNameNotDefault(final String siteName, final User user, final boolean respectFrontendRoles) {
final Host site = this.getHostFactory().bySiteName(siteName);
final Host site = this.getHostFactory().bySiteName(siteName, respectFrontendRoles);
if (null != site) {
try {
checkSitePermission(user, respectFrontendRoles, site);
Expand Down Expand Up @@ -253,7 +255,7 @@ public Optional<Host> findByIdOrKey(final String siteIdOrKey, final User user,
@Override
@CloseDBIfOpened
public Host findByAlias(final String alias, final User user, final boolean respectFrontendRoles) throws DotDataException, DotSecurityException {
final Host site = this.getHostFactory().byAlias(alias);
final Host site = this.getHostFactory().byAlias(alias, respectFrontendRoles);
if (null != site) {
try {
checkSitePermission(user, respectFrontendRoles, site);
Expand Down Expand Up @@ -298,7 +300,7 @@ public Host find(final String id, final User user,
}

Host site = null;
Host cachedSiteById = hostCache.getById(id);
Host cachedSiteById = hostCache.getById(id, respectFrontendRoles);
if (UtilMethods.isSet(() -> cachedSiteById.getIdentifier())) {
if (HostCache.CACHE_404_HOST.equals(cachedSiteById.getIdentifier())) {
return null;
Expand Down Expand Up @@ -355,7 +357,15 @@ public List<Host> findAllFromDB(final User user, final boolean respectFrontendRo
@Override
public List<Host> findAllFromDB(final User user, final boolean includeSystemHost,
final boolean respectFrontendRoles) throws DotDataException, DotSecurityException {
return this.findPaginatedSitesFromDB(user, 0, 0, null, includeSystemHost, respectFrontendRoles);
return this.findAllFromDB(user, includeSystemHost, false, respectFrontendRoles);
}

@Override
public List<Host> findAllFromDB(final User user, final boolean includeSystemHost,
final boolean retrieveLiveVersion,
final boolean respectFrontendRoles) throws DotDataException, DotSecurityException {
return this.findPaginatedSitesFromDB(user, 0, 0, null,
includeSystemHost, retrieveLiveVersion, respectFrontendRoles);
}

/**
Expand All @@ -380,7 +390,7 @@ public List<Host> findAllFromDB(final User user, final boolean includeSystemHost
@CloseDBIfOpened
private List<Host> findPaginatedSitesFromDB(final User user, final int limit, final int offset, final String
sortBy, final boolean respectFrontendRoles) throws DotDataException, DotSecurityException {
return this.findPaginatedSitesFromDB(user, limit, offset, sortBy, true, respectFrontendRoles);
return this.findPaginatedSitesFromDB(user, limit, offset, sortBy, true, false, respectFrontendRoles);
}

/**
Expand All @@ -395,32 +405,48 @@ private List<Host> findPaginatedSitesFromDB(final User user, final int limit, fi
* @param sortBy Optional sorting criterion, as specified by the available columns in: {@link
* com.dotmarketing.common.util.SQLUtil#ORDERBY_WHITELIST}
* @param includeSystemHost If the System Host should be included in the result list, set to {@code true}.
* @param retrieveLiveVersion If the live version of the Site should be retrieved, set to {@code true}.
* @param respectFrontendRoles If the User's front-end roles need to be taken into account in order to perform this
* operation, set to {@code true}. Otherwise, set to {@code false}.
*
* @return The list of {@link Host} objects.
*
* @throws DotDataException An error occurred when accessing the data source.
* @throws DotSecurityException The specified User does not have the required permissions to perform this
* operation.
*/
private List<Host> findPaginatedSitesFromDB(final User user, final int limit, final int offset,
final String sortBy, final boolean includeSystemHost,
final boolean respectFrontendRoles) throws DotDataException, DotSecurityException {
final List<Host> siteList = this.getHostFactory().findAll(limit, offset, sortBy, includeSystemHost);
final boolean retrieveLiveVersion, final boolean respectFrontendRoles) throws DotDataException, DotSecurityException {
final List<Host> siteList = this.getHostFactory().findAll(
limit, offset, sortBy, includeSystemHost, retrieveLiveVersion);
return filterHostsByPermissions(user, includeSystemHost, respectFrontendRoles, siteList);
}

/**
* Returns a list of hosts filtered by user read permissions.
* @param user The {@link User} performing this action.
* @param includeSystemHost If the System Host should be included in the result list, set to {@code true}.
* @param respectFrontendRoles If the User's front-end roles need to be taken into account in order to perform this
* operation, set to {@code true}. Otherwise, set to {@code false}.
* @param siteList The list of {@link Host} objects to be filtered.
* @return The list of {@link Host} objects filtered by user read permissions.
*/
private List<Host> filterHostsByPermissions(final User user, final boolean includeSystemHost,
final boolean respectFrontendRoles, final List<Host> siteList) {
if (null != siteList && !siteList.isEmpty()) {
return siteList.stream().filter(site -> {
try {
if (site.isSystemHost() && !user.isAdmin()){
if (site.isSystemHost() && !user.isAdmin()) {
return includeSystemHost &&
APILocator.getPermissionAPI().doesSystemHostHavePermissions(APILocator.systemHost(), user, respectFrontendRoles, Host.class.getCanonicalName());
APILocator.getPermissionAPI().doesSystemHostHavePermissions(
APILocator.systemHost(), user, respectFrontendRoles,
Host.class.getCanonicalName());
}
this.checkSitePermission(user, respectFrontendRoles, site);
return true;
} catch (final DotDataException | DotSecurityException e) {
Logger.warn(this,
String.format("An error occurred when checking permissions from User '%s' on " + "Site " +
"'%s': %s", user.getUserId(), site.getInode(), e.getMessage()));
"'%s': %s", user.getUserId(), site.getInode(), e.getMessage()));
}
return false;
}).collect(Collectors.toList());
Expand All @@ -431,11 +457,17 @@ private List<Host> findPaginatedSitesFromDB(final User user, final int limit, fi
@Override
public List<Host> findAllFromCache(final User user,
final boolean respectFrontendRoles) throws DotDataException, DotSecurityException {
Set<Host> cachedSites = hostCache.getAllSites();
Set<Host> cachedSites = hostCache.getAllSites(respectFrontendRoles);
if(null == cachedSites){
final List<Host> allFromDB = findAllFromDB(user, respectFrontendRoles);
hostCache.addAll(allFromDB);
cachedSites = hostCache.getAllSites();
final List<Host> allFromDB = findAllFromDB(APILocator.systemUser(),
true, false,false);
final List<Host> allFromDBLive = findAllFromDB(APILocator.systemUser(),
true, true,false);
hostCache.addAll(allFromDB, allFromDBLive);
final List<Host> filteredSiteList = filterHostsByPermissions(
user, true, respectFrontendRoles,
new ArrayList<>(hostCache.getAllSites(respectFrontendRoles)));
cachedSites = filteredSiteList != null ? new HashSet<>(filteredSiteList) : new HashSet<>();
}
return ImmutableList.copyOf(cachedSites);
}
Expand Down Expand Up @@ -484,6 +516,7 @@ public Host save(final Host hostToBeSaved, User user, boolean respectFrontendRol

if(hostToBeSaved.isWorking() || hostToBeSaved.isLive()){
APILocator.getVersionableAPI().setLive(contentletHost);
Logger.info(this, "Host " + hostToBeSaved.getHostname() + " is now live");
}
Host savedHost = new Host(contentletHost);

Expand Down Expand Up @@ -704,8 +737,14 @@ private void sendUnArchiveSiteSystemEvent (final Contentlet contentlet) {
}
}

/**
* Retrieves the default site if exists or creates a new one if required.
* @param respectFrontendRoles If the User's front-end roles need to be taken into account in order to perform this
* operation, set to {@code true}. Otherwise, set to {@code false}.
* @return The default site.
*/
@CloseDBIfOpened
private synchronized Host getOrCreateDefaultHost() throws DotDataException, DotSecurityException {
private synchronized Host getOrCreateDefaultHost(final boolean respectFrontendRoles) throws DotDataException, DotSecurityException {

final ContentType siteContentType = hostType();
final List<Field> fields = siteContentType.fields();
Expand All @@ -716,7 +755,8 @@ private synchronized Host getOrCreateDefaultHost() throws DotDataException, DotS
Logger.error(HostAPIImpl.class, message);
throw new DotDataException(message);
}
final Optional<Host> defaultHostOpt = this.getHostFactory().findDefaultHost(siteContentType.inode(), defaultField.get().dbColumn());
final Optional<Host> defaultHostOpt = this.getHostFactory().findDefaultHost(
siteContentType.inode(), defaultField.get().dbColumn(), respectFrontendRoles);
if (defaultHostOpt.isPresent()) {
return defaultHostOpt.get();
}
Expand Down Expand Up @@ -794,8 +834,8 @@ public Host DBSearch(String id, User user, boolean respectFrontendRoles)
}

@Override
public void updateCache(Host host) {
hostCache.remove(host);
public void updateCache(Host host) throws DotDataException, DotSecurityException {
hostCache.remove(host, false);
hostCache.clearAliasCache();
hostCache.add(new Host(host));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

import com.dotmarketing.beans.Host;
import com.dotmarketing.business.Cachable;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.exception.DotSecurityException;

import java.util.Set;

//This interface should have default package access
public abstract class HostCache implements Cachable{
protected static String PRIMARY_GROUP = "HostCache";
protected static String ALIAS_GROUP = "HostAliasCache";
protected static String HOST_LIVE_GROUP = "HostLiveCache";
protected static String NOT_FOUND_BY_ID_GROUP = "Host404ByIdCache";
protected static String NOT_FOUND_BY_NAME_GROUP = "Host404ByNameCache";

Expand All @@ -20,23 +24,25 @@ public String getIdentifier() {
}
};

abstract protected Host add(Host host);
abstract protected Host add(Host host) throws DotDataException, DotSecurityException;

abstract protected Host getById(String id);
abstract protected Host getById(String id, boolean retrieveLiveVersion);

abstract protected Host getByName(String name);
abstract protected Host getByName(String name, boolean retrieveLiveVersion);

abstract public void clearCache();

abstract protected void remove(Host host);

abstract protected void addAll(final Iterable<Host> hosts);
abstract protected void remove(Host host, boolean removeLiveVersion);

abstract protected void addAll(Iterable<Host> hosts, Iterable<Host> liveHosts) throws DotDataException, DotSecurityException;

abstract protected Set<Host> getAllSites();
abstract protected Set<Host> getAllSites(boolean retrieveLiveVersion);

abstract protected Host getDefaultHost();
abstract protected Host getDefaultHost(boolean retrieveLiveVersion);

abstract protected Host getHostByAlias(String alias);
abstract protected Host getHostByAlias(String alias, boolean retrieveLiveVersion);

abstract protected void addHostAlias(String alias, Host host);

Expand Down
Loading

0 comments on commit 978a2d0

Please sign in to comment.