Skip to content
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

feat(Announcements): correcting query that retrieves announcements from prod and fixing postman Ref:s#25736 #27480

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3228595
#25736 the postman is set to create the CT taking into account the an…
fabrizzio-dotCMS Jan 30, 2024
9466a86
#25736 megre latest from master
fabrizzio-dotCMS Jan 30, 2024
11fe5fb
Merge branch 'master' into issue-25736-improve-postman-to-use-publish…
fabrizzio-dotCMS Jan 30, 2024
f2860af
#25736 allowing time for publishing to take effect
fabrizzio-dotCMS Jan 31, 2024
bc75599
Merge branch 'issue-25736-improve-postman-to-use-publish-date' of htt…
fabrizzio-dotCMS Jan 31, 2024
3562c17
#25736 debugging postman failure
fabrizzio-dotCMS Jan 31, 2024
55e9032
#25736 correcting announcements remote query
fabrizzio-dotCMS Feb 1, 2024
9f5d8e5
#25736 code clean up
fabrizzio-dotCMS Feb 1, 2024
3f4e7ff
Merge branch 'master' into issue-25736-improve-postman-to-use-publish…
fabrizzio-dotCMS Feb 1, 2024
7dc1e62
#25736 updating postman test
fabrizzio-dotCMS Feb 1, 2024
dc5b264
Merge branch 'issue-25736-improve-postman-to-use-publish-date' of htt…
fabrizzio-dotCMS Feb 1, 2024
3e5bbed
#25736 url query fix
fabrizzio-dotCMS Feb 1, 2024
520c872
#25736 adjusting test
fabrizzio-dotCMS Feb 1, 2024
c8bdc9c
#25736 imrproved IT
fabrizzio-dotCMS Feb 1, 2024
a6c0627
Merge branch 'master' into issue-25736-improve-postman-to-use-publish…
fabrizzio-dotCMS Feb 1, 2024
c0740e7
#25736 log should be debug
fabrizzio-dotCMS Feb 2, 2024
4102c0e
Merge branch 'master' into issue-25736-improve-postman-to-use-publish…
fabrizzio-dotCMS Feb 2, 2024
84b4a4c
Merge branch 'master' into issue-25736-improve-postman-to-use-publish…
fabrizzio-dotCMS Feb 2, 2024
ab4d7a1
Merge branch 'master' into issue-25736-improve-postman-to-use-publish…
fabrizzio-dotCMS Feb 2, 2024
78172a7
Merge branch 'master' into issue-25736-improve-postman-to-use-publish…
fabrizzio-dotCMS Feb 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
205 changes: 148 additions & 57 deletions dotCMS/src/curl-test/Announcements.postman_collection.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public interface AnnouncementsHelper {
Lazy.of(() -> Config.getIntProperty("ANNOUNCEMENTS_LIMIT", 5));


List<Announcement> getAnnouncements(String languageIdOrCode, boolean refreshCache,
List<Announcement> getAnnouncements(boolean refreshCache,
Integer limit, User user);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
import com.dotcms.system.announcements.Announcement;
import com.dotcms.system.announcements.AnnouncementsCache;
import com.dotcms.system.announcements.AnnouncementsCacheImpl;
import com.dotmarketing.business.APILocator;
import com.dotmarketing.portlets.languagesmanager.business.LanguageAPI;
import com.dotmarketing.portlets.languagesmanager.model.Language;
import com.dotmarketing.util.Logger;
import com.liferay.portal.model.User;
import java.util.List;
Expand All @@ -15,75 +12,46 @@
*/
public class AnnouncementsHelperImpl implements AnnouncementsHelper{

private final LanguageAPI languageAPI;

private final AnnouncementsCache announcementsCache;

private final AnnouncementsLoader loader;


public AnnouncementsHelperImpl() {
this(APILocator.getLanguageAPI(), new RemoteAnnouncementsLoaderImpl(), new AnnouncementsCacheImpl());
this(new RemoteAnnouncementsLoaderImpl(), new AnnouncementsCacheImpl());
}

/**
* Constructor
* @param languageAPI LanguageAPI
* @param announcementsCache AnnouncementsCache
*/
public AnnouncementsHelperImpl(LanguageAPI languageAPI, AnnouncementsLoader loader, AnnouncementsCache announcementsCache) {
this.languageAPI = languageAPI;
public AnnouncementsHelperImpl(AnnouncementsLoader loader, AnnouncementsCache announcementsCache) {
this.announcementsCache = announcementsCache;
this.loader = loader;
}


/**
* Get the language by id or code, if not found fallback to default language
* @param languageIdOrCode String
* @return Language
*/
Language getLanguage(final String languageIdOrCode) {
Language language;
try {
final String[] split = languageIdOrCode.split("-");
if(split.length > 1) {
language = languageAPI.getLanguage(split[0], split[1]);
} else {
language = languageAPI.getLanguage(languageIdOrCode);
}
} catch (Exception e) {
Logger.debug(AnnouncementsHelperImpl.class, String.format(" failed to get lang [%s] with message: [%s] fallback to default language", languageIdOrCode, e.getMessage()));
language = languageAPI.getDefaultLanguage();
}
return language;
}


/**
* Get the announcements from the cache or from the remote server
* @param languageIdOrCode String
*
* @param refreshCache boolean
* @param limit Integer
* @param user User
* @return List<Announcement>
*/
@Override
public List<Announcement> getAnnouncements( final String languageIdOrCode, final boolean refreshCache, final Integer limit, final User user) {
public List<Announcement> getAnnouncements(final boolean refreshCache, final Integer limit, final User user) {

Logger.debug(AnnouncementsHelperImpl.class,String.format("Getting announcements for language: %s refreshCache: %s limit: %d, user: %s ", languageIdOrCode, refreshCache, limit, user.getUserId()));
final Language language = getLanguage(languageIdOrCode);
Logger.debug(AnnouncementsHelperImpl.class,String.format("Getting announcements refreshCache: %s limit: %d, user: %s ", refreshCache, limit, user.getUserId()));
final int limitValue = getLimit(limit);
if(!refreshCache) {
Logger.debug(this, "Getting announcements from cache for language: " + language.getId() + " limit: " + limitValue);
final List<Announcement> announcements = announcementsCache.get(language);
Logger.debug(this, "Getting announcements from cache for limit: " + limitValue);
final List<Announcement> announcements = announcementsCache.get();
if (announcements != null && !announcements.isEmpty()) {
return getSubList(limitValue, announcements);
}
}
final List<Announcement> announcements = loader.loadAnnouncements(language);
final List<Announcement> announcements = loader.loadAnnouncements();
if(!announcements.isEmpty()){
announcementsCache.put(language, announcements);
announcementsCache.put(announcements);
return getSubList(limitValue, announcements);
}
return List.of();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ public interface AnnouncementsLoader {

/**
* Load the announcements for the given language
* @param language Language
* @return List<Announcement>
*/
List<Announcement> loadAnnouncements(Language language);
List<Announcement> loadAnnouncements();

}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ public AnnouncementsResource() {
@Produces({MediaType.APPLICATION_JSON, "application/javascript"})
public final ResponseEntityView<List<Announcement>> announcements(@Context final HttpServletRequest request,
@Context final HttpServletResponse response,
@QueryParam("langIdOrCode") final String langIdOrCode,
@QueryParam("refreshCache") final boolean refreshCache,
@QueryParam("limit") final int limit
) {
Expand All @@ -74,7 +73,7 @@ public final ResponseEntityView<List<Announcement>> announcements(@Context final
.rejectWhenNoUser(true)
.init();
final User user = initData.getUser();
final List<Announcement> announcements = helper.getAnnouncements(langIdOrCode, refreshCache , limit, user);
final List<Announcement> announcements = helper.getAnnouncements(refreshCache , limit, user);
return new ResponseEntityView<>(announcements); // 200
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
import com.dotcms.content.business.json.ContentletJsonHelper;
import com.dotcms.rest.RestClientBuilder;
import com.dotcms.system.announcements.Announcement;
import com.dotmarketing.business.APILocator;
import com.dotmarketing.exception.DotRuntimeException;
import com.dotmarketing.portlets.languagesmanager.business.LanguageAPI;
import com.dotmarketing.portlets.languagesmanager.model.Language;
import com.dotmarketing.util.Config;
import com.dotmarketing.util.Logger;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import io.vavr.Lazy;
import io.vavr.control.Try;
Expand All @@ -21,6 +19,7 @@
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.List;
import java.util.function.Supplier;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
Expand All @@ -31,35 +30,47 @@
*/
public class RemoteAnnouncementsLoaderImpl implements AnnouncementsLoader{

//The CT varN/ame used to retrieve the Announcements
static final Lazy<String>DOT_ANNOUNCEMENT_CT =
Lazy.of(()-> Config.getStringProperty("DOT_ANNOUNCEMENT_CT", "Announcement"));

//This is the url to the dotCMS instance set to provide and feed all consumers with announcements
static final Lazy<String> ANNOUNCEMENTS_BASE_URL =
static final Lazy<String> BASE_URL_LAZY_SUPPLIER =
Lazy.of(() -> Config.getStringProperty("ANNOUNCEMENTS_BASE_URL", "https://www.dotcms.com"));

//The query pattern to retrieve the Announcements
static final String ANNOUNCEMENTS_QUERY_PATTERN = "%s/api/content/render/false/query/+contentType:%s +languageId:%d +deleted:false +live:true/orderBy/%s.announcementDate desc";
static final String ANNOUNCEMENTS_QUERY = "/api/content/render/false/query/+contentType:Announcement%20+languageId:1%20+deleted:false%20+live:true%20/orderby/Announcement.announcementDate%20desc";

Supplier<String> baseURL = BASE_URL_LAZY_SUPPLIER;

/**
* Default constructor
*/
public RemoteAnnouncementsLoaderImpl() {
}

/**
* Constructor
* @param baseURL Supplier<String>
*/
@VisibleForTesting
public RemoteAnnouncementsLoaderImpl(final Supplier<String> baseURL) {
this.baseURL = baseURL;
}

/**
* Load the announcements from the remote dotCMS instance
* @param language Language
* @return List<Announcement>
*/
@Override
public List<Announcement> loadAnnouncements(final Language language) {
final JsonNode jsonNode = loadRemoteAnnouncements(language);
public List<Announcement> loadAnnouncements() {
final JsonNode jsonNode = loadRemoteAnnouncements();
return toAnnouncements(jsonNode);
}

/**
* Load the announcements from the remote dotCMS instance
* @param language Language
* @return JsonNode
*/
JsonNode loadRemoteAnnouncements(final Language language) {
final String url = buildURL(language);
JsonNode loadRemoteAnnouncements() {
final String url = buildURL();
//Let's log the url to retrieve the announcements for debugging purposes on postman
Logger.debug(AnnouncementsHelperImpl.class, String.format("loading announcements from [%s]", url));
try {
final Client client = restClient();
final WebTarget webTarget = client.target(url);
Expand All @@ -83,12 +94,10 @@ JsonNode loadRemoteAnnouncements(final Language language) {

/**
* Build the url to retrieve the announcements
* @param language Language
* @return String
*/
String buildURL(Language language) {
final String raw = String.format(ANNOUNCEMENTS_QUERY_PATTERN, ANNOUNCEMENTS_BASE_URL.get(),
DOT_ANNOUNCEMENT_CT.get(), language.getId(), DOT_ANNOUNCEMENT_CT.get());
String buildURL() {
final String raw = baseURL.get() + ANNOUNCEMENTS_QUERY;
//clean up double slashes in the url
return raw.replaceAll("(?<!(http:|https:))//", "/");
}
Expand All @@ -101,23 +110,6 @@ static Client restClient() {
return RestClientBuilder.newClient();
}

/**
* Get the language by id or code, if not found fallback to default language
* @param languageIdOrCode String
* @return Language
*/
Language getLanguage(final String languageIdOrCode) {
final LanguageAPI languageAPI = APILocator.getLanguageAPI();
Language language;
try {
language = languageAPI.getLanguage(languageIdOrCode);
} catch (Exception e) {
Logger.debug(AnnouncementsHelperImpl.class, String.format(" failed to get lang [%s] with message: [%s] fallback to default language", languageIdOrCode, e.getMessage()));
language = languageAPI.getDefaultLanguage();
}
return language;
}

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd HH:mm:ss")
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 3, true)
Expand All @@ -129,7 +121,7 @@ Language getLanguage(final String languageIdOrCode) {
* @param root JsonNode
* @return List<Announcement>
*/
List<Announcement> toAnnouncements(final JsonNode root) {
List<Announcement> toAnnouncements(final JsonNode root) {

final ImmutableList.Builder<Announcement> announcements = ImmutableList.builder();
final JsonNode nodes = root.get("contentlets");
Expand All @@ -147,9 +139,6 @@ List<Announcement> toAnnouncements(final JsonNode root) {
final LocalDateTime date = LocalDateTime.parse(dateString, formatter);
final LocalDateTime modDate = LocalDateTime.parse(modDateString, formatter);

final Language language = getLanguage(langId);


announcements.add(
Announcement.builder()
.identifier(identifier)
Expand All @@ -159,8 +148,7 @@ List<Announcement> toAnnouncements(final JsonNode root) {
.announcementDateAsISO8601(date.toString())
.type(type)
.url(url)
.languageId(language.getId())
.languageCode(language.getIsoCode())
.languageId(langId)
.modDate(modDate.toInstant(java.time.ZoneOffset.UTC))
.modDateAsISO8601(modDate.toString())
.description(description)
Expand All @@ -172,4 +160,4 @@ List<Announcement> toAnnouncements(final JsonNode root) {
}


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ public interface AbstractAnnouncement {

String inode();

String languageCode();

long languageId();
String languageId();

String type();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package com.dotcms.system.announcements;

import com.dotmarketing.portlets.languagesmanager.model.Language;
import java.util.List;

public interface AnnouncementsCache {

void clearCache();

void put(Language language, List<Announcement> announcements);
void put(List<Announcement> announcements);

List<Announcement> get(Language language);
List<Announcement> get();

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.dotcms.business.SystemCache;
import com.dotcms.cache.Expirable;
import com.dotmarketing.business.CacheLocator;
import com.dotmarketing.portlets.languagesmanager.model.Language;
import com.dotmarketing.util.Config;
import com.google.common.annotations.VisibleForTesting;
import io.vavr.Lazy;
Expand All @@ -18,7 +17,7 @@ public class AnnouncementsCacheImpl implements AnnouncementsCache {
static final Lazy<Integer> ANNOUNCEMENTS_TTL =
Lazy.of(() -> Config.getIntProperty("ANNOUNCEMENTS_TTL", 3600 ));

static final String ANNOUNCEMENTS = "announcements::%s";
static final String ANNOUNCEMENTS_KEY = "dot::announcements";
private final SystemCache systemCache;

public AnnouncementsCacheImpl() {
Expand All @@ -28,32 +27,27 @@ public AnnouncementsCacheImpl() {

@Override
public void clearCache() {
systemCache.clearCache();
}

private String hashKey(Language language) {
return String.format(ANNOUNCEMENTS, language.getIsoCode());
systemCache.remove(ANNOUNCEMENTS_KEY);
}

@Override
public void put(final Language language, final List<Announcement> announcements) {
this.put(language, announcements, ANNOUNCEMENTS_TTL.get());
public void put(final List<Announcement> announcements) {
this.put(announcements, ANNOUNCEMENTS_TTL.get());
}

@VisibleForTesting
public void put(final Language language, final List<Announcement> announcements , final long ttl) {
systemCache.put(hashKey(language), new CacheEntryImpl(announcements,ttl));
public void put(final List<Announcement> announcements , final long ttl) {
systemCache.put(ANNOUNCEMENTS_KEY, new CacheEntryImpl(announcements,ttl));
}

@SuppressWarnings("unchecked")
@Override
public List<Announcement> get(final Language language) {
final String key = String.format(ANNOUNCEMENTS, language.getIsoCode());
final Object object = systemCache.get(key);
public List<Announcement> get() {
final Object object = systemCache.get(ANNOUNCEMENTS_KEY);
if (object instanceof Expirable) {
final CacheEntryImpl entry = (CacheEntryImpl) object;
if (entry.isExpired()) {
systemCache.remove(key);
systemCache.remove(ANNOUNCEMENTS_KEY);
return List.of();
}
return entry.getAnnouncements();
Expand Down